summaryrefslogtreecommitdiff
path: root/libcpu/mips
diff options
context:
space:
mode:
authorbernard <[email protected]>2017-09-29 10:23:56 +0800
committerbernard <[email protected]>2017-09-29 10:23:56 +0800
commitcccff34fcac04f34233a33e453f2d0ec255bf231 (patch)
treed406036f73296b27f3cb96e77ede98dd7803c61d /libcpu/mips
parente9a77b513f0a4b37d539a030592a61b08d03602d (diff)
parent3691b67e83ab57196dfc62606b1be18db76994a7 (diff)
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'libcpu/mips')
-rw-r--r--libcpu/mips/common/mipsregs.h90
-rw-r--r--libcpu/mips/loongson_1c/context_gcc.S6
-rw-r--r--libcpu/mips/loongson_1c/cpuport.c36
-rw-r--r--libcpu/mips/loongson_1c/interrupt.c111
-rw-r--r--libcpu/mips/loongson_1c/ls1c.h66
-rw-r--r--libcpu/mips/loongson_1c/stackframe_fpu.h98
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
+