From da74af2347cfee577b202cf4e26c1af16c05f5b6 Mon Sep 17 00:00:00 2001 From: "luohui2320@gmail.com" Date: Tue, 23 Aug 2011 14:48:10 +0000 Subject: [PATCH] AT91SAM9260 branch 1. Support Keil MDK development environment 2. Modify EMAC driver according to the changes of lwIP API in reversion 1668 and 1669 git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1681 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- bsp/at91sam9260/application.c | 13 +- bsp/at91sam9260/macb.c | 31 ++- bsp/at91sam9260/macb.h | 1 + bsp/at91sam9260/mii.h | 2 +- bsp/at91sam9260/startup.c | 13 ++ libcpu/arm/at91sam926x/at91sam926x.h | 4 + libcpu/arm/at91sam926x/context_rvds.S | 107 +++++++++ libcpu/arm/at91sam926x/gpio.h | 3 +- libcpu/arm/at91sam926x/interrupt.c | 7 +- libcpu/arm/at91sam926x/io.h | 8 +- libcpu/arm/at91sam926x/start_rvds.S | 315 ++++++++++++++++++++++++++ libcpu/arm/at91sam926x/system_clock.c | 40 +++- 12 files changed, 508 insertions(+), 36 deletions(-) create mode 100644 libcpu/arm/at91sam926x/context_rvds.S create mode 100644 libcpu/arm/at91sam926x/start_rvds.S diff --git a/bsp/at91sam9260/application.c b/bsp/at91sam9260/application.c index 9b229f57b..97c413b45 100755 --- a/bsp/at91sam9260/application.c +++ b/bsp/at91sam9260/application.c @@ -32,6 +32,16 @@ #endif #endif +#if defined(RT_USING_DFS_DEVFS) +#include +#endif + +#ifdef RT_USING_LWIP +#include +#include +#include "macb.h" +#endif + #ifdef RT_USING_LED #include "led.h" #endif @@ -90,6 +100,7 @@ void rt_init_thread_entry(void* parameter) rt_kprintf("UFFS File System initialzation failed!\n"); } #endif + } #endif @@ -98,8 +109,6 @@ void rt_init_thread_entry(void* parameter) /* register ethernetif device */ eth_system_device_init(); rt_hw_macb_init(); - /* re-init device driver */ - rt_device_init_all(); /* init lwip system */ lwip_sys_init(); rt_kprintf("TCP/IP initialized!\n"); diff --git a/bsp/at91sam9260/macb.c b/bsp/at91sam9260/macb.c index 898a21d0d..e29a50437 100755 --- a/bsp/at91sam9260/macb.c +++ b/bsp/at91sam9260/macb.c @@ -68,7 +68,7 @@ struct rt_macb_eth /* inherit from ethernet device */ struct eth_device parent; - void *regs; + unsigned int regs; unsigned int rx_tail; unsigned int tx_head; @@ -213,9 +213,9 @@ static rt_uint16_t macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg) static void macb_phy_reset(rt_device_t dev) { - struct rt_macb_eth *macb = dev->user_data;; int i; rt_uint16_t status, adv; + struct rt_macb_eth *macb = dev->user_data;; adv = ADVERTISE_CSMA | ADVERTISE_ALL; macb_mdio_write(macb, MII_ADVERTISE, adv); @@ -322,13 +322,15 @@ void macb_update_link(struct rt_macb_eth *macb) ? 100 : 10); macb->duplex = (media & ADVERTISE_FULL) ? 1 : 0; rt_kprintf("%s: link up (%dMbps/%s-duplex)\n", - dev->parent.name, macb->speed, - DUPLEX_FULL == macb->duplex ? "Full":"Half"); - netif_set_link_up(macb->parent.netif); + dev->parent.name, macb->speed, + DUPLEX_FULL == macb->duplex ? "Full":"Half"); + macb->parent.link_status = 1; } else { rt_kprintf("%s: link down\n", dev->parent.name); - netif_set_link_down(macb->parent.netif); + macb->parent.link_status = 0; } + + eth_device_linkchange(&macb->parent, RT_TRUE); } } @@ -458,13 +460,11 @@ static rt_err_t rt_macb_control(rt_device_t dev, rt_uint8_t cmd, void *args) /* transmit packet. */ rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p) { - struct rt_macb_eth *macb = dev->user_data; struct pbuf* q; - rt_uint32_t len; rt_uint8_t* bufptr, *buf = RT_NULL; - unsigned long paddr, ctrl; + unsigned long ctrl; + struct rt_macb_eth *macb = dev->user_data; unsigned int tx_head = macb->tx_head; - int i; /* lock macb device */ rt_sem_take(&sem_lock, RT_WAITING_FOREVER); @@ -500,7 +500,6 @@ rt_err_t rt_macb_tx( rt_device_t dev, struct pbuf* p) /* wait ack */ rt_sem_take(&sem_ack, RT_WAITING_FOREVER); rt_free(buf); - buf == RT_NULL; return RT_EOK; } @@ -555,7 +554,7 @@ struct pbuf *rt_macb_rx(rt_device_t dev) } if (status & RXBUF_FRAME_END) { - buffer = macb->rx_buffer + 128 * macb->rx_tail; + buffer = (void *)((unsigned int)macb->rx_buffer + 128 * macb->rx_tail); len = status & RXBUF_FRMLEN_MASK; p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); if (!p) @@ -579,14 +578,14 @@ struct pbuf *rt_macb_rx(rt_device_t dev) taillen = len - headlen; memcpy((void *)buf, buffer, headlen); - memcpy((void *)buf + headlen, + memcpy((void *)((unsigned int)buf + headlen), macb->rx_buffer, taillen); buffer = (void *)buf; for (q = p; q != RT_NULL; q= q->next) { /* read data from device */ memcpy((void *)q->payload, buffer, q->len); - buffer += q->len; + buffer = (void *)((unsigned int)buffer + q->len); } rt_free(buf); buf = RT_NULL; @@ -595,7 +594,7 @@ struct pbuf *rt_macb_rx(rt_device_t dev) { /* read data from device */ memcpy((void *)q->payload, buffer, q->len); - buffer += q->len; + buffer = (void *)((unsigned int)buffer + q->len); } } @@ -643,7 +642,7 @@ void macb_initialize() macb->rx_ring_dma = (unsigned long)macb->rx_ring; macb->tx_ring_dma = (unsigned long)macb->tx_ring; - macb->regs = (void *)AT91SAM9260_BASE_EMAC; + macb->regs = AT91SAM9260_BASE_EMAC; macb->phy_addr = 0x00; /* diff --git a/bsp/at91sam9260/macb.h b/bsp/at91sam9260/macb.h index 3b84bfa15..8d5950e78 100755 --- a/bsp/at91sam9260/macb.h +++ b/bsp/at91sam9260/macb.h @@ -330,6 +330,7 @@ struct dma_desc { #define MACB_TX_USED_OFFSET 31 #define MACB_TX_USED_SIZE 1 +void rt_hw_macb_init(); #endif /* _MACB_H */ diff --git a/bsp/at91sam9260/mii.h b/bsp/at91sam9260/mii.h index 50a02f1e1..8c932039e 100644 --- a/bsp/at91sam9260/mii.h +++ b/bsp/at91sam9260/mii.h @@ -158,7 +158,7 @@ * 100T4 this is fine. If your phy places 100T4 elsewhere in the * priority order, you will need to roll your own function. */ -static inline unsigned int mii_nway_result (unsigned int negotiated) +rt_inline unsigned int mii_nway_result (unsigned int negotiated) { unsigned int ret; diff --git a/bsp/at91sam9260/startup.c b/bsp/at91sam9260/startup.c index d7382f5e7..3e3d85cd2 100755 --- a/bsp/at91sam9260/startup.c +++ b/bsp/at91sam9260/startup.c @@ -20,12 +20,17 @@ #include #endif +#ifdef RT_USING_DEVICE +#include +#endif + extern void rt_hw_interrupt_init(void); extern void rt_hw_board_init(void); extern void rt_serial_init(void); extern void rt_system_timer_init(void); extern void rt_system_scheduler_init(void); extern void rt_thread_idle_init(void); +extern void mmu_invalidate_icache(); extern void rt_hw_cpu_icache_enable(void); extern void rt_show_version(void); extern void rt_system_heap_init(void*, void*); @@ -174,4 +179,12 @@ void rtthread_startup(void) return ; } +int main(void) +{ + /* startup RT-Thread RTOS */ + rtthread_startup(); + + return 0; +} + /*@}*/ diff --git a/libcpu/arm/at91sam926x/at91sam926x.h b/libcpu/arm/at91sam926x/at91sam926x.h index 8101fecc9..8f164edb1 100755 --- a/libcpu/arm/at91sam926x/at91sam926x.h +++ b/libcpu/arm/at91sam926x/at91sam926x.h @@ -203,6 +203,10 @@ struct rt_hw_register #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +extern struct clk *clk_get(const char *id); +extern rt_uint32_t clk_get_rate(struct clk *clk); +extern void rt_hw_clock_init(void); + #ifdef __cplusplus } #endif diff --git a/libcpu/arm/at91sam926x/context_rvds.S b/libcpu/arm/at91sam926x/context_rvds.S new file mode 100644 index 000000000..60aaa37ac --- /dev/null +++ b/libcpu/arm/at91sam926x/context_rvds.S @@ -0,0 +1,107 @@ +;/* +; * File : context_rvds.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * The license and distribution terms for this file may be +; * found in the file LICENSE in this distribution or at +; * http://www.rt-thread.org/license/LICENSE +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety copy from mini2440 +; */ + +NOINT EQU 0xc0 ; disable interrupt in psr + + AREA |.text|, CODE, READONLY, ALIGN=2 + ARM + REQUIRE8 + PRESERVE8 + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ +rt_hw_interrupt_disable PROC + EXPORT rt_hw_interrupt_disable + MRS r0, cpsr + ORR r1, r0, #NOINT + MSR cpsr_c, r1 + BX lr + ENDP + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ +rt_hw_interrupt_enable PROC + EXPORT rt_hw_interrupt_enable + MSR cpsr_c, r0 + BX lr + ENDP + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ +rt_hw_context_switch PROC + EXPORT rt_hw_context_switch + STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC) + STMFD sp!, {r0-r12, lr} ; push lr & register file + + MRS r4, cpsr + STMFD sp!, {r4} ; push cpsr + MRS r4, spsr + STMFD sp!, {r4} ; push spsr + + STR sp, [r0] ; store sp in preempted tasks TCB + LDR sp, [r1] ; get new task stack pointer + + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 + + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + ENDP + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; */ +rt_hw_context_switch_to PROC + EXPORT rt_hw_context_switch_to + LDR sp, [r0] ; get new task stack pointer + + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 + + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + ENDP + +;/* +; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); +; */ + IMPORT rt_thread_switch_interrput_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +rt_hw_context_switch_interrupt PROC + EXPORT rt_hw_context_switch_interrupt + LDR r2, =rt_thread_switch_interrput_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1 + STR r3, [r2] + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] +_reswitch + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + BX lr + ENDP + + END diff --git a/libcpu/arm/at91sam926x/gpio.h b/libcpu/arm/at91sam926x/gpio.h index e132b9982..1872d3d68 100644 --- a/libcpu/arm/at91sam926x/gpio.h +++ b/libcpu/arm/at91sam926x/gpio.h @@ -1,6 +1,7 @@ #ifndef __GPIO_H__ #define __GPIO_H__ +#include #include #define PIN_BASE AIC_IRQS @@ -111,7 +112,7 @@ #define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) -static inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio) +rt_inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio) { return gpio; } diff --git a/libcpu/arm/at91sam926x/interrupt.c b/libcpu/arm/at91sam926x/interrupt.c index dd556fb0a..392b46902 100755 --- a/libcpu/arm/at91sam926x/interrupt.c +++ b/libcpu/arm/at91sam926x/interrupt.c @@ -76,6 +76,9 @@ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = { */ /*@{*/ +void rt_hw_interrupt_mask(int irq); +void rt_hw_interrupt_umask(int irq); + rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); @@ -102,7 +105,7 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) irq_n = AIC_IRQS + 32*2; } else - return; + return RT_NULL; isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); while (isr) { @@ -113,6 +116,8 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) isr >>= 1; irq_n++; } + + return RT_NULL; } /* diff --git a/libcpu/arm/at91sam926x/io.h b/libcpu/arm/at91sam926x/io.h index f634778b0..3afdd1cef 100755 --- a/libcpu/arm/at91sam926x/io.h +++ b/libcpu/arm/at91sam926x/io.h @@ -28,16 +28,16 @@ #define writel(v,a) (*(volatile unsigned int *)(a) = (v)) -static inline unsigned int at91_sys_read(unsigned int reg_offset) +rt_inline unsigned int at91_sys_read(unsigned int reg_offset) { - void *addr = (void *)AT91_BASE_SYS; + unsigned int addr = AT91_BASE_SYS; return readl(addr + reg_offset); } -static inline void at91_sys_write(unsigned int reg_offset, unsigned long value) +rt_inline void at91_sys_write(unsigned int reg_offset, unsigned long value) { - void *addr = (void *)AT91_BASE_SYS; + unsigned int addr = AT91_BASE_SYS; writel(value, addr + reg_offset); } diff --git a/libcpu/arm/at91sam926x/start_rvds.S b/libcpu/arm/at91sam926x/start_rvds.S new file mode 100644 index 000000000..bc2a0cc87 --- /dev/null +++ b/libcpu/arm/at91sam926x/start_rvds.S @@ -0,0 +1,315 @@ +;/* +; * File : start_rvds.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * The license and distribution terms for this file may be +; * found in the file LICENSE in this distribution or at +; * http://www.rt-thread.org/license/LICENSE +; * +; * Change Logs: +; * Date Author Notes +; * 2011-08-14 weety first version +; */ + + +; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs + +Mode_USR EQU 0x10 +Mode_FIQ EQU 0x11 +Mode_IRQ EQU 0x12 +Mode_SVC EQU 0x13 +Mode_ABT EQU 0x17 +Mode_UND EQU 0x1B +Mode_SYS EQU 0x1F + +SVCMODE EQU 0x13 +MODEMASK EQU 0x1f + +I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled +F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled + + +;----------------------- Stack and Heap Definitions ---------------------------- + +;// Stack Configuration (Stack Sizes in Bytes) +;// Undefined Mode <0x0-0xFFFFFFFF:8> +;// Supervisor Mode <0x0-0xFFFFFFFF:8> +;// Abort Mode <0x0-0xFFFFFFFF:8> +;// Fast Interrupt Mode <0x0-0xFFFFFFFF:8> +;// Interrupt Mode <0x0-0xFFFFFFFF:8> +;// User/System Mode <0x0-0xFFFFFFFF:8> +;// + +UND_Stack_Size EQU 512 +SVC_Stack_Size EQU 4096 +ABT_Stack_Size EQU 512 +FIQ_Stack_Size EQU 1024 +IRQ_Stack_Size EQU 1024 +USR_Stack_Size EQU 512 + +ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + FIQ_Stack_Size + IRQ_Stack_Size) + + AREA STACK, NOINIT, READWRITE, ALIGN=3 + +Stack_Mem SPACE USR_Stack_Size +__initial_sp SPACE ISR_Stack_Size +Stack_Top + + +;// Heap Configuration +;// Heap Size (in Bytes) <0x0-0xFFFFFFFF> +;// + +Heap_Size EQU 0x00000000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + +;----------------------- Memory Definitions ------------------------------------ + +AT91_MATRIX_BASE EQU 0xffffee00 +AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100) +AT91_MATRIX_RCB0 EQU 0x00000001 +AT91_MATRIX_RCB1 EQU 0x00000002 +AT91_AIC_BASE EQU 0xfffff000 +AT91_AIC_IDCR EQU 0x124 +AT91_AIC_ICCR EQU 0x128 + +;----------------------- CODE -------------------------------------------------- + + PRESERVE8 + + +; Area Definition and Entry Point +; Startup Code must be linked first at Address at which it expects to run. + + AREA RESET, CODE, READONLY + ARM + +; Exception Vectors +; Mapped to Address 0. +; Absolute addressing mode must be used. +; Dummy Handlers are implemented as infinite loops which can be modified. + + EXPORT Entry_Point +Entry_Point +Vectors LDR PC, Reset_Addr + LDR PC, Undef_Addr + LDR PC, SWI_Addr + LDR PC, PAbt_Addr + LDR PC, DAbt_Addr + NOP + LDR PC, IRQ_Addr + LDR PC, FIQ_Addr + +Reset_Addr DCD Reset_Handler +Undef_Addr DCD Undef_Handler +SWI_Addr DCD SWI_Handler +PAbt_Addr DCD PAbt_Handler +DAbt_Addr DCD DAbt_Handler + DCD 0 ; Reserved Address +IRQ_Addr DCD IRQ_Handler +FIQ_Addr DCD FIQ_Handler + +Undef_Handler B Undef_Handler +SWI_Handler B SWI_Handler +PAbt_Handler B PAbt_Handler +;DAbt_Handler B DAbt_Handler +FIQ_Handler B FIQ_Handler + +;* +;************************************************************************* +;* +;* Interrupt handling +;* +;************************************************************************* +;* +; DAbt Handler +DAbt_Handler + IMPORT rt_hw_trap_dabt + + sub sp, sp, #72 + stmia sp, {r0 - r12} ;/* Calling r0-r12 */ + add r8, sp, #60 + stmdb r8, {sp, lr} ;/* Calling SP, LR */ + str lr, [r8, #0] ;/* Save calling PC */ + mrs r6, spsr + str r6, [r8, #4] ;/* Save CPSR */ + str r0, [r8, #8] ;/* Save OLD_R0 */ + mov r0, sp + + bl rt_hw_trap_dabt + + +;########################################## +; Reset Handler + + EXPORT Reset_Handler +Reset_Handler + + +; set the cpu to SVC32 mode----------------------------------------------------- + + MRS R0,CPSR + BIC R0,R0,#MODEMASK + ORR R0,R0,#SVCMODE + MSR CPSR_cxsf,R0 + LDR R1, =AT91_AIC_BASE + LDR R0, =0xffffffff + STR R0, [R1, #AT91_AIC_IDCR] + STR R0, [R1, #AT91_AIC_ICCR] + +; remap internal ram to 0x00000000 address + LDR R0, =AT91_MATRIX_MRCR + LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1) + STR R1, [R0] + + +; Copy Exception Vectors to Internal RAM --------------------------------------- + + ADR R8, Vectors ; Source + LDR R9, =0x00 ; Destination + LDMIA R8!, {R0-R7} ; Load Vectors + STMIA R9!, {R0-R7} ; Store Vectors + LDMIA R8!, {R0-R7} ; Load Handler Addresses + STMIA R9!, {R0-R7} ; Store Handler Addresses + + +; Setup Stack for each mode ---------------------------------------------------- + + LDR R0, =Stack_Top + +; Enter Undefined Instruction Mode and set its Stack Pointer + MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit + MOV SP, R0 + SUB R0, R0, #UND_Stack_Size + +; Enter Abort Mode and set its Stack Pointer + MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit + MOV SP, R0 + SUB R0, R0, #ABT_Stack_Size + +; Enter FIQ Mode and set its Stack Pointer + MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit + MOV SP, R0 + SUB R0, R0, #FIQ_Stack_Size + +; Enter IRQ Mode and set its Stack Pointer + MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit + MOV SP, R0 + SUB R0, R0, #IRQ_Stack_Size + +; Enter Supervisor Mode and set its Stack Pointer + MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit + MOV SP, R0 + SUB R0, R0, #SVC_Stack_Size + +; Enter User Mode and set its Stack Pointer + ; MSR CPSR_c, #Mode_USR + MOV SP, R0 + SUB SL, SP, #USR_Stack_Size + +; Enter the C code ------------------------------------------------------------- + + IMPORT __main + LDR R0, =__main + BX R0 + + IMPORT rt_interrupt_enter + IMPORT rt_interrupt_leave + IMPORT rt_thread_switch_interrput_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + IMPORT rt_hw_trap_irq + +IRQ_Handler PROC + EXPORT IRQ_Handler + 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 + ; rt_hw_context_switch_interrupt_do and don't return + LDR r0, =rt_thread_switch_interrput_flag + LDR r1, [r0] + CMP r1, #1 + BEQ rt_hw_context_switch_interrupt_do + + LDMFD sp!, {r0-r12,lr} + SUBS pc, lr, #4 + ENDP + +; /* +; * void rt_hw_context_switch_interrupt_do(rt_base_t flag) +; */ +rt_hw_context_switch_interrupt_do PROC + EXPORT rt_hw_context_switch_interrupt_do + MOV r1, #0 ; clear 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 + + MRS r3, spsr ; get cpsr of interrupt thread + + ; switch to SVC mode and no interrupt + MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC + + 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 cpsr + 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 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!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc + ENDP + + IF :DEF:__MICROLIB + + EXPORT __heap_base + EXPORT __heap_limit + + ELSE +; User Initial Stack & Heap + AREA |.text|, CODE, READONLY + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + USR_Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDIF + + + END + diff --git a/libcpu/arm/at91sam926x/system_clock.c b/libcpu/arm/at91sam926x/system_clock.c index c7667b763..8dc359599 100755 --- a/libcpu/arm/at91sam926x/system_clock.c +++ b/libcpu/arm/at91sam926x/system_clock.c @@ -26,34 +26,52 @@ struct clk { }; static struct clk clk32k = { - .name = "clk32k", - .rate_hz = AT91_SLOW_CLOCK, + "clk32k", + AT91_SLOW_CLOCK, + RT_NULL, + {RT_NULL, RT_NULL}, }; static struct clk main_clk = { - .name = "main", + "main", + 0, + RT_NULL, + {RT_NULL, RT_NULL}, }; static struct clk plla = { - .name = "plla", + "plla", + 0, + RT_NULL, + {RT_NULL, RT_NULL}, }; static struct clk mck = { - .name = "mck", + "mck", + 0, + RT_NULL, + {RT_NULL, RT_NULL}, }; static struct clk uhpck = { - .name = "uhpck", + "uhpck", + 0, + RT_NULL, + {RT_NULL, RT_NULL}, }; static struct clk pllb = { - .name = "pllb", - .parent = &main_clk, + "pllb", + 0, + &main_clk, + {RT_NULL, RT_NULL}, }; static struct clk udpck = { - .name = "udpck", - .parent = &pllb, + "udpck", + 0, + &pllb, + {RT_NULL, RT_NULL}, }; static struct clk *const standard_pmc_clocks[] = { @@ -75,7 +93,7 @@ struct clk *clk_get(const char *id) for (list = (&clocks)->next; list != &clocks; list = list->next) { clk = (struct clk *)rt_list_entry(list, struct clk, node); - if (strcmp(id, clk->name) == 0) + if (rt_strcmp(id, clk->name) == 0) return clk; }