summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2011-03-17 09:14:38 +0000
committerbernard.xiong <[email protected]>2011-03-17 09:14:38 +0000
commitb5fbd467765e062d293e9e22a033ca6665210627 (patch)
tree1ee5821b7be358e2763b40113429df4eea718d47 /libcpu
parent24dfbe437de3b96e78298206e6e62c1dc975c4f8 (diff)
add GNU GCC support in LPC2478.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1333 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/lpc24xx/interrupt.c2
-rw-r--r--libcpu/arm/lpc24xx/serial.c6
-rw-r--r--libcpu/arm/lpc24xx/start_gcc.S363
-rw-r--r--libcpu/arm/lpc24xx/trap.c2
4 files changed, 225 insertions, 148 deletions
diff --git a/libcpu/arm/lpc24xx/interrupt.c b/libcpu/arm/lpc24xx/interrupt.c
index 0b573d57e7..9e6c6c8893 100644
--- a/libcpu/arm/lpc24xx/interrupt.c
+++ b/libcpu/arm/lpc24xx/interrupt.c
@@ -52,7 +52,6 @@ void rt_hw_interrupt_init()
*vect_addr = 0x0;
*vect_cntl = 0xF;
}
-
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
@@ -79,6 +78,7 @@ void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_ha
{
/* find first un-assigned VIC address for the handler */
vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + vector*4);
+ if (old_handler != RT_NULL) *old_handler = *vect_addr; /* get old handler */
*vect_addr = (rt_uint32_t)new_handler; /* set interrupt vector */
}
}
diff --git a/libcpu/arm/lpc24xx/serial.c b/libcpu/arm/lpc24xx/serial.c
index 161717aae5..0eeb94a61e 100644
--- a/libcpu/arm/lpc24xx/serial.c
+++ b/libcpu/arm/lpc24xx/serial.c
@@ -322,7 +322,7 @@ void rt_hw_serial_init(void)
lpc_serial->read_index = lpc_serial->save_index = 0;
/* Enable UART0 RxD and TxD pins */
- PINSEL0 |= 0x05;
+ PINSEL0 |= 0x50;
/* 8 bits, no Parity, 1 Stop bit */
UART_LCR(lpc_serial->hw_base) = 0x83;
@@ -334,6 +334,7 @@ void rt_hw_serial_init(void)
/* DLAB = 0 */
UART_LCR(lpc_serial->hw_base) = 0x03;
+ lpc_serial->parent.type = RT_Device_Class_Char;
lpc_serial->parent.init = rt_serial_init;
lpc_serial->parent.open = rt_serial_open;
lpc_serial->parent.close = rt_serial_close;
@@ -343,7 +344,7 @@ void rt_hw_serial_init(void)
lpc_serial->parent.user_data = RT_NULL;
rt_device_register(&lpc_serial->parent,
- "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+ "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
#endif
#ifdef RT_USING_UART2
@@ -371,6 +372,7 @@ void rt_hw_serial_init(void)
/* DLAB = 0 */
UART_LCR(lpc_serial->hw_base) = 0x03;
+ lpc_serial->parent.type = RT_Device_Class_Char;
lpc_serial->parent.init = rt_serial_init;
lpc_serial->parent.open = rt_serial_open;
lpc_serial->parent.close = rt_serial_close;
diff --git a/libcpu/arm/lpc24xx/start_gcc.S b/libcpu/arm/lpc24xx/start_gcc.S
index bd473bc0cd..5baf2d0c6a 100644
--- a/libcpu/arm/lpc24xx/start_gcc.S
+++ b/libcpu/arm/lpc24xx/start_gcc.S
@@ -10,13 +10,10 @@
* Change Logs:
* Date Author Notes
* 2008-12-11 XuXinming first version
+ * 2011-03-17 Bernard update to 0.4.x
*/
-/**
- * @addtogroup LPC2478
- */
-/*@{*/
-
+#define CONFIG_STACKSIZE 512
#define WDMOD (0xE0000000 + 0x00)
#define VICIntEnClr (0xFFFFF000 + 0x014)
#define VICVectAddr (0xFFFFF000 + 0xF00)
@@ -26,189 +23,265 @@
#define PLLFEED (0xE01FC000 + 0x08C)
#define PLLSTAT (0xE01FC000 + 0x088)
#define CCLKCFG (0xE01FC000 + 0x104)
-#define MEMMAP (0xE01FC000 + 0x040)
-#define SCS (0xE01FC000 + 0x1A0)
+#define MEMMAP (0xE01FC000 + 0x040)
+#define SCS (0xE01FC000 + 0x1A0)
#define CLKSRCSEL (0xE01FC000 + 0x10C)
#define MAMCR (0xE01FC000 + 0x000)
#define MAMTIM (0xE01FC000 + 0x004)
+/* stack memory */
+.section .bss.noinit
+.equ IRQ_STACK_SIZE, 0x00000200
+.equ FIQ_STACK_SIZE, 0x00000100
+.equ UDF_STACK_SIZE, 0x00000004
+.equ ABT_STACK_SIZE, 0x00000004
+.equ SVC_STACK_SIZE, 0x00000200
+
+.space IRQ_STACK_SIZE
+IRQ_STACK:
+
+.space FIQ_STACK_SIZE
+FIQ_STACK:
+
+.space UDF_STACK_SIZE
+UDF_STACK:
+
+.space ABT_STACK_SIZE
+ABT_STACK:
-/*.section .init, "ax"*/
-.section .vectors
+.space SVC_STACK_SIZE
+SVC_STACK:
+
+.section .init, "ax"
.code 32
.globl _start
_start:
- b reset
- ldr pc, _vector_undef
- ldr pc, _vector_swi
- ldr pc, _vector_pabt
- ldr pc, _vector_dabt
- ldr pc, _vector_resv
- ldr pc, _vector_irq
- ldr pc, _vector_fiq
+ b reset
+ ldr pc, _vector_undef
+ ldr pc, _vector_swi
+ ldr pc, _vector_pabt
+ ldr pc, _vector_dabt
+ ldr pc, _vector_resv
+ ldr pc, _vector_irq
+ ldr pc, _vector_fiq
+
+_vector_undef: .word vector_undef
+_vector_swi: .word vector_swi
+_vector_pabt: .word vector_pabt
+_vector_dabt: .word vector_dabt
+_vector_resv: .word vector_resv
+_vector_irq: .word vector_irq
+_vector_fiq: .word vector_fiq
+
+.balignl 16,0xdeadbeef
+
+/*
+ * rtthread kernel start and end
+ * which are defined in linker script
+ */
+.globl _rtthread_start
+_rtthread_start:
+ .word _start
+
+.globl _rtthread_end
+_rtthread_end:
+ .word _end
-_vector_undef: .word vector_undef
-_vector_swi: .word vector_swi
-_vector_pabt: .word vector_pabt
-_vector_dabt: .word vector_dabt
-_vector_resv: .word vector_resv
-_vector_irq: .word vector_irq
-_vector_fiq: .word vector_fiq
+/*
+ * rtthread bss start and end which are defined in linker script
+ */
+.globl _bss_start
+_bss_start:
+ .word __bss_start
+
+.globl _bss_end
+_bss_end:
+ .word __bss_end
.text
.code 32
/* the system entry */
reset:
- /* enter svc mode */
- msr cpsr_c, #SVCMODE|NOINT
-
- /*watch dog disable */
- ldr r0,=WDMOD
- ldr r1,=0x0
- str r1,[r0]
-
- /* all interrupt disable */
- ldr r0,=VICIntEnClr
- ldr r1,=0xffffffff
- str r1,[r0]
-
- ldr r1, =VICVectAddr
- ldr r0, =0x00
- str r0, [r1]
-
- ldr r1, =VICIntSelect
- ldr r0, =0x00
- str r0, [r1]
-
- /* setup stack */
- bl stack_setup
+ /* enter svc mode */
+ msr cpsr_c, #SVCMODE|NOINT
+
+ /*watch dog disable */
+ ldr r0,=WDMOD
+ ldr r1,=0x0
+ str r1,[r0]
+
+ /* all interrupt disable */
+ ldr r0,=VICIntEnClr
+ ldr r1,=0xffffffff
+ str r1,[r0]
+
+ ldr r1, =VICVectAddr
+ ldr r0, =0x00
+ str r0, [r1]
+
+ ldr r1, =VICIntSelect
+ ldr r0, =0x00
+ str r0, [r1]
+
+ /* setup stack */
+ bl stack_setup
+
+ /* copy .data to SRAM */
+ ldr r1, =_sidata /* .data start in image */
+ ldr r2, =_edata /* .data end in image */
+ ldr r3, =_sdata /* sram data start */
+data_loop:
+ ldr r0, [r1, #0]
+ str r0, [r3]
+
+ add r1, r1, #4
+ add r3, r3, #4
+
+ cmp r3, r2 /* check if data to clear */
+ blo data_loop /* loop until done */
-_rtthread_startup: .word rtthread_startup
+ /* clear .bss */
+ mov r0,#0 /* get a zero */
+ ldr r1,=__bss_start /* bss start */
+ ldr r2,=__bss_end /* bss end */
+
+bss_loop:
+ cmp r1,r2 /* check if data to clear */
+ strlo r0,[r1],#4 /* clear 4 bytes */
+ blo bss_loop /* loop until done */
- .equ USERMODE, 0x10
- .equ FIQMODE, 0x11
- .equ IRQMODE, 0x12
- .equ SVCMODE, 0x13
- .equ ABORTMODE, 0x17
- .equ UNDEFMODE, 0x1b
- .equ MODEMASK, 0x1f
- .equ NOINT, 0xc0
+ /* call C++ constructors of global objects */
+ ldr r0, =__ctors_start__
+ ldr r1, =__ctors_end__
+
+ctor_loop:
+ cmp r0, r1
+ beq ctor_end
+ ldr r2, [r0], #4
+ stmfd sp!, {r0-r1}
+ mov lr, pc
+ bx r2
+ ldmfd sp!, {r0-r1}
+ b ctor_loop
+ctor_end:
+
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+
+_rtthread_startup:
+ .word rtthread_startup
+
+ .equ USERMODE, 0x10
+ .equ FIQMODE, 0x11
+ .equ IRQMODE, 0x12
+ .equ SVCMODE, 0x13
+ .equ ABORTMODE, 0x17
+ .equ UNDEFMODE, 0x1b
+ .equ MODEMASK, 0x1f
+ .equ NOINT, 0xc0
/* exception handlers */
-vector_undef: bl rt_hw_trap_udef
-vector_swi: bl rt_hw_trap_swi
-vector_pabt: bl rt_hw_trap_pabt
-vector_dabt: bl rt_hw_trap_dabt
-vector_resv: bl rt_hw_trap_resv
+vector_undef: bl rt_hw_trap_udef
+vector_swi: bl rt_hw_trap_swi
+vector_pabt: bl rt_hw_trap_pabt
+vector_dabt: bl rt_hw_trap_dabt
+vector_resv: bl rt_hw_trap_resv
.globl rt_interrupt_enter
.globl rt_interrupt_leave
.globl rt_thread_switch_interrput_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
-vector_irq:
- stmfd sp!, {r0-r12,lr}
- bl rt_interrupt_enter
- bl rt_hw_trap_irq
- bl rt_interrupt_leave
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
- /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
- ldr r0, =rt_thread_switch_interrput_flag
- ldr r1, [r0]
- cmp r1, #1
- beq _interrupt_thread_switch
+ /* if rt_thread_switch_interrput_flag set,
+ * jump to _interrupt_thread_switch and don't return
+ */
+ ldr r0, =rt_thread_switch_interrput_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq _interrupt_thread_switch
- ldmfd sp!, {r0-r12,lr}
- subs pc, lr, #4
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
- .align 5
+ .align 5
vector_fiq:
- stmfd sp!,{r0-r7,lr}
- bl rt_hw_trap_fiq
- ldmfd sp!,{r0-r7,lr}
- subs pc,lr,#4
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc,lr,#4
_interrupt_thread_switch:
- mov r1, #0 @ clear rt_thread_switch_interrput_flag
- str r1, [r0]
+ mov r1, #0 /* clear rt_thread_switch_interrput_flag */
+ str r1, [r0]
- ldmfd sp!, {r0-r12,lr} @ reload saved registers
- stmfd sp!, {r0-r3} @ save r0-r3
- mov r1, sp
- add sp, sp, #16 @ restore sp
- sub r2, lr, #4 @ save old task's pc to r2
+ ldmfd sp!, {r0-r12,lr} /* reload saved registers */
+ stmfd sp!, {r0-r3} /* save r0-r3 */
+ mov r1, sp
+ add sp, sp, #16 /* restore sp */
+ sub r2, lr, #4 /* save old task's pc to r2 */
- mrs r3, spsr @ disable interrupt
- orr r0, r3, #NOINT
- msr spsr_c, r0
+ mrs r3, spsr /* disable interrupt */
+ orr r0, r3, #NOINT
+ msr spsr_c, r0
- ldr r0, =.+8 @ switch to interrupted task's stack
- movs pc, r0
+ ldr r0, =.+8 /* switch to interrupted task's stack */
+ movs pc, r0
- stmfd sp!, {r2} @ push old task's pc
- stmfd sp!, {r4-r12,lr} @ push old task's lr,r12-r4
- mov r4, r1 @ Special optimised code below
- mov r5, r3
- ldmfd r4!, {r0-r3}
- stmfd sp!, {r0-r3} @ push old task's r3-r0
- stmfd sp!, {r5} @ push old task's psr
- mrs r4, spsr
- stmfd sp!, {r4} @ push old task's spsr
+ stmfd sp!, {r2} /* push old task's pc */
+ stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
+ mov r4, r1 /* Special optimised code below */
+ mov r5, r3
+ ldmfd r4!, {r0-r3}
+ stmfd sp!, {r0-r3} /* push old task's r3-r0 */
+ stmfd sp!, {r5} /* push old task's psr */
+ mrs r4, spsr
+ stmfd sp!, {r4} /* push old task's spsr */
- ldr r4, =rt_interrupt_from_thread
- ldr r5, [r4]
- str sp, [r5] @ store sp in preempted tasks's TCB
+ ldr r4, =rt_interrupt_from_thread
+ ldr r5, [r4]
+ str sp, [r5] /* store sp in preempted tasks's TCB */
- ldr r6, =rt_interrupt_to_thread
- ldr r6, [r6]
- ldr sp, [r6] @ get new task's stack pointer
+ ldr r6, =rt_interrupt_to_thread
+ ldr r6, [r6]
+ ldr sp, [r6] /* get new task's stack pointer */
- ldmfd sp!, {r4} @ pop new task's spsr
- msr SPSR_cxsf, r4
- ldmfd sp!, {r4} @ pop new task's psr
- msr CPSR_cxsf, r4
+ ldmfd sp!, {r4} /* pop new task's spsr */
+ msr SPSR_cxsf, r4
+ ldmfd sp!, {r4} /* pop new task's psr */
+ msr CPSR_cxsf, r4
- ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
+ ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
-/* each mode stack memory */
stack_setup:
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1, r0, #UNDEFMODE|NOINT
- msr cpsr_cxsf, r1 @ undef mode
- ldr sp, =__UndStack_end
-
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1,r0,#ABORTMODE|NOINT
- msr cpsr_cxsf,r1 @ abort mode
- ldr sp,=__ABTStack_end
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r1, r0, #UNDEFMODE|NOINT
+ msr cpsr_cxsf, r1 /* undef mode */
+ ldr sp, =UDF_STACK
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1,r0,#IRQMODE|NOINT
- msr cpsr_cxsf,r1 @ IRQ mode
- ldr sp,=__IRQStack_end
+ orr r1,r0,#ABORTMODE|NOINT
+ msr cpsr_cxsf,r1 /* abort mode */
+ ldr sp, =ABT_STACK
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1,r0,#FIQMODE|NOINT
- msr cpsr_cxsf,r1 @ FIQ mode
- ldr sp,=__FIQStack_end
+ orr r1,r0,#IRQMODE|NOINT
+ msr cpsr_cxsf,r1 /* IRQ mode */
+ ldr sp, =IRQ_STACK
- mrs r0, cpsr
- bic r0, r0, #MODEMASK
- orr r1,r0,#SVCMODE|NOINT
- msr cpsr_cxsf,r1 @ SVC mode
- ldr sp,=__SVCStack_end
+ orr r1,r0,#FIQMODE|NOINT
+ msr cpsr_cxsf,r1 /* FIQ mode */
+ ldr sp, =FIQ_STACK
- /* USER mode is not initialized. */
- mrs r0, cpsr
- bic r0, r0, #MODEMASK|0x80 //IRQ enable and FIQ disable
- orr r1,r0,#USERMODE
- msr cpsr_cxsf,r1 @ usr mode
- ldr sp,=__USRStack_end
-
- ldr pc, _rtthread_startup
+ bic r0,r0,#MODEMASK
+ orr r1,r0,#SVCMODE|NOINT
+ msr cpsr_cxsf,r1 /* SVC mode */
+ ldr sp, =SVC_STACK
+ /* USER mode is not initialized. */
+ mov pc,lr /* The LR register may be not valid for the mode changes.*/
diff --git a/libcpu/arm/lpc24xx/trap.c b/libcpu/arm/lpc24xx/trap.c
index e8c18c4498..e7377c94f7 100644
--- a/libcpu/arm/lpc24xx/trap.c
+++ b/libcpu/arm/lpc24xx/trap.c
@@ -121,6 +121,8 @@ void rt_hw_trap_irq()
rt_isr_handler_t isr_func;
isr_func = (rt_isr_handler_t) VICVectAddr;
+
+ /* fixme, how to get interrupt number */
isr_func(0);
}