diff options
| author | armink <[email protected]> | 2019-12-17 20:11:46 +0800 |
|---|---|---|
| committer | armink <[email protected]> | 2019-12-17 20:11:46 +0800 |
| commit | 4875ee8a3ab95c4fbf1e09941d3f44d99a9a632b (patch) | |
| tree | 15c596c04a842bac747bbcf05a703b8da76f8eac /libcpu/arm | |
| parent | fa46d6ac861f26b472d62abdf1278c445431ce4c (diff) | |
Sync from master (75a3f3dd3a930eab1dc58fa0258a9d1605a0ac11)
Diffstat (limited to 'libcpu/arm')
| -rw-r--r-- | libcpu/arm/am335x/start_gcc.S | 1 | ||||
| -rw-r--r-- | libcpu/arm/arm926/context_gcc.S | 1 | ||||
| -rw-r--r-- | libcpu/arm/arm926/cpuport.c | 44 | ||||
| -rw-r--r-- | libcpu/arm/arm926/machine.c | 27 | ||||
| -rw-r--r-- | libcpu/arm/arm926/mmu.c | 40 | ||||
| -rw-r--r-- | libcpu/arm/arm926/mmu.h | 5 | ||||
| -rw-r--r-- | libcpu/arm/arm926/stack.c | 2 | ||||
| -rw-r--r-- | libcpu/arm/arm926/start_gcc.S | 503 | ||||
| -rw-r--r-- | libcpu/arm/arm926/trap.c | 91 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/cache.c | 6 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/context_gcc.S | 24 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/cpu.c | 6 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/stack.c | 3 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/start_gcc.S | 71 | ||||
| -rw-r--r-- | libcpu/arm/cortex-a/trap.c | 33 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m0/cpuport.c | 2 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m3/cpuport.c | 19 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m4/cpuport.c | 21 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m7/cpu_cache.c | 6 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m7/cpuport.c | 21 | ||||
| -rw-r--r-- | libcpu/arm/cortex-r4/start_gcc.S | 1 | ||||
| -rw-r--r-- | libcpu/arm/realview-a8-vmm/start_gcc.S | 1 | ||||
| -rw-r--r-- | libcpu/arm/zynq7000/start_gcc.S | 1 |
23 files changed, 589 insertions, 340 deletions
diff --git a/libcpu/arm/am335x/start_gcc.S b/libcpu/arm/am335x/start_gcc.S index 6b76fb04a4..7e996e2a80 100644 --- a/libcpu/arm/am335x/start_gcc.S +++ b/libcpu/arm/am335x/start_gcc.S @@ -33,6 +33,7 @@ .globl stack_start .globl stack_top +.align 3 stack_start: .rept ISR_Stack_Size .long 0 diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S index b6b7863679..f69aa9f5ba 100644 --- a/libcpu/arm/arm926/context_gcc.S +++ b/libcpu/arm/arm926/context_gcc.S @@ -10,6 +10,7 @@ #define NOINT 0xC0 +.text ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c index 1efb23e896..035e97d543 100644 --- a/libcpu/arm/arm926/cpuport.c +++ b/libcpu/arm/arm926/cpuport.c @@ -23,30 +23,30 @@ rt_inline rt_uint32_t cp15_rd(void) { rt_uint32_t i; - __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i)); return i; } rt_inline void cache_enable(rt_uint32_t bit) { __asm volatile(\ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "orr r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + : "r"(bit) \ + : "memory"); } rt_inline void cache_disable(rt_uint32_t bit) { __asm volatile(\ - "mrc p15,0,r0,c1,c0,0\n\t" \ - "bic r0,r0,%0\n\t" \ - "mcr p15,0,r0,c1,c0,0" \ - : \ - :"r" (bit) \ - :"memory"); + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + : "r"(bit) \ + : "memory"); } #endif @@ -152,7 +152,7 @@ void rt_hw_cpu_reset() rt_kprintf("Restarting system...\n"); machine_reset(); - while(1); /* loop forever and wait for reset to happen */ + while (1); /* loop forever and wait for reset to happen */ /* NEVER REACHED */ } @@ -206,21 +206,7 @@ int __rt_ffs(int value) #elif defined(__GNUC__) || defined(__ICCARM__) int __rt_ffs(int value) { - register rt_uint32_t x; - - if (value == 0) - return value; - - __asm - ( - "rsb %[temp], %[val], #0\n" - "and %[temp], %[temp], %[val]\n" - "clz %[temp], %[temp]\n" - "rsb %[temp], %[temp], #32\n" - :[temp] "=r"(x) - :[val] "r"(value) - ); - return x; + return __builtin_ffs(value); } #endif diff --git a/libcpu/arm/arm926/machine.c b/libcpu/arm/arm926/machine.c new file mode 100644 index 0000000000..aa26d10ec6 --- /dev/null +++ b/libcpu/arm/arm926/machine.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-02-08 RT-Thread the first version + */ + +#include <rthw.h> +#include <rtthread.h> + +RT_WEAK void machine_reset(void) +{ + rt_kprintf("reboot system...\n"); + rt_hw_interrupt_disable(); + while (1); +} + +RT_WEAK void machine_shutdown(void) +{ + rt_kprintf("shutdown...\n"); + rt_hw_interrupt_disable(); + while (1); +} + diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c index f1e475189b..19d70b9b0b 100644 --- a/libcpu/arm/arm926/mmu.c +++ b/libcpu/arm/arm926/mmu.c @@ -140,7 +140,7 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while(ptr < buffer + size) + while (ptr < buffer + size) { __asm volatile { MCR p15, 0, ptr, c7, c14, 1 } ptr += CACHE_LINE_SIZE; @@ -211,18 +211,18 @@ void mmu_setttbase(register rt_uint32_t i) * set by page table entry */ value = 0; - asm volatile ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); value = 0x55555555; - asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); - asm volatile ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); + asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); } void mmu_set_domain(register rt_uint32_t i) { - asm volatile ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); + asm volatile("mcr p15,0, %0, c3, c0, 0": :"r"(i)); } void mmu_enable() @@ -321,7 +321,7 @@ void mmu_disable_alignfault() void mmu_clean_invalidated_cache_index(int index) { - asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); + asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index)); } void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) @@ -330,9 +330,9 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) ptr = buffer & ~(CACHE_LINE_SIZE - 1); - while(ptr < buffer + size) + while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -347,7 +347,7 @@ void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -361,7 +361,7 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) while (ptr < buffer + size) { - asm volatile ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr)); ptr += CACHE_LINE_SIZE; } @@ -369,19 +369,19 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) void mmu_invalidate_tlb() { - asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0)); } void mmu_invalidate_icache() { - asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0)); } void mmu_invalidate_dcache_all() { - asm volatile ("mcr p15, 0, %0, c7, c6, 0": :"r" (0)); + asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0)); } #endif @@ -389,10 +389,10 @@ void mmu_invalidate_dcache_all() /* level1 page table */ #if defined(__ICCARM__) #pragma data_alignment=(16*1024) -static volatile rt_uint32_t _page_table[4*1024]; +static volatile rt_uint32_t _page_table[4 * 1024]; #else -static volatile rt_uint32_t _page_table[4*1024] \ - __attribute__((aligned(16*1024))); +static volatile rt_uint32_t _page_table[4 * 1024] \ +__attribute__((aligned(16 * 1024))); #endif void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, @@ -401,11 +401,11 @@ void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, volatile rt_uint32_t *pTT; volatile int nSec; int i = 0; - pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20); - nSec=(vaddrEnd>>20)-(vaddrStart>>20); - for(i=0; i<=nSec; i++) + pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for (i = 0; i <= nSec; i++) { - *pTT = attr |(((paddrStart>>20)+i)<<20); + *pTT = attr | (((paddrStart >> 20) + i) << 20); pTT++; } } diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h index 7b930f5358..36fdbeacd8 100644 --- a/libcpu/arm/arm926/mmu.h +++ b/libcpu/arm/arm926/mmu.h @@ -5,6 +5,7 @@ * * Change Logs: * Date Author Notes + * 2018-02-08 RT-Thread the first version */ #ifndef __MMU_H__ @@ -45,5 +46,7 @@ struct mem_desc }; void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size); - +void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size); +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size); +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size); #endif diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c index fa98feb824..f90bfa8c22 100644 --- a/libcpu/arm/arm926/stack.c +++ b/libcpu/arm/arm926/stack.c @@ -38,7 +38,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, stack_addr += sizeof(rt_uint32_t); stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t *)stack_addr; + stk = (rt_uint32_t *)stack_addr; *(--stk) = (rt_uint32_t)tentry; /* entry point */ *(--stk) = (rt_uint32_t)texit; /* lr */ diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index fee8e018cb..35c1f1722e 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -11,295 +11,320 @@ * 2015-06-04 aozima Align stack address to 8 byte. */ -#include "rt_low_level_init.h" +.equ MODE_USR, 0x10 +.equ MODE_FIQ, 0x11 +.equ MODE_IRQ, 0x12 +.equ MODE_SVC, 0x13 +.equ MODE_ABT, 0x17 +.equ MODE_UND, 0x1B +.equ MODE_SYS, 0x1F +.equ MODEMASK, 0x1F +.equ NOINT, 0xC0 -#define S_FRAME_SIZE (18*4) //72 +.equ I_BIT, 0x80 +.equ F_BIT, 0x40 -@#define S_SPSR (17*4) //SPSR -@#define S_CPSR (16*4) //CPSR -#define S_PC (15*4) //R15 -@#define S_LR (14*4) //R14 -@#define S_SP (13*4) //R13 +.equ UND_STACK_SIZE, 0x00000100 +.equ SVC_STACK_SIZE, 0x00000100 +.equ ABT_STACK_SIZE, 0x00000100 +.equ FIQ_STACK_SIZE, 0x00000100 +.equ IRQ_STACK_SIZE, 0x00000100 +.equ SYS_STACK_SIZE, 0x00000100 -@#define S_IP (12*4) //R12 -@#define S_FP (11*4) //R11 -@#define S_R10 (10*4) -@#define S_R9 (9*4) -@#define S_R8 (8*4) -@#define S_R7 (7*4) -@#define S_R6 (6*4) -@#define S_R5 (5*4) -@#define S_R4 (4*4) -@#define S_R3 (3*4) -@#define S_R2 (2*4) -@#define S_R1 (1*4) -@#define S_R0 (0*4) + /* + *************************************** + * Interrupt vector table + *************************************** + */ +.section .vectors +.code 32 -#define MODE_SYS 0x1F -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_ABT 0x17 -#define MODE_UND 0x1B -#define MODEMASK 0x1F +.global system_vectors +system_vectors: + ldr pc, _vector_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 -#define NOINT 0xC0 +_vector_reset: + .word reset +_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 -@;----------------------- Stack and Heap Definitions --------------------------- - .section .nobss, "w" +.balignl 16,0xdeadbeef - .space UND_STK_SIZE + /* + *************************************** + * Stack and Heap Definitions + *************************************** + */ + .section .data + .space UND_STACK_SIZE .align 3 - .global UND_STACK_START -UND_STACK_START: + .global und_stack_start +und_stack_start: - .space ABT_STK_SIZE + .space ABT_STACK_SIZE .align 3 - .global ABT_STACK_START -ABT_STACK_START: + .global abt_stack_start +abt_stack_start: - .space FIQ_STK_SIZE + .space FIQ_STACK_SIZE .align 3 - .global FIQ_STACK_START -FIQ_STACK_START: + .global fiq_stack_start +fiq_stack_start: - .space IRQ_STK_SIZE + .space IRQ_STACK_SIZE .align 3 - .global IRQ_STACK_START -IRQ_STACK_START: + .global irq_stack_start +irq_stack_start: - .skip SYS_STK_SIZE + .skip SYS_STACK_SIZE .align 3 - .global SYS_STACK_START -SYS_STACK_START: + .global sys_stack_start +sys_stack_start: - .space SVC_STK_SIZE + .space SVC_STACK_SIZE .align 3 - .global SVC_STACK_START -SVC_STACK_START: - -@;--------------Jump vector table----------------------------------------------- - .section .init, "ax" - .arm + .global svc_stack_start +svc_stack_start: - .global start -start: - LDR PC, vector_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 +/* + *************************************** + * Startup Code + *************************************** + */ + .section .text + .global reset +reset: + /* Enter svc mode and mask interrupts */ + mrs r0, cpsr + bic r0, r0, #MODEMASK + orr r0, r0, #MODE_SVC|NOINT + msr cpsr_cxsf, r0 -vector_reset: - .word Reset_Handler -vector_undef: - .word Undef_Handler -vector_swi: - .word SWI_Handler -vector_pabt: - .word PAbt_Handler -vector_dabt: - .word DAbt_Handler -vector_resv: - .word Resv_Handler -vector_irq: - .word IRQ_Handler -vector_fiq: - .word FIQ_Handler + /* init cpu */ + bl cpu_init_crit + + /* todo:copyself to link address */ + + /* Copy vector to the correct address */ + ldr r0, =system_vectors + mrc p15, 0, r2, c1, c0, 0 + ands r2, r2, #(1 << 13) + ldreq r1, =0x00000000 + ldrne r1, =0xffff0000 + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} + ldmia r0!, {r2-r8, r10} + stmia r1!, {r2-r8, r10} - .balignl 16,0xdeadbeef + /* turn off the watchdog */ + ldr r0, =0x01C20CB8 + mov r1, #0x0 + str r1, [r0] -@;----------------- Reset Handler --------------------------------------------- - .global rt_low_level_init - .global main - .global Reset_Handler -Reset_Handler: - @; Set the cpu to SVC32 mode - MRS R0, CPSR - BIC R0, R0, #MODEMASK - ORR R0, R0, #MODE_SVC|NOINT - MSR CPSR_cxsf, R0 + /* mask all IRQs source */ + ldr r1, =0xffffffff + ldr r0, =0x01C20430 + str r1, [r0], #0x04 + str r1, [r0] + + /* Call low level init function */ + ldr sp, =svc_stack_start + ldr r0, =rt_low_level_init + blx r0 - @; Set CO-Processor - @; little-end锛宒isbale I/D Cache MMU, vector table is 0x00000000 - MRC P15, 0, R0, C1, C0, 0 @; Read CP15 - LDR R1, =0x00003085 @; set clear bits - BIC R0, R0, R1 - MCR P15, 0, R0, C1, C0, 0 @; Write CP15 + /* init stack */ + bl stack_setup + + /* clear bss */ + mov r0, #0 + ldr r1, =__bss_start + ldr r2, =__bss_end + +bss_clear_loop: + cmp r1, r2 + strlo r0, [r1], #4 + blo bss_clear_loop + + /* 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 - @; Call low level init function, - @; disable and clear all IRQs, Init MMU, Init interrupt controller, etc. - LDR SP, =SVC_STACK_START - LDR R0, =rt_low_level_init - BLX R0 -Setup_Stack: - @; Setup Stack for each mode - MRS R0, CPSR - BIC R0, R0, #MODEMASK - ORR R1, R0, #MODE_UND|NOINT - MSR CPSR_cxsf, R1 @; Undef mode - LDR SP, =UND_STACK_START +cpu_init_crit: + /* invalidate I/D caches */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 + mcr p15, 0, r0, c8, c7, 0 - ORR R1, R0, #MODE_ABT|NOINT - MSR CPSR_cxsf, R1 @; Abort mode - LDR SP, =ABT_STACK_START + /* disable MMU stuff and caches */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 + bic r0, r0, #0x00000087 + orr r0, r0, #0x00000002 + orr r0, r0, #0x00001000 + mcr p15, 0, r0, c1, c0, 0 - ORR R1, R0, #MODE_IRQ|NOINT - MSR CPSR_cxsf, R1 @; IRQ mode - LDR SP, =IRQ_STACK_START + bx lr + +stack_setup: + /* Setup Stack for each mode */ + mrs r0, cpsr + bic r0, r0, #MODEMASK - ORR R1, R0, #MODE_FIQ|NOINT - MSR CPSR_cxsf, R1 @; FIQ mode - LDR SP, =FIQ_STACK_START + orr r1, r0, #MODE_UND|NOINT + msr cpsr_cxsf, r1 + ldr sp, =und_stack_start - ORR R1, R0, #MODE_SYS|NOINT - MSR CPSR_cxsf,R1 @; SYS/User mode - LDR SP, =SYS_STACK_START + orr r1, r0, #MODE_ABT|NOINT + msr cpsr_cxsf, r1 + ldr sp, =abt_stack_start - ORR R1, R0, #MODE_SVC|NOINT - MSR CPSR_cxsf, R1 @; SVC mode - LDR SP, =SVC_STACK_START + orr r1, r0, #MODE_IRQ|NOINT + msr cpsr_cxsf, r1 + ldr sp, =irq_stack_start - @; clear .bss - MOV R0, #0 @; get a zero - LDR R1, =__bss_start__ @; bss start - LDR R2, =__bss_end__ @; bss end + orr r1, r0, #MODE_FIQ|NOINT + msr cpsr_cxsf, r1 + ldr sp, =fiq_stack_start -bss_clear_loop: - CMP R1, R2 @; check if data to clear - STRLO R0, [R1], #4 @; clear 4 bytes - BLO bss_clear_loop @; loop until done + orr r1, r0, #MODE_SYS|NOINT + msr cpsr_cxsf,r1 + ldr sp, =sys_stack_start - @; call C++ constructors of global objects - LDR R0, =__ctors_start__ - LDR R1, =__ctors_end__ + orr r1, r0, #MODE_SVC|NOINT + msr cpsr_cxsf, r1 + ldr sp, =svc_stack_start -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: + bx lr + +/* + *************************************** + * exception handlers + *************************************** + */ + /* Interrupt */ +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc, lr, #4 - @; Enter the C code - LDR R0, =rtthread_startup - BLX R0 +vector_irq: + stmfd sp!, {r0-r12,lr} -@;----------------- Exception Handler ----------------------------------------- - .global rt_hw_trap_udef - .global rt_hw_trap_swi - .global rt_hw_trap_pabt - .global rt_hw_trap_dabt - .global rt_hw_trap_resv - .global rt_hw_trap_irq - .global rt_hw_trap_fiq + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave - .global rt_interrupt_enter - .global rt_interrupt_leave - .global rt_thread_switch_interrupt_flag - .global rt_interrupt_from_thread - .global rt_interrupt_to_thread - - .align 5 -Undef_Handler: - SUB SP, SP, #S_FRAME_SIZE - STMIA SP, {R0 - R12} @; Calling R0-R12 - ADD R8, SP, #S_PC - 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 SPSR - MOV R0, SP - BL rt_hw_trap_udef - - .align 5 -SWI_Handler: - BL rt_hw_trap_swi - - .align 5 -PAbt_Handler: - BL rt_hw_trap_pabt + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do - .align 5 -DAbt_Handler: - SUB SP, SP, #S_FRAME_SIZE - STMIA SP, {R0 - R12} @; Calling R0-R12 - ADD R8, SP, #S_PC - 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 SPSR - MOV R0, SP - BL rt_hw_trap_dabt + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 - .align 5 -Resv_Handler: - BL rt_hw_trap_resv +rt_hw_context_switch_interrupt_do: + mov r1, #0 + str r1, [r0] - .align 5 -FIQ_Handler: - STMFD SP!, {R0-R7,LR} - BL rt_hw_trap_fiq - LDMFD SP!, {R0-R7,LR} - SUBS PC, LR, #4 + mov r1, sp + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr} + mrs r0, spsr + sub r2, lr, #4 - .align 5 -IRQ_Handler: - STMFD SP!, {R0-R12,LR} - BL rt_interrupt_enter - BL rt_hw_trap_irq - BL rt_interrupt_leave + msr cpsr_c, #I_BIT|F_BIT|MODE_SVC - @; If rt_thread_switch_interrupt_flag set, - @; jump to rt_hw_context_switch_interrupt_do and don't return - LDR R0, =rt_thread_switch_interrupt_flag - LDR R1, [R0] - CMP R1, #1 - BEQ rt_hw_context_switch_interrupt_do + stmfd sp!, {r2} + stmfd sp!, {r4-r12,lr} + ldmfd r1, {r1-r4} + stmfd sp!, {r1-r4} + stmfd sp!, {r0} - LDMFD SP!, {R0-R12,LR} - SUBS PC, LR, #4 + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] -@;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- -rt_hw_context_switch_interrupt_do: - MOV R1, #0 @; Clear flag - STR R1, [R0] @; Save to flag variable + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] - LDMFD SP!, {R0-R12,LR} @; Reload saved registers - STMFD SP, {R0-R2} @; Save R0-R2 - SUB R1, SP, #4*3 @; Save old task's SP to R1 - SUB R2, LR, #4 @; Save old task's PC to R2 + ldmfd sp!, {r4} + msr spsr_cxsf, r4 - MRS R0, SPSR @; Get CPSR of interrupt thread + ldmfd sp!, {r0-r12,lr,pc}^ - MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt + /* Exception */ +.macro push_svc_reg + sub sp, sp, #17 * 4 + stmia sp, {r0 - r12} + mov r0, sp + mrs r6, spsr + str lr, [r0, #15*4] + str r6, [r0, #16*4] + str sp, [r0, #13*4] + str lr, [r0, #14*4] +.endm - STMFD SP!, {R2} @; Push old task's PC - STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3 - LDMFD R1, {R1-R3} - STMFD SP!, {R1-R3} @; Push old task's R2-R0 - STMFD SP!, {R0} @; Push old task's CPSR +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . - LDR R4, =rt_interrupt_from_thread - LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB - STR SP, [R5] @; Store SP in preempted tasks's TCB +vector_undef: + push_svc_reg + bl rt_hw_trap_udef + b . - LDR R6, =rt_interrupt_to_thread - LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB - LDR SP, [R6] @; Get new task's stack pointer +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . - LDMFD SP!, {R4} @; Pop new task's SPSR - MSR SPSR_cxsf, R4 +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . - LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . diff --git a/libcpu/arm/arm926/trap.c b/libcpu/arm/arm926/trap.c index 054cc2741a..9e7ba48037 100644 --- a/libcpu/arm/arm926/trap.c +++ b/libcpu/arm/arm926/trap.c @@ -41,14 +41,18 @@ struct rt_hw_register rt_uint32_t cpsr; rt_uint32_t ORIG_r0; }; - +static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; +void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)) +{ + rt_exception_hook = exception_handle; +} /** * this function will show registers of CPU * * @param regs the registers point */ -void rt_hw_show_register (struct rt_hw_register *regs) +void rt_hw_show_register(struct rt_hw_register *regs) { rt_kprintf("Execption:\n"); rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", @@ -74,6 +78,13 @@ void rt_hw_show_register (struct rt_hw_register *regs) */ void rt_hw_trap_udef(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("undefined instruction\n"); @@ -96,6 +107,13 @@ void rt_hw_trap_udef(struct rt_hw_register *regs) */ void rt_hw_trap_swi(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("software interrupt\n"); @@ -112,6 +130,13 @@ void rt_hw_trap_swi(struct rt_hw_register *regs) */ void rt_hw_trap_pabt(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("prefetch abort\n"); @@ -133,6 +158,13 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs) */ void rt_hw_trap_dabt(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_hw_show_register(regs); rt_kprintf("data abort\n"); @@ -153,55 +185,26 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs) */ void rt_hw_trap_resv(struct rt_hw_register *regs) { + if (rt_exception_hook != RT_NULL) + { + rt_err_t result; + + result = rt_exception_hook(regs); + if (result == RT_EOK) return; + } rt_kprintf("not used\n"); rt_hw_show_register(regs); rt_hw_cpu_shutdown(); } -extern struct rt_irq_desc irq_desc[]; -extern rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq); -extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id); - -void rt_hw_trap_irq() -{ - rt_isr_handler_t isr_func; - rt_uint32_t irq; - void *param; - - /* get irq number */ - irq = rt_hw_interrupt_get_active(INT_IRQ); +extern void rt_interrupt_dispatch(rt_uint32_t fiq_irq); - /* get interrupt service routine */ - isr_func = irq_desc[irq].handler; - param = irq_desc[irq].param; - - /* turn to interrupt service routine */ - isr_func(irq, param); - - rt_hw_interrupt_ack(INT_IRQ, irq); -#ifdef RT_USING_INTERRUPT_INFO - irq_desc[irq].counter ++; -#endif +void rt_hw_trap_irq(void) +{ + rt_interrupt_dispatch(INT_IRQ); } -void rt_hw_trap_fiq() +void rt_hw_trap_fiq(void) { - rt_isr_handler_t isr_func; - rt_uint32_t irq; - void *param; - - /* get irq number */ - irq = rt_hw_interrupt_get_active(INT_FIQ); - - /* get interrupt service routine */ - isr_func = irq_desc[irq].handler; - param = irq_desc[irq].param; - - /* turn to interrupt service routine */ - isr_func(irq, param); - - rt_hw_interrupt_ack(INT_FIQ, irq); -#ifdef RT_USING_INTERRUPT_INFO - irq_desc[irq].counter ++; -#endif + rt_interrupt_dispatch(INT_FIQ); } diff --git a/libcpu/arm/cortex-a/cache.c b/libcpu/arm/cortex-a/cache.c index 6d28d9e9f9..30af86baa1 100644 --- a/libcpu/arm/cortex-a/cache.c +++ b/libcpu/arm/cortex-a/cache.c @@ -30,6 +30,7 @@ void rt_hw_cpu_icache_invalidate(void *addr, int size) rt_uint32_t start_addr = (rt_uint32_t)addr; rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + asm volatile ("dmb":::"memory"); start_addr &= ~(line_size-1); end_addr &= ~(line_size-1); while (start_addr < end_addr) @@ -37,6 +38,7 @@ void rt_hw_cpu_icache_invalidate(void *addr, int size) asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r"(start_addr)); /* icimvau */ start_addr += line_size; } + asm volatile ("dsb\n\tisb":::"memory"); } void rt_hw_cpu_dcache_invalidate(void *addr, int size) @@ -45,6 +47,7 @@ void rt_hw_cpu_dcache_invalidate(void *addr, int size) rt_uint32_t start_addr = (rt_uint32_t)addr; rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + asm volatile ("dmb":::"memory"); start_addr &= ~(line_size-1); end_addr &= ~(line_size-1); while (start_addr < end_addr) @@ -52,6 +55,7 @@ void rt_hw_cpu_dcache_invalidate(void *addr, int size) asm volatile ("mcr p15, 0, %0, c7, c6, 1" :: "r"(start_addr)); /* dcimvac */ start_addr += line_size; } + asm volatile ("dsb":::"memory"); } void rt_hw_cpu_dcache_clean(void *addr, int size) @@ -60,6 +64,7 @@ void rt_hw_cpu_dcache_clean(void *addr, int size) rt_uint32_t start_addr = (rt_uint32_t)addr; rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1; + asm volatile ("dmb":::"memory"); start_addr &= ~(line_size-1); end_addr &= ~(line_size-1); while (start_addr < end_addr) @@ -67,6 +72,7 @@ void rt_hw_cpu_dcache_clean(void *addr, int size) asm volatile ("mcr p15, 0, %0, c7, c10, 1" :: "r"(start_addr)); /* dccmvac */ start_addr += line_size; } + asm volatile ("dsb":::"memory"); } void rt_hw_cpu_icache_ops(int ops, void *addr, int size) diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index dff7a1de68..768c5138e9 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/libcpu/arm/cortex-a/context_gcc.S @@ -76,6 +76,18 @@ rt_hw_context_switch: stmfd sp, {r13, r14}^ @ push usr_sp usr_lr sub sp, #8 #endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif str sp, [r0] @ store sp in preempted tasks TCB ldr sp, [r1] @ get new task stack pointer @@ -147,6 +159,18 @@ rt_hw_context_switch_exit: mov sp, r0 #endif #endif +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} +1: +#endif #ifdef RT_USING_LWP ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */ diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c index 6b129f89ee..7c6bf58a4b 100644 --- a/libcpu/arm/cortex-a/cpu.c +++ b/libcpu/arm/cortex-a/cpu.c @@ -14,6 +14,7 @@ #include <board.h> #ifdef RT_USING_SMP + int rt_hw_cpu_id(void) { int cpu_id; @@ -25,6 +26,11 @@ int rt_hw_cpu_id(void) return cpu_id; }; +void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) +{ + lock->slock = 0; +} + void rt_hw_spin_lock(rt_hw_spinlock_t *lock) { unsigned long tmp; diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c index d76b8a428a..07d795ab5b 100644 --- a/libcpu/arm/cortex-a/stack.c +++ b/libcpu/arm/cortex-a/stack.c @@ -60,6 +60,9 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, *(--stk) = 0; /* user lr */ *(--stk) = 0; /* user sp*/ #endif +#ifdef RT_USING_FPU + *(--stk) = 0; /* not use fpu*/ +#endif /* return task's current stack address */ return (rt_uint8_t *)stk; diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 014846f3aa..268cc7ef56 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -22,7 +22,11 @@ .equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled +#ifdef RT_USING_FPU +.equ UND_Stack_Size, 0x00000400 +#else .equ UND_Stack_Size, 0x00000000 +#endif .equ SVC_Stack_Size, 0x00000400 .equ ABT_Stack_Size, 0x00000000 .equ RT_FIQ_STACK_PGSZ, 0x00000000 @@ -37,6 +41,7 @@ .globl stack_start .globl stack_top +.align 3 stack_start: .rept ISR_Stack_Size .byte 0 @@ -50,6 +55,11 @@ _reset: /* set the cpu to SVC32 mode and disable interrupt */ cps #Mode_SVC +#ifdef RT_USING_FPU + mov r4, #0xfffffff + mcr p15, 0, r4, c1, c0, 2 +#endif + /* disable the data alignment check */ mrc p15, 0, r1, c1, c0, 0 bic r1, #(1<<1) @@ -176,6 +186,19 @@ vector_irq: stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */ sub r0, #8 #endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb r0!, {d0-d15} + vstmdb r0!, {d16-d31} + vmrs r5, fpscr + stmfd r0!, {r5} +1: + stmfd r0!, {r6} +#endif + /* now irq stack is clean */ /* r0 is task svc_sp */ /* backup r0 -> r8 */ @@ -234,6 +257,18 @@ rt_hw_context_switch_interrupt_do: stmfd sp, {r13, r14}^ @push usr_sp, usr_lr sub sp, #8 #endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif ldr r4, =rt_interrupt_from_thread ldr r5, [r4] @@ -243,6 +278,19 @@ rt_hw_context_switch_interrupt_do: ldr r6, [r6] ldr sp, [r6] @ get new task's stack pointer +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} +1: +#endif + #ifdef RT_USING_LWP ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr add sp, #8 @@ -278,7 +326,14 @@ vector_swi: .globl vector_undef vector_undef: push_svc_reg + cps #Mode_UND bl rt_hw_trap_undef +#ifdef RT_USING_FPU + ldr lr, [sp, #15*4] + ldmia sp, {r0 - r12} + add sp, sp, #17 * 4 + movs pc, lr +#endif b . .align 5 @@ -315,6 +370,12 @@ set_secondary_cpu_boot_address: .global secondary_cpu_start secondary_cpu_start: + +#ifdef RT_USING_FPU + mov r4, #0xfffffff + mcr p15, 0, r4, c1, c0, 2 +#endif + mrc p15, 0, r1, c1, c0, 1 mov r0, #(1<<6) orr r1, r0 @@ -324,6 +385,11 @@ secondary_cpu_start: bic r0, #(1<<13) mcr p15, 0, r0, c1, c0, 0 +#ifdef RT_USING_FPU + cps #Mode_UND + ldr sp, =und_stack_2_limit +#endif + cps #Mode_IRQ ldr sp, =irq_stack_2_limit @@ -349,3 +415,8 @@ irq_stack_2: .space (1 << 10) irq_stack_2_limit: +#ifdef RT_USING_FPU +und_stack_2: + .space (1 << 10) +und_stack_2_limit: +#endif diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index a25f6ac862..dc232a46ee 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -45,6 +45,39 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs) */ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) { +#ifdef RT_USING_FPU + { + uint32_t ins; + uint32_t addr; + + if (regs->cpsr & (1 << 5)) + { + /* thumb mode */ + addr = regs->pc - 2; + ins = (uint32_t)*(uint16_t*)addr; + if ((ins & (3 << 11)) != 0) + { + /* 32 bit ins */ + ins <<= 16; + ins += *(uint16_t*)(addr + 2); + } + } + else + { + addr = regs->pc - 4; + ins = *(uint32_t*)addr; + } + if ((ins & 0xe00) == 0xa00) + { + /* float ins */ + uint32_t val = (1U << 30); + + asm volatile ("vmsr fpexc, %0"::"r"(val):"memory"); + regs->pc = addr; + return; + } + } +#endif rt_kprintf("undefined instruction:\n"); rt_hw_show_register(regs); #ifdef RT_USING_FINSH diff --git a/libcpu/arm/cortex-m0/cpuport.c b/libcpu/arm/cortex-m0/cpuport.c index 5d36fa11fe..19aec42230 100644 --- a/libcpu/arm/cortex-m0/cpuport.c +++ b/libcpu/arm/cortex-m0/cpuport.c @@ -119,7 +119,7 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *contex) #define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ #define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ #define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ -#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */ #define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ #define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index a386747750..d17d4fdf2e 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/libcpu/arm/cortex-m3/cpuport.c @@ -11,6 +11,7 @@ * 2012-12-23 aozima stack addr align to 8byte. * 2012-12-29 Bernard Add exception hook. * 2013-07-09 aozima enhancement hard fault exception handler. + * 2019-07-03 yangjie add __rt_ffs() for armclang. */ #include <rtthread.h> @@ -382,6 +383,24 @@ __asm int __rt_ffs(int value) exit BX lr } +#elif defined(__CLANG_ARM) +int __rt_ffs(int value) +{ + __asm volatile( + "CMP r0, #0x00 \n" + "BEQ exit \n" + + "RBIT r0, r0 \n" + "CLZ r0, r0 \n" + "ADDS r0, r0, #0x01 \n" + + "exit: \n" + + : "=r"(value) + : "r"(value) + ); + return value; +} #elif defined(__IAR_SYSTEMS_ICC__) int __rt_ffs(int value) { diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index 18f027895b..f556ba0c26 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -14,6 +14,7 @@ * 2012-12-29 Bernard Add exception hook. * 2013-06-23 aozima support lazy stack optimized. * 2018-07-24 aozima enhancement hard fault exception handler. + * 2019-07-03 yangjie add __rt_ffs() for armclang. */ #include <rtthread.h> @@ -453,7 +454,7 @@ RT_WEAK void rt_hw_cpu_reset(void) * @return return the index of the first bit set. If value is 0, then this function * shall return 0. */ -#if defined(__CC_ARM) || defined(__CLANG_ARM) +#if defined(__CC_ARM) __asm int __rt_ffs(int value) { CMP r0, #0x00 @@ -466,6 +467,24 @@ __asm int __rt_ffs(int value) exit BX lr } +#elif defined(__CLANG_ARM) +int __rt_ffs(int value) +{ + __asm volatile( + "CMP r0, #0x00 \n" + "BEQ exit \n" + + "RBIT r0, r0 \n" + "CLZ r0, r0 \n" + "ADDS r0, r0, #0x01 \n" + + "exit: \n" + + : "=r"(value) + : "r"(value) + ); + return value; +} #elif defined(__IAR_SYSTEMS_ICC__) int __rt_ffs(int value) { diff --git a/libcpu/arm/cortex-m7/cpu_cache.c b/libcpu/arm/cortex-m7/cpu_cache.c index 4a1a9c2201..350b819c00 100644 --- a/libcpu/arm/cortex-m7/cpu_cache.c +++ b/libcpu/arm/cortex-m7/cpu_cache.c @@ -72,15 +72,15 @@ void rt_hw_cpu_dcache_ops(int ops, void* addr, int size) if (ops & (RT_HW_CACHE_FLUSH | RT_HW_CACHE_INVALIDATE)) { - SCB_CleanInvalidateDCache_by_Addr((rt_uint32_t *)startAddr, size_byte); + SCB_CleanInvalidateDCache_by_Addr((uint32_t *)startAddr, size_byte); } else if (ops & RT_HW_CACHE_FLUSH) { - SCB_CleanDCache_by_Addr((rt_uint32_t *)startAddr, size_byte); + SCB_CleanDCache_by_Addr((uint32_t *)startAddr, size_byte); } else if (ops & RT_HW_CACHE_INVALIDATE) { - SCB_InvalidateDCache_by_Addr((rt_uint32_t *)startAddr, size_byte); + SCB_InvalidateDCache_by_Addr((uint32_t *)startAddr, size_byte); } else { diff --git a/libcpu/arm/cortex-m7/cpuport.c b/libcpu/arm/cortex-m7/cpuport.c index 18f027895b..c22242f140 100644 --- a/libcpu/arm/cortex-m7/cpuport.c +++ b/libcpu/arm/cortex-m7/cpuport.c @@ -14,6 +14,7 @@ * 2012-12-29 Bernard Add exception hook. * 2013-06-23 aozima support lazy stack optimized. * 2018-07-24 aozima enhancement hard fault exception handler. + * 2019-07-03 yangjie add __rt_ffs() for armclang. */ #include <rtthread.h> @@ -453,7 +454,7 @@ RT_WEAK void rt_hw_cpu_reset(void) * @return return the index of the first bit set. If value is 0, then this function * shall return 0. */ -#if defined(__CC_ARM) || defined(__CLANG_ARM) +#if defined(__CC_ARM) __asm int __rt_ffs(int value) { CMP r0, #0x00 @@ -466,6 +467,24 @@ __asm int __rt_ffs(int value) exit BX lr } +#elif defined(__CLANG_ARM) +int __rt_ffs(int value) +{ + __asm volatile( + "CMP r0, #0x00 \n" + "BEQ exit \n" + + "RBIT r0, r0 \n" + "CLZ r0, r0 \n" + "ADDS r0, r0, #0x01 \n" + + "exit: \n" + + : "=r"(value) + : "r"(value) + ); + return value; +} #elif defined(__IAR_SYSTEMS_ICC__) int __rt_ffs(int value) { diff --git a/libcpu/arm/cortex-r4/start_gcc.S b/libcpu/arm/cortex-r4/start_gcc.S index ab77b98781..a347503ec0 100644 --- a/libcpu/arm/cortex-r4/start_gcc.S +++ b/libcpu/arm/cortex-r4/start_gcc.S @@ -36,6 +36,7 @@ .globl stack_start .globl stack_top +.align 3 stack_start: .rept (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size) .byte 0 diff --git a/libcpu/arm/realview-a8-vmm/start_gcc.S b/libcpu/arm/realview-a8-vmm/start_gcc.S index 2ec7fe6c86..879cf992a8 100644 --- a/libcpu/arm/realview-a8-vmm/start_gcc.S +++ b/libcpu/arm/realview-a8-vmm/start_gcc.S @@ -47,6 +47,7 @@ .globl stack_start .globl stack_top +.align 3 stack_start: .rept ISR_Stack_Size .byte 0 diff --git a/libcpu/arm/zynq7000/start_gcc.S b/libcpu/arm/zynq7000/start_gcc.S index 6904c45587..18056f0ad9 100644 --- a/libcpu/arm/zynq7000/start_gcc.S +++ b/libcpu/arm/zynq7000/start_gcc.S @@ -33,6 +33,7 @@ .globl stack_start .globl stack_top +.align 3 .bss stack_start: .rept ISR_Stack_Size |
