diff options
| author | bernard <[email protected]> | 2017-09-29 10:23:56 +0800 |
|---|---|---|
| committer | bernard <[email protected]> | 2017-09-29 10:23:56 +0800 |
| commit | cccff34fcac04f34233a33e453f2d0ec255bf231 (patch) | |
| tree | d406036f73296b27f3cb96e77ede98dd7803c61d /libcpu/mips | |
| parent | e9a77b513f0a4b37d539a030592a61b08d03602d (diff) | |
| parent | 3691b67e83ab57196dfc62606b1be18db76994a7 (diff) | |
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'libcpu/mips')
| -rw-r--r-- | libcpu/mips/common/mipsregs.h | 90 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1c/context_gcc.S | 6 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1c/cpuport.c | 36 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1c/interrupt.c | 111 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1c/ls1c.h | 66 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1c/stackframe_fpu.h | 98 |
6 files changed, 343 insertions, 64 deletions
diff --git a/libcpu/mips/common/mipsregs.h b/libcpu/mips/common/mipsregs.h index 888d4b13b5..22e5754b8b 100644 --- a/libcpu/mips/common/mipsregs.h +++ b/libcpu/mips/common/mipsregs.h @@ -116,6 +116,70 @@ #define CP1_REVISION $0 #define CP1_STATUS $31 +/* + * FPU Status Register Values + */ +/* + * Status Register Values + */ + +#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ +#define FPU_CSR_COND 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ +#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ +#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ +#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ +#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ +#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ +#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ + + +/* FS/FO/FN */ +#define FPU_CSR_FS 0x01000000 +#define FPU_CSR_FO 0x00400000 +#define FPU_CSR_FN 0x00200000 + +/* + * Bits 18 - 20 of the FPU Status Register will be read as 0, + * and should be written as zero. + */ +#define FPU_CSR_RSVD 0x001c0000 + +/* + * X the exception cause indicator + * E the exception enable + * S the sticky/flag bit +*/ +#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_UNI_X 0x00020000 +#define FPU_CSR_INV_X 0x00010000 +#define FPU_CSR_DIV_X 0x00008000 +#define FPU_CSR_OVF_X 0x00004000 +#define FPU_CSR_UDF_X 0x00002000 +#define FPU_CSR_INE_X 0x00001000 + +#define FPU_CSR_ALL_E 0x00000f80 +#define FPU_CSR_INV_E 0x00000800 +#define FPU_CSR_DIV_E 0x00000400 +#define FPU_CSR_OVF_E 0x00000200 +#define FPU_CSR_UDF_E 0x00000100 +#define FPU_CSR_INE_E 0x00000080 + +#define FPU_CSR_ALL_S 0x0000007c +#define FPU_CSR_INV_S 0x00000040 +#define FPU_CSR_DIV_S 0x00000020 +#define FPU_CSR_OVF_S 0x00000010 +#define FPU_CSR_UDF_S 0x00000008 +#define FPU_CSR_INE_S 0x00000004 + +/* Bits 0 and 1 of FPU Status Register specify the rounding mode */ +#define FPU_CSR_RM 0x00000003 +#define FPU_CSR_RN 0x0 /* nearest */ +#define FPU_CSR_RZ 0x1 /* towards zero */ +#define FPU_CSR_RU 0x2 /* towards +Infinity */ +#define FPU_CSR_RD 0x3 /* towards -Infinity */ + /* * R4x00 interrupt enable / cause bits @@ -610,6 +674,32 @@ do { \ #define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + /* gas fails to assemble cfc1 for some archs (octeon).*/ \ + ".set\tmips1\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) +#define write_32bit_cp1_register(register, value) \ +do { \ + __asm__ __volatile__( \ + "ctc1\t%z0, "STR(register)"\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define read_c1_status() read_32bit_cp1_register(CP1_STATUS) +#define read_c1_revision() read_32bit_cp1_register(CP1_REVISION); +#define write_c1_status(val) write_32bit_cp1_register(CP1_STATUS, val) + + #endif /* end of __ASSEMBLY__ */ #endif /* end of __MIPSREGS_H__ */ diff --git a/libcpu/mips/loongson_1c/context_gcc.S b/libcpu/mips/loongson_1c/context_gcc.S index 1ac2747747..fbffd34866 100644 --- a/libcpu/mips/loongson_1c/context_gcc.S +++ b/libcpu/mips/loongson_1c/context_gcc.S @@ -16,6 +16,7 @@ #include "../common/mips.inc" #include "../common/stackframe.h" +#include "stackframe_fpu.h" .section ".text", "ax" .set noreorder @@ -56,10 +57,12 @@ rt_hw_interrupt_enable: rt_hw_context_switch: mtc0 ra, CP0_EPC SAVE_ALL + SAVE_FPU sw sp, 0(a0) /* store sp in preempted tasks TCB */ lw sp, 0(a1) /* get new task stack pointer */ + RESTORE_FPU RESTORE_ALL_AND_RET /* @@ -70,6 +73,7 @@ rt_hw_context_switch: rt_hw_context_switch_to: lw sp, 0(a0) /* get new task stack pointer */ + RESTORE_FPU RESTORE_ALL_AND_RET /* @@ -103,6 +107,7 @@ _reswitch: .globl mips_irq_handle mips_irq_handle: SAVE_ALL + SAVE_FPU mfc0 t0, CP0_CAUSE and t1, t0, 0xff @@ -151,6 +156,7 @@ mips_irq_handle: nop spurious_interrupt: + RESTORE_FPU RESTORE_ALL_AND_RET .set reorder diff --git a/libcpu/mips/loongson_1c/cpuport.c b/libcpu/mips/loongson_1c/cpuport.c index 6cdae024c4..f4914dfec4 100644 --- a/libcpu/mips/loongson_1c/cpuport.c +++ b/libcpu/mips/loongson_1c/cpuport.c @@ -121,5 +121,41 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad return (rt_uint8_t *)stk; } +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else +#define Hit_Invalidate_I 0x10 +#endif +#define Hit_Invalidate_D 0x11 +#define CONFIG_SYS_CACHELINE_SIZE 32 +#define Hit_Writeback_Inv_D 0x15 + + +void flush_cache(unsigned long start_addr, unsigned long size) +{ + unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; + unsigned long addr = start_addr & ~(lsize - 1); + unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } +} + + /*@}*/ diff --git a/libcpu/mips/loongson_1c/interrupt.c b/libcpu/mips/loongson_1c/interrupt.c index b39b579731..cc0b8e4e9c 100644 --- a/libcpu/mips/loongson_1c/interrupt.c +++ b/libcpu/mips/loongson_1c/interrupt.c @@ -18,8 +18,10 @@ #include <rtthread.h> #include <rthw.h> #include "ls1c.h" +#include "ls1c_public.h" -#define MAX_INTR 32 + +#define MAX_INTR (LS1C_NR_IRQS) extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread; @@ -50,13 +52,26 @@ static void rt_hw_interrupt_handler(int vector, void *param) void rt_hw_interrupt_init(void) { rt_int32_t idx; + rt_int32_t i; + rt_uint32_t c0_status = 0; + + // ����Э������0��״̬�Ĵ���SR��IM7-2�������ж� + c0_status = read_c0_status(); + c0_status |= 0xFC00; + write_c0_status(c0_status); - /* pci active low */ - ls1c_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq - /* make all interrupts level triggered */ - (ls1c_hw0_icregs+0)->int_edge = 0x0000e000; - /* mask all interrupts */ - (ls1c_hw0_icregs+0)->int_clr = 0xffffffff; + // ��о1c���жϷ�Ϊ���� + for (i=0; i<5; i++) + { + /* disable */ + (ls1c_hw0_icregs+i)->int_en = 0x0; + /* pci active low */ + (ls1c_hw0_icregs+i)->int_pol = -1; //must be done here 20110802 lgnq + /* make all interrupts level triggered */ + (ls1c_hw0_icregs+i)->int_edge = 0x00000000; + /* mask all interrupts */ + (ls1c_hw0_icregs+i)->int_clr = 0xffffffff; + } rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); for (idx = 0; idx < MAX_INTR; idx ++) @@ -115,6 +130,51 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, return old_handler; } + +/** + * ִ���жϴ������� + * @IRQn �жϺ� + */ +void ls1c_do_IRQ(int IRQn) +{ + rt_isr_handler_t irq_func; + void *param; + + // �ҵ��жϴ������� + irq_func = irq_handle_table[IRQn].handler; + param = irq_handle_table[IRQn].param; + + // ִ���жϴ������� + irq_func(IRQn, param); + +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[IRQn].counter++; +#endif + + return ; +} + + +void ls1c_irq_dispatch(int n) +{ + rt_uint32_t intstatus, irq; + + /* Receive interrupt signal, compute the irq */ + intstatus = (ls1c_hw0_icregs+n)->int_isr & (ls1c_hw0_icregs+n)->int_en; + if (0 == intstatus) + return ; + + // ִ���жϴ������� + irq = ls1c_ffs(intstatus) - 1; + ls1c_do_IRQ((n<<5) + irq); + + /* ack interrupt */ + (ls1c_hw0_icregs+n)->int_clr |= (1 << irq); + + return ; +} + + void rt_interrupt_dispatch(void *ptreg) { int irq; @@ -139,50 +199,25 @@ void rt_interrupt_dispatch(void *ptreg) { rt_hw_timer_handler(); } - - if (pending_im & CAUSEF_IP2) + else if (pending_im & CAUSEF_IP2) { - /* the hardware interrupt */ - status = ls1c_hw0_icregs->int_isr; - if (!status) - return; - - for (irq = MAX_INTR; irq > 0; --irq) - { - if ((status & (1 << irq))) - { - status &= ~(1 << irq); - - irq_func = irq_handle_table[irq].handler; - param = irq_handle_table[irq].param; - - /* do interrupt */ - irq_func(irq, param); - -#ifdef RT_USING_INTERRUPT_INFO - irq_handle_table[irq].counter++; -#endif /* RT_USING_INTERRUPT_INFO */ - - /* ack interrupt */ - ls1c_hw0_icregs->int_clr |= (1 << irq); - } - } + ls1c_irq_dispatch(0); } else if (pending_im & CAUSEF_IP3) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(1); } else if (pending_im & CAUSEF_IP4) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(2); } else if (pending_im & CAUSEF_IP5) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(3); } else if (pending_im & CAUSEF_IP6) { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + ls1c_irq_dispatch(4); } } diff --git a/libcpu/mips/loongson_1c/ls1c.h b/libcpu/mips/loongson_1c/ls1c.h index 8b50da5ac9..a203810c37 100644 --- a/libcpu/mips/loongson_1c/ls1c.h +++ b/libcpu/mips/loongson_1c/ls1c.h @@ -20,7 +20,7 @@ #define LS1C_ACPI_IRQ 0 #define LS1C_HPET_IRQ 1 -#define LS1C_UART0_IRQ 2 +//#define LS1C_UART0_IRQ 3 // linux����3��v1.4�汾��1c�ֲ�����2�������Σ���ȷ�� #define LS1C_UART1_IRQ 4 #define LS1C_UART2_IRQ 5 #define LS1C_CAN0_IRQ 6 @@ -32,41 +32,55 @@ #define LS1C_KB_IRQ 12 #define LS1C_DMA0_IRQ 13 #define LS1C_DMA1_IRQ 14 -#define LS1C_NAND_IRQ 15 -#define LS1C_I2C0_IRQ 16 -#define LS1C_I2C1_IRQ 17 -#define LS1C_PWM0_IRQ 18 -#define LS1C_PWM1_IRQ 19 -#define LS1C_PWM2_IRQ 20 -#define LS1C_PWM3_IRQ 21 -#define LS1C_LPC_IRQ 22 -#define LS1C_EHCI_IRQ 32 -#define LS1C_OHCI_IRQ 33 -#define LS1C_GMAC1_IRQ 34 -#define LS1C_GMAC2_IRQ 35 -#define LS1C_SATA_IRQ 36 -#define LS1C_GPU_IRQ 37 -#define LS1C_PCI_INTA_IRQ 38 -#define LS1C_PCI_INTB_IRQ 39 -#define LS1C_PCI_INTC_IRQ 40 -#define LS1C_PCI_INTD_IRQ 41 +#define LS1C_DMA2_IRQ 15 +#define LS1C_NAND_IRQ 16 +#define LS1C_PWM0_IRQ 17 +#define LS1C_PWM1_IRQ 18 +#define LS1C_PWM2_IRQ 19 +#define LS1C_PWM3_IRQ 20 +#define LS1C_RTC_INT0_IRQ 21 +#define LS1C_RTC_INT1_IRQ 22 +#define LS1C_RTC_INT2_IRQ 23 +#define LS1C_UART3_IRQ 29 +#define LS1C_ADC_IRQ 30 +#define LS1C_SDIO_IRQ 31 + + +#define LS1C_EHCI_IRQ (32+0) +#define LS1C_OHCI_IRQ (32+1) +#define LS1C_OTG_IRQ (32+2) +#define LS1C_MAC_IRQ (32+3) +#define LS1C_CAM_IRQ (32+4) +#define LS1C_UART4_IRQ (32+5) +#define LS1C_UART5_IRQ (32+6) +#define LS1C_UART6_IRQ (32+7) +#define LS1C_UART7_IRQ (32+8) +#define LS1C_UART8_IRQ (32+9) +#define LS1C_UART9_IRQ (32+13) +#define LS1C_UART10_IRQ (32+14) +#define LS1C_UART11_IRQ (32+15) +#define LS1C_I2C2_IRQ (32+17) +#define LS1C_I2C1_IRQ (32+18) +#define LS1C_I2C0_IRQ (32+19) + #define LS1C_GPIO_IRQ 64 #define LS1C_GPIO_FIRST_IRQ 64 #define LS1C_GPIO_IRQ_COUNT 96 #define LS1C_GPIO_LAST_IRQ (LS1C_GPIO_FIRST_IRQ + LS1C_GPIO_IRQ_COUNT-1) -#define INT_PCI_INTA (1<<6) -#define INT_PCI_INTB (1<<7) -#define INT_PCI_INTC (1<<8) -#define INT_PCI_INTD (1<<9) #define LS1C_LAST_IRQ 159 -#define MIPS_CPU_TIMER_IRQ 167 #define LS1C_INTREG_BASE 0xbfd01040 -#define LS1C_DMA_IRQ_BASE 168 -#define LS1C_DMA_IRQ_COUNT 16 +// ��о1c���жϷ�Ϊ���飬ÿ��32�� +#define LS1C_NR_IRQS (32*5) + + +// GPIO��ź��жϺ�֮��Ļ���ת�� +#define LS1C_GPIO_TO_IRQ(GPIOn) (LS1C_GPIO_FIRST_IRQ + (GPIOn)) +#define LS1C_IRQ_TO_GPIO(IRQn) ((IRQn) - LS1C_GPIO_FIRST_IRQ) + struct ls1c_intc_regs { diff --git a/libcpu/mips/loongson_1c/stackframe_fpu.h b/libcpu/mips/loongson_1c/stackframe_fpu.h new file mode 100644 index 0000000000..93b8ef10c3 --- /dev/null +++ b/libcpu/mips/loongson_1c/stackframe_fpu.h @@ -0,0 +1,98 @@ +/* + * ls1c FPU's stackframe + * �ʼ���룬��������뵽stackframe.h�е�SAVE_ALL, RESTORE_ALL��RESTORE_ALL_AND_RET�У� + * �����ǵ�Դ�ļ�"stackframe.h"λ��Ŀ¼"libcpu\mips\common"�ڣ���Ӱ�쵽����mips cpu + * ���ԣ������½���Դ�ļ� + */ +#ifndef __OPENLOONGSON_STACKFRAME_FPU_H +#define __OPENLOONGSON_STACKFRAME_FPU_H + + +#include "../common/asm.h" +#include "../common/mipsregs.h" +#include "../common/stackframe.h" + + + +#define PT_FPU_R0 (0) +#define PT_FPU_R2 ((PT_FPU_R0) + 2*LONGSIZE) +#define PT_FPU_R4 ((PT_FPU_R2) + 2*LONGSIZE) +#define PT_FPU_R6 ((PT_FPU_R4) + 2*LONGSIZE) +#define PT_FPU_R8 ((PT_FPU_R6) + 2*LONGSIZE) +#define PT_FPU_R10 ((PT_FPU_R8) + 2*LONGSIZE) +#define PT_FPU_R12 ((PT_FPU_R10) + 2*LONGSIZE) +#define PT_FPU_R14 ((PT_FPU_R12) + 2*LONGSIZE) +#define PT_FPU_R16 ((PT_FPU_R14) + 2*LONGSIZE) +#define PT_FPU_R18 ((PT_FPU_R16) + 2*LONGSIZE) +#define PT_FPU_R20 ((PT_FPU_R18) + 2*LONGSIZE) +#define PT_FPU_R22 ((PT_FPU_R20) + 2*LONGSIZE) +#define PT_FPU_R24 ((PT_FPU_R22) + 2*LONGSIZE) +#define PT_FPU_R26 ((PT_FPU_R24) + 2*LONGSIZE) +#define PT_FPU_R28 ((PT_FPU_R26) + 2*LONGSIZE) +#define PT_FPU_R30 ((PT_FPU_R28) + 2*LONGSIZE) + +#define PT_FPU_SIZE ((((PT_FPU_R30) + 2*LONGSIZE) + (2*PTRSIZE-1)) & ~(2*PTRSIZE-1)) + + + .macro SAVE_FPU + .set push + .set noreorder +#ifdef RT_USING_FPU + move k1, sp /* �����ֳ� */ + and k0, k1, 0xFFFFFFF8 /* 8�ֽڶ��� */ + PTR_SUBU sp, k0, PT_FPU_SIZE /* ����ջ�� */ + s.d $f0, PT_FPU_R0(sp) + s.d $f2, PT_FPU_R2(sp) + s.d $f4, PT_FPU_R4(sp) + s.d $f6, PT_FPU_R6(sp) + s.d $f8, PT_FPU_R8(sp) + s.d $f10, PT_FPU_R10(sp) + s.d $f12, PT_FPU_R12(sp) + s.d $f14, PT_FPU_R14(sp) + s.d $f16, PT_FPU_R16(sp) + s.d $f18, PT_FPU_R18(sp) + s.d $f20, PT_FPU_R20(sp) + s.d $f22, PT_FPU_R22(sp) + s.d $f24, PT_FPU_R24(sp) + s.d $f26, PT_FPU_R26(sp) + s.d $f28, PT_FPU_R28(sp) + s.d $f30, PT_FPU_R30(sp) + move sp, k1 /* �ָ��ֳ� */ +#endif + .set reorder + .set pop + .endm + + + .macro RESTORE_FPU + .set push + .set noreorder +#ifdef RT_USING_FPU + move k1, sp /* �����ֳ� */ + and k0, k1, 0xFFFFFFF8 /* 8�ֽڶ��� */ + PTR_SUBU sp, k0, PT_FPU_SIZE /* ����ջ��*/ + l.d $f0, PT_FPU_R0(sp) + l.d $f2, PT_FPU_R2(sp) + l.d $f4, PT_FPU_R4(sp) + l.d $f6, PT_FPU_R6(sp) + l.d $f8, PT_FPU_R8(sp) + l.d $f10, PT_FPU_R10(sp) + l.d $f12, PT_FPU_R12(sp) + l.d $f14, PT_FPU_R14(sp) + l.d $f16, PT_FPU_R16(sp) + l.d $f18, PT_FPU_R18(sp) + l.d $f20, PT_FPU_R20(sp) + l.d $f22, PT_FPU_R22(sp) + l.d $f24, PT_FPU_R24(sp) + l.d $f26, PT_FPU_R26(sp) + l.d $f28, PT_FPU_R28(sp) + l.d $f30, PT_FPU_R30(sp) + move sp, k1 /* �ָ��ֳ� */ +#endif + .set reorder + .set pop + .endm + + +#endif + |
