diff options
| author | Bernard Xiong <[email protected]> | 2019-12-21 06:40:47 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-12-21 06:40:47 +0800 |
| commit | 0c11cd86717295bc4c41d7421e4119a62bbbfa11 (patch) | |
| tree | 594994078d07de40ba37c47d5d5c536a51bfe0fc /libcpu | |
| parent | 3491b2f0f470d3834763b9d78071ce7804597c94 (diff) | |
| parent | a383385a3c0a676cee4471fd3cb4f372a36e1023 (diff) | |
Merge pull request #3274 from armink/lts-v3.1.x
Lts v3.1.x
Diffstat (limited to 'libcpu')
37 files changed, 824 insertions, 734 deletions
diff --git a/libcpu/Kconfig b/libcpu/Kconfig index 22b4a6336a..ec0f139275 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -1,6 +1,10 @@ config ARCH_ARM bool +config RT_USING_CPU_FFS + bool + default n + config ARCH_ARM_CORTEX_M bool select ARCH_ARM @@ -15,6 +19,7 @@ config ARCH_ARM_CORTEX_M0 config ARCH_ARM_CORTEX_M3 bool select ARCH_ARM_CORTEX_M + select RT_USING_CPU_FFS config ARCH_ARM_MPU bool @@ -23,10 +28,12 @@ config ARCH_ARM_MPU config ARCH_ARM_CORTEX_M4 bool select ARCH_ARM_CORTEX_M + select RT_USING_CPU_FFS config ARCH_ARM_CORTEX_M7 bool select ARCH_ARM_CORTEX_M + select RT_USING_CPU_FFS config ARCH_ARM_CORTEX_R bool 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 diff --git a/libcpu/mips/common/cache.h b/libcpu/mips/common/cache.h deleted file mode 100644 index 1c7cf41324..0000000000 --- a/libcpu/mips/common/cache.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Cache operations for the cache instruction. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle - * (C) Copyright 1999 Silicon Graphics, Inc. - */ -#ifndef __CACHE_H__ -#define __CACHE_H__ - - -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 - -/* - * Cache Operations available on all MIPS processors with R4000-style caches - */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 -#define Index_Load_Tag_I 0x04 -#define Index_Load_Tag_D 0x05 -#define Index_Store_Tag_I 0x08 -#define Index_Store_Tag_D 0x09 - -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 -#define Hit_Writeback_Inv_D 0x15 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 - -/* - *The lock state is cleared by executing an Index -Invalidate, Index Writeback Invalidate, Hit -Invalidate, or Hit Writeback Invalidate -operation to the locked line, or via an Index -Store Tag operation with the lock bit reset in -the TagLo register. - */ -#define Fetch_And_Lock_I 0x1c -#define Fetch_And_Lock_D 0x1d -/* - * R4000-specific cacheops - */ -#define Create_Dirty_Excl_D 0x0d -#define Fill 0x14 - -/* - * R4000SC and R4400SC-specific cacheops - */ -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 -#define Index_Store_Tag_SI 0x0A -#define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_SI 0x12 -#define Hit_Invalidate_SD 0x13 -#define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_SD 0x1b -#define Hit_Set_Virtual_SI 0x1e -#define Hit_Set_Virtual_SD 0x1f - -/* - * R5000-specific cacheops - */ -#define R5K_Page_Invalidate_S 0x17 - -/* - * RM7000-specific cacheops - */ -#define Page_Invalidate_T 0x16 - -/* - * R1000-specific cacheops - * - * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. - * Most of the _S cacheops are identical to the R4000SC _SD cacheops. - */ -#define Index_Writeback_Inv_S 0x03 -#define Index_Load_Tag_S 0x07 -#define Index_Store_Tag_S 0x0B -#define Hit_Invalidate_S 0x13 -#define Cache_Barrier 0x14 -#define Hit_Writeback_Inv_S 0x17 -#define Index_Load_Data_I 0x18 -#define Index_Load_Data_D 0x19 -#define Index_Load_Data_S 0x1b -#define Index_Store_Data_I 0x1c -#define Index_Store_Data_D 0x1d -#define Index_Store_Data_S 0x1f - - -#ifndef __ASSEMBLER__ - -#ifndef dcache_size -#define dcache_size (g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size) -#endif - -#ifndef icache_size -#define icache_size (g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size) -#endif - -#ifndef cpu_dcache_line_size -#define cpu_dcache_line_size() g_mips_core.icache_line_size -#endif - -#ifndef cpu_icache_line_size -#define cpu_icache_line_size() g_mips_core.icache_line_size -#endif - -#define cache_op(op, addr) \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " .set mips3\n\t \n" \ - " cache %0, %1 \n" \ - " .set mips0 \n" \ - " .set reorder" \ - : \ - : "i" (op), "m" (*(unsigned char *)(addr))) - -#define cache16_unroll32(base, op) \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " .set mips3 \n" \ - " cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \ - " cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \ - " cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \ - " cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \ - " cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \ - " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \ - " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \ - " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \ - " cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \ - " cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \ - " cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \ - " cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \ - " cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \ - " cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \ - " cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \ - " cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \ - " .set mips0 \n" \ - " .set reorder \n" \ - : \ - : "r" (base), \ - "i" (op)); - - -static inline void flush_icache_line_indexed(rt_ubase_t addr) -{ - cache_op(Index_Invalidate_I, addr); -} - -static inline void flush_dcache_line_indexed(rt_ubase_t addr) -{ - cache_op(Index_Writeback_Inv_D, addr); -} - -static inline void flush_icache_line(rt_ubase_t addr) -{ - cache_op(Hit_Invalidate_I, addr); -} - -static inline void lock_icache_line(rt_ubase_t addr) -{ - cache_op(Fetch_And_Lock_I, addr); -} - -static inline void lock_dcache_line(rt_ubase_t addr) -{ - cache_op(Fetch_And_Lock_D, addr); -} - -static inline void flush_dcache_line(rt_ubase_t addr) -{ - cache_op(Hit_Writeback_Inv_D, addr); -} - -static inline void invalidate_dcache_line(rt_ubase_t addr) -{ - cache_op(Hit_Invalidate_D, addr); -} - -static inline void blast_dcache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + dcache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Index_Writeback_Inv_D); -} - -static inline void inv_dcache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + dcache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Hit_Invalidate_D); -} - -static inline void blast_icache16(void) -{ - rt_ubase_t start = KSEG0; - rt_ubase_t end = start + icache_size; - rt_ubase_t addr; - - for (addr = start; addr < end; addr += 0x200) - cache16_unroll32(addr, Index_Invalidate_I); -} - - - -void r4k_cache_init(void); -void r4k_cache_flush_all(void); -void r4k_icache_flush_all(void); -void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size); -void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size); -void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size); -void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size); - -#endif /*end of __ASSEMBLER__ */ - -#endif /* end of __CACHE_H__ */ diff --git a/libcpu/mips/common/mips.h b/libcpu/mips/common/mips.h index 6a9811ae7e..a4bc74a050 100644 --- a/libcpu/mips/common/mips.h +++ b/libcpu/mips/common/mips.h @@ -1,25 +1,11 @@ /* - * File : mips.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team + * Copyright (c) 2006-2019, RT-Thread Development Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes - * 2016��9��7�� Urey the first version + * 2016-09-07 Urey first version */ #ifndef _COMMON_MIPS_H_ diff --git a/libcpu/mips/common/mips_def.h b/libcpu/mips/common/mips_def.h index 70da2deccf..1727684f50 100644 --- a/libcpu/mips/common/mips_def.h +++ b/libcpu/mips/common/mips_def.h @@ -1,25 +1,11 @@ /* - * File : mips_def.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team + * Copyright (c) 2006-2019, RT-Thread Development Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes - * 2016��9��7�� Urey the first version + * 2016-09-07 Urey first version */ #ifndef _COMMON_MIPS_DEF_H_ diff --git a/libcpu/mips/loongson_1b/cache_gcc.S b/libcpu/mips/loongson_1b/cache_gcc.S index bb6f46de4c..1e718c9883 100644 --- a/libcpu/mips/loongson_1b/cache_gcc.S +++ b/libcpu/mips/loongson_1b/cache_gcc.S @@ -1,20 +1,22 @@ /* - * File : cache_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version * 2010-09-11 bernard port to Loongson SoC3210 * 2011-08-08 lgnq port to Loongson LS1B + * 2019-07-19 Zhou Yanjie clean up code */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + #include "../common/mipsregs.h" -#include "../common/mips.inc" +#include "../common/mips_def.h" #include "../common/asm.h" #include "cache.h" diff --git a/libcpu/mips/loongson_1b/context_gcc.S b/libcpu/mips/loongson_1b/context_gcc.S index ce004dc716..bed2c13252 100644 --- a/libcpu/mips/loongson_1b/context_gcc.S +++ b/libcpu/mips/loongson_1b/context_gcc.S @@ -1,20 +1,21 @@ /* - * File : context_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version * 2010-09-11 bernard port to Loongson SoC3210 * 2011-08-08 lgnq port to Loongson LS1B + * 2019-07-19 Zhou Yanjie clean up code */ -#include "../common/mips.inc" +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../common/mips_def.h" #include "../common/stackframe.h" .section ".text", "ax" diff --git a/libcpu/mips/loongson_1b/start_gcc.S b/libcpu/mips/loongson_1b/start_gcc.S index fd98335671..f54fbb9a1d 100644 --- a/libcpu/mips/loongson_1b/start_gcc.S +++ b/libcpu/mips/loongson_1b/start_gcc.S @@ -1,19 +1,20 @@ /* - * File : start_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version * 2010-09-04 bernard porting to Jz47xx + * 2019-07-19 Zhou Yanjie clean up code */ -#include "../common/mips.inc" +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../common/mips_def.h" #include "../common/stackframe.h" .section ".start", "ax" diff --git a/libcpu/mips/loongson_1c/cache_gcc.S b/libcpu/mips/loongson_1c/cache_gcc.S index af25c31ded..649a88b67b 100644 --- a/libcpu/mips/loongson_1c/cache_gcc.S +++ b/libcpu/mips/loongson_1c/cache_gcc.S @@ -1,11 +1,7 @@ /* - * File : cache_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes @@ -13,9 +9,15 @@ * 2010-09-11 bernard port to Loongson SoC3210 * 2011-08-08 lgnq port to Loongson LS1B * 2015-07-08 chinesebear port to Loongson LS1C + * 2019-07-19 Zhou Yanjie clean up code */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + #include "../common/mipsregs.h" -#include "../common/mips.inc" +#include "../common/mips_def.h" #include "../common/asm.h" #include "cache.h" diff --git a/libcpu/mips/loongson_1c/context_gcc.S b/libcpu/mips/loongson_1c/context_gcc.S index fbffd34866..53bce723e7 100644 --- a/libcpu/mips/loongson_1c/context_gcc.S +++ b/libcpu/mips/loongson_1c/context_gcc.S @@ -1,20 +1,21 @@ /* - * File : context_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version * 2010-09-11 bernard port to Loongson SoC3210 * 2011-08-08 lgnq port to Loongson LS1B + * 2019-07-19 Zhou Yanjie clean up code */ -#include "../common/mips.inc" +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../common/mips_def.h" #include "../common/stackframe.h" #include "stackframe_fpu.h" diff --git a/libcpu/mips/loongson_1c/ls1c.h b/libcpu/mips/loongson_1c/ls1c.h index a203810c37..963f774cf7 100644 --- a/libcpu/mips/loongson_1c/ls1c.h +++ b/libcpu/mips/loongson_1c/ls1c.h @@ -18,36 +18,36 @@ #include "../common/mipsregs.h" -#define LS1C_ACPI_IRQ 0 -#define LS1C_HPET_IRQ 1 -//#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 -#define LS1C_CAN1_IRQ 7 -#define LS1C_SPI0_IRQ 8 -#define LS1C_SPI1_IRQ 9 -#define LS1C_AC97_IRQ 10 -#define LS1C_MS_IRQ 11 -#define LS1C_KB_IRQ 12 -#define LS1C_DMA0_IRQ 13 -#define LS1C_DMA1_IRQ 14 -#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_ACPI_IRQ 0 +#define LS1C_HPET_IRQ 1 +//#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 +#define LS1C_CAN1_IRQ 7 +#define LS1C_SPI0_IRQ 8 +#define LS1C_SPI1_IRQ 9 +#define LS1C_AC97_IRQ 10 +#define LS1C_MS_IRQ 11 +#define LS1C_KB_IRQ 12 +#define LS1C_DMA0_IRQ 13 +#define LS1C_DMA1_IRQ 14 +#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_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_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) @@ -64,7 +64,7 @@ #define LS1C_I2C0_IRQ (32+19) -#define LS1C_GPIO_IRQ 64 +#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) @@ -84,72 +84,72 @@ struct ls1c_intc_regs { - volatile unsigned int int_isr; - volatile unsigned int int_en; - volatile unsigned int int_set; - volatile unsigned int int_clr; /* offset 0x10*/ - volatile unsigned int int_pol; - volatile unsigned int int_edge; /* offset 0 */ + volatile unsigned int int_isr; + volatile unsigned int int_en; + volatile unsigned int int_set; + volatile unsigned int int_clr; /* offset 0x10*/ + volatile unsigned int int_pol; + volatile unsigned int int_edge; /* offset 0 */ }; struct ls1c_cop_global_regs { - volatile unsigned int control; - volatile unsigned int rd_inten; - volatile unsigned int wr_inten; - volatile unsigned int rd_intisr; /* offset 0x10*/ - volatile unsigned int wr_intisr; - unsigned int unused[11]; + volatile unsigned int control; + volatile unsigned int rd_inten; + volatile unsigned int wr_inten; + volatile unsigned int rd_intisr; /* offset 0x10*/ + volatile unsigned int wr_intisr; + unsigned int unused[11]; } ; struct ls1c_cop_channel_regs { - volatile unsigned int rd_control; - volatile unsigned int rd_src; - volatile unsigned int rd_cnt; - volatile unsigned int rd_status; /* offset 0x10*/ - volatile unsigned int wr_control; - volatile unsigned int wr_src; - volatile unsigned int wr_cnt; - volatile unsigned int wr_status; /* offset 0x10*/ + volatile unsigned int rd_control; + volatile unsigned int rd_src; + volatile unsigned int rd_cnt; + volatile unsigned int rd_status; /* offset 0x10*/ + volatile unsigned int wr_control; + volatile unsigned int wr_src; + volatile unsigned int wr_cnt; + volatile unsigned int wr_status; /* offset 0x10*/ } ; struct ls1c_cop_regs { - struct ls1c_cop_global_regs global; - struct ls1c_cop_channel_regs chan[8][2]; + struct ls1c_cop_global_regs global; + struct ls1c_cop_channel_regs chan[8][2]; } ; -#define __REG8(addr) *((volatile unsigned char *)(addr)) -#define __REG16(addr) *((volatile unsigned short *)(addr)) -#define __REG32(addr) *((volatile unsigned int *)(addr)) +#define __REG8(addr) *((volatile unsigned char *)(addr)) +#define __REG16(addr) *((volatile unsigned short *)(addr)) +#define __REG32(addr) *((volatile unsigned int *)(addr)) -#define GMAC0_BASE 0xBFE10000 -#define GMAC0_DMA_BASE 0xBFE11000 -#define GMAC1_BASE 0xBFE20000 -#define GMAC1_DMA_BASE 0xBFE21000 -#define I2C0_BASE 0xBFE58000 -#define PWM0_BASE 0xBFE5C000 -#define PWM1_BASE 0xBFE5C010 -#define PWM2_BASE 0xBFE5C020 -#define PWM3_BASE 0xBFE5C030 -#define WDT_BASE 0xBFE5C060 -#define RTC_BASE 0xBFE64000 -#define I2C1_BASE 0xBFE68000 -#define I2C2_BASE 0xBFE70000 -#define AC97_BASE 0xBFE74000 -#define NAND_BASE 0xBFE78000 -#define SPI_BASE 0xBFE80000 -#define CAN1_BASE 0xBF004300 -#define CAN0_BASE 0xBF004400 +#define GMAC0_BASE 0xBFE10000 +#define GMAC0_DMA_BASE 0xBFE11000 +#define GMAC1_BASE 0xBFE20000 +#define GMAC1_DMA_BASE 0xBFE21000 +#define I2C0_BASE 0xBFE58000 +#define PWM0_BASE 0xBFE5C000 +#define PWM1_BASE 0xBFE5C010 +#define PWM2_BASE 0xBFE5C020 +#define PWM3_BASE 0xBFE5C030 +#define WDT_BASE 0xBFE5C060 +#define RTC_BASE 0xBFE64000 +#define I2C1_BASE 0xBFE68000 +#define I2C2_BASE 0xBFE70000 +#define AC97_BASE 0xBFE74000 +#define NAND_BASE 0xBFE78000 +#define SPI_BASE 0xBFE80000 +#define CAN1_BASE 0xBF004300 +#define CAN0_BASE 0xBF004400 /* Watch Dog registers */ -#define WDT_EN __REG32(WDT_BASE + 0x00) -#define WDT_SET __REG32(WDT_BASE + 0x04) -#define WDT_TIMER __REG32(WDT_BASE + 0x08) +#define WDT_EN __REG32(WDT_BASE + 0x00) +#define WDT_SET __REG32(WDT_BASE + 0x08) +#define WDT_TIMER __REG32(WDT_BASE + 0x04) -#define PLL_FREQ __REG32(0xbfe78030) -#define PLL_DIV_PARAM __REG32(0xbfe78034) +#define PLL_FREQ __REG32(0xbfe78030) +#define PLL_DIV_PARAM __REG32(0xbfe78034) #endif diff --git a/libcpu/mips/loongson_1c/start_gcc.S b/libcpu/mips/loongson_1c/start_gcc.S index 4e71bc0524..1d13ef7f0f 100644 --- a/libcpu/mips/loongson_1c/start_gcc.S +++ b/libcpu/mips/loongson_1c/start_gcc.S @@ -1,19 +1,20 @@ /* - * File : start_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team + * Copyright (c) 2006-2019, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2010-05-17 swkyer first version - * 2010-09-04 bernard porting to Jz47xx + * 2010-09-04 bernard porting to JZ47xx + * 2019-07-19 Zhou Yanjie clean up code */ -#include "../common/mips.inc" +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../common/mips_def.h" #include "../common/stackframe.h" #include "sdram_cfg.h" #include "cache.h" diff --git a/libcpu/mips/pic32/context_gcc.S b/libcpu/mips/pic32/context_gcc.S index 3e820fb9d8..bd46dffdc7 100644 --- a/libcpu/mips/pic32/context_gcc.S +++ b/libcpu/mips/pic32/context_gcc.S @@ -1,5 +1,20 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-05-24 aozima first version + * 2019-07-19 Zhou Yanjie clean up code + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + #include <p32xxxx.h> -#include "../common/mips.inc" +#include "../common/mips_def.h" #include "../common/stackframe.h" .section ".text", "ax" diff --git a/libcpu/ti-dsp/c28x/context.s b/libcpu/ti-dsp/c28x/context.s index 019b5def13..f21e0ddb6e 100644 --- a/libcpu/ti-dsp/c28x/context.s +++ b/libcpu/ti-dsp/c28x/context.s @@ -6,6 +6,8 @@ ; Change Logs: ; Date Author Notes ; 2018-09-01 xuzhuoyi the first version. +; 2019-06-17 zhaoxiaowei fix bugs of old c28x interrupt api. +; 2019-07-03 zhaoxiaowei add _rt_hw_calc_csb function to support __rt_ffs. ; .ref _rt_interrupt_to_thread @@ -15,6 +17,7 @@ .def _RTOSINT_Handler .def _rt_hw_get_st0 .def _rt_hw_get_st1 + .def _rt_hw_calc_csb .def _rt_hw_context_switch_interrupt .def _rt_hw_context_switch .def _rt_hw_context_switch_to @@ -73,7 +76,9 @@ RT_CTX_RESTORE .macro ; .asmfunc _rt_hw_interrupt_disable: - DINT + PUSH ST1 + SETC INTM,DBGM + MOV AL, *--SP LRETR .endasmfunc @@ -82,7 +87,8 @@ _rt_hw_interrupt_disable: ; .asmfunc _rt_hw_interrupt_enable: - EINT + MOV *SP++, AL + POP ST1 LRETR .endasmfunc @@ -94,11 +100,10 @@ _rt_hw_interrupt_enable: .asmfunc _rt_hw_context_switch_interrupt: -_rt_hw_context_switch: MOVL XAR0, #0 MOV AR0, AL MOVL XAR4, *-SP[4] - ; set rt_thread_switch_interrupt_flag to 1 + ; set rt_thread_switch_interrupt_flag to 1 MOVL XAR5, #_rt_thread_switch_interrupt_flag MOVL XAR6, *XAR5 MOVL ACC, XAR6 @@ -114,6 +119,36 @@ _reswitch: MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread MOVL *XAR5, XAR4 + LRETR + .endasmfunc + +; +; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; r0 --> from +; r4 --> to + + + .asmfunc +_rt_hw_context_switch: + MOVL XAR0, #0 + MOV AR0, AL + MOVL XAR4, *-SP[4] + ; set rt_thread_switch_interrupt_flag to 1 + MOVL XAR5, #_rt_thread_switch_interrupt_flag + MOVL XAR6, *XAR5 + MOVL ACC, XAR6 + CMPB AL, #1 + B _reswitch2, EQ + MOVL XAR6, #1 + MOVL *XAR5, XAR6 + + MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread + MOVL *XAR5, XAR0 + +_reswitch2: + MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread + MOVL *XAR5, XAR4 + TRAP #16 LRETR .endasmfunc @@ -139,8 +174,6 @@ _RTOSINT_Handler: MOV AR1, AL CMP AR1, #0 B switch_to_thread, EQ ; skip register save at the first time - - ;MOVZ AR1, @SP ; get from thread stack pointer ;#if defined (__VFP_FP__) && !defined(__SOFTFP__) ; TST lr, #0x10 ; if(!EXC_RETURN[4]) @@ -159,9 +192,9 @@ _RTOSINT_Handler: ;#endif MOV AL, *AR0 - MOV AR1, AL + MOV AR0, AL MOVZ AR1, @SP ; get from thread stack pointer - MOV *AR0, AR1 ; update from thread stack pointer + MOV *AR0, AR1 ; update from thread stack pointer switch_to_thread: MOV AR1, #_rt_interrupt_to_thread @@ -175,7 +208,7 @@ switch_to_thread: ;#endif MOV @SP, AR1 - INC SP + RT_CTX_RESTORE ; pop r4 - r11 register rtosint_exit: @@ -199,6 +232,25 @@ _rt_hw_get_st1: LRETR .endasmfunc +; C28x do not have a build-in "__ffs" func in its C compiler. +; We can use the "Count Sign Bits" (CSB) instruction to make one. +; CSB will return the number of 0's minus 1 above the highest set bit. +; The count is placed in T. For example: +; ACC T maxbit +; 0x00000001 30 0 +; 0x00000010 26 4 +; 0x000001FF 22 8 +; 0x000001F0 22 8 + .asmfunc +_rt_hw_calc_csb: + MOV AH, #0 + CSB ACC ; T = no. of sign bits - 1 + MOVU ACC, T ; ACC = no. of sign bits - 1 + SUBB ACC, #30 ; ACC = ACC - 30 + ABS ACC ; ACC = |ACC| + lretr + .endasmfunc + ; ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to diff --git a/libcpu/ti-dsp/c28x/cpuport.c b/libcpu/ti-dsp/c28x/cpuport.c index 8885f647a9..3f88606c65 100644 --- a/libcpu/ti-dsp/c28x/cpuport.c +++ b/libcpu/ti-dsp/c28x/cpuport.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018-09-01 xuzhuoyi the first version. + * 2019-07-03 zhaoxiaowei add support for __rt_ffs. */ #include <rtthread.h> @@ -17,6 +18,10 @@ rt_uint32_t rt_thread_switch_interrupt_flag; /* exception hook */ static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL; +extern rt_uint16_t rt_hw_get_st0(void); +extern rt_uint16_t rt_hw_get_st1(void); +extern int rt_hw_calc_csb(int value); + struct exception_stack_frame { rt_uint32_t t_st0; @@ -59,6 +64,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, stk = stack_addr; stk = (rt_uint8_t *)RT_ALIGN((rt_uint32_t)stk, 8); //stk -= sizeof(struct stack_frame); + stk += 1; stack_frame = (struct stack_frame *)stk; @@ -72,7 +78,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, stack_frame->exception_stack_frame.acc = 0x33332222; stack_frame->exception_stack_frame.ar1_ar0 = 0x00001111 & (unsigned long)parameter; /* ar0 : argument */ stack_frame->exception_stack_frame.p = 0x55554444; /* p */ - stack_frame->exception_stack_frame.dp_st1 = (0x00000000) | rt_hw_get_st1(); /* dp_st1 */ + stack_frame->exception_stack_frame.dp_st1 = (0x00000000) | rt_hw_get_st1() & 0xFFFFFFFE; /* dp_st1 */ stack_frame->exception_stack_frame.dbgstat_ier = 0; /* dbgstat_ier */ stack_frame->exception_stack_frame.return_address = (unsigned long)tentry; /* return_address */ stack_frame->rpc = (unsigned long)texit; @@ -98,6 +104,19 @@ struct exception_info struct stack_frame stack_frame; }; +#ifdef RT_USING_CPU_FFS +/* + * This function called rt_hw_calc_csb to finds the first bit set in value. + * rt_hw_calc_csb is a native assembly program that use "CSB" instruction in C28x. + * When you use this function, remember that "int" is only 16-bit in C28x's C compiler. + * If value is a number bigger that 0xFFFF, trouble may be caused. + * Maybe change "int __rt_ffs(int value)" to "rt_int32_t __rt_ffs(rt_int32_t value)" will be better. + */ +int __rt_ffs(int value) +{ + return rt_hw_calc_csb(value); +} +#endif /** * shutdown CPU |
