diff options
| author | cliff-cmc <[email protected]> | 2021-02-26 11:09:27 +0800 |
|---|---|---|
| committer | Cliff Chen <[email protected]> | 2021-02-26 11:45:19 +0800 |
| commit | eea0c3d74a40f73235da45c6f77e8b411ac94cf2 (patch) | |
| tree | a6906f1aed7118ab53dbe18f2ee4727a754583af /libcpu | |
| parent | 1a9ecf27f31277750d92c921b62503f75275e122 (diff) | |
| parent | fae0fa8eea4c0e797940bf1eddc8ee6c1711734a (diff) | |
Add memtrace command for memheap.c
Diffstat (limited to 'libcpu')
160 files changed, 6444 insertions, 480 deletions
diff --git a/libcpu/Kconfig b/libcpu/Kconfig index e355664de2..974c421138 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -82,6 +82,10 @@ config ARCH_MIPS config ARCH_MIPS64 bool + select ARCH_CPU_64BIT + +config ARCH_CPU_64BIT + bool config ARCH_MIPS_XBURST bool @@ -102,6 +106,14 @@ config ARCH_RISCV config ARCH_RISCV_FPU bool +config ARCH_RISCV_FPU_S + select ARCH_RISCV_FPU + bool + +config ARCH_RISCV_FPU_D + select ARCH_RISCV_FPU + bool + config ARCH_RISCV32 select ARCH_RISCV bool diff --git a/libcpu/aarch64/common/SConscript b/libcpu/aarch64/common/SConscript index 72fb8e26c3..c51148525b 100644 --- a/libcpu/aarch64/common/SConscript +++ b/libcpu/aarch64/common/SConscript @@ -8,7 +8,7 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') CPPPATH = [cwd] -group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) # build for sub-directory list = os.listdir(cwd) diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 962a53a071..84d3df2e8a 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -76,7 +76,7 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) /*@{*/ /** shutdown CPU */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/aarch64/cortex-a53/SConscript b/libcpu/aarch64/cortex-a53/SConscript index c6a4817802..0b74223c6f 100644 --- a/libcpu/aarch64/cortex-a53/SConscript +++ b/libcpu/aarch64/cortex-a53/SConscript @@ -8,6 +8,6 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') CPPPATH = [cwd] -group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/aarch64/cortex-a72/SConscript b/libcpu/aarch64/cortex-a72/SConscript index c6a4817802..0b74223c6f 100644 --- a/libcpu/aarch64/cortex-a72/SConscript +++ b/libcpu/aarch64/cortex-a72/SConscript @@ -8,6 +8,6 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') CPPPATH = [cwd] -group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arc/common/SConscript b/libcpu/arc/common/SConscript index 1c77347e61..80c21d87eb 100644 --- a/libcpu/arc/common/SConscript +++ b/libcpu/arc/common/SConscript @@ -5,6 +5,6 @@ src = Glob('*.c') CPPPATH = [cwd] -group = DefineGroup('cpu', src, depend = [], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arc/em/SConscript b/libcpu/arc/em/SConscript index ff1d8c134d..a52aa9b1e4 100644 --- a/libcpu/arc/em/SConscript +++ b/libcpu/arc/em/SConscript @@ -10,6 +10,6 @@ CPPPATH = [cwd] src += Glob('*.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arc/em/cpuport.c b/libcpu/arc/em/cpuport.c index 34f538881f..1a2593644a 100644 --- a/libcpu/arc/em/cpuport.c +++ b/libcpu/arc/em/cpuport.c @@ -32,7 +32,7 @@ struct init_stack_frame { /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { } diff --git a/libcpu/arm/AT91SAM7S/SConscript b/libcpu/arm/AT91SAM7S/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/AT91SAM7S/SConscript +++ b/libcpu/arm/AT91SAM7S/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/AT91SAM7S/cpu.c b/libcpu/arm/AT91SAM7S/cpu.c index 8d28063eb1..b24ab5644b 100644 --- a/libcpu/arm/AT91SAM7S/cpu.c +++ b/libcpu/arm/AT91SAM7S/cpu.c @@ -20,7 +20,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -28,7 +28,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/AT91SAM7X/SConscript b/libcpu/arm/AT91SAM7X/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/AT91SAM7X/SConscript +++ b/libcpu/arm/AT91SAM7X/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/AT91SAM7X/cpu.c b/libcpu/arm/AT91SAM7X/cpu.c index 484c19d10a..046f7e8ced 100644 --- a/libcpu/arm/AT91SAM7X/cpu.c +++ b/libcpu/arm/AT91SAM7X/cpu.c @@ -20,7 +20,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -28,7 +28,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/am335x/SConscript b/libcpu/arm/am335x/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/am335x/SConscript +++ b/libcpu/arm/am335x/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/am335x/cpu.c b/libcpu/arm/am335x/cpu.c index cae865fe50..469276466b 100644 --- a/libcpu/arm/am335x/cpu.c +++ b/libcpu/arm/am335x/cpu.c @@ -149,7 +149,7 @@ rt_base_t rt_hw_cpu_dcache_status() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/arm926/SConscript b/libcpu/arm/arm926/SConscript index 00785a135b..2275af97d9 100644 --- a/libcpu/arm/arm926/SConscript +++ b/libcpu/arm/arm926/SConscript @@ -20,6 +20,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c index 035e97d543..dc93f42ed6 100644 --- a/libcpu/arm/arm926/cpuport.c +++ b/libcpu/arm/arm926/cpuport.c @@ -146,7 +146,7 @@ rt_base_t rt_hw_cpu_dcache_status() * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { rt_kprintf("Restarting system...\n"); @@ -161,7 +161,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S index 35c1f1722e..658dcf8656 100644 --- a/libcpu/arm/arm926/start_gcc.S +++ b/libcpu/arm/arm926/start_gcc.S @@ -121,31 +121,7 @@ reset: /* 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} - /* turn off the watchdog */ - ldr r0, =0x01C20CB8 - mov r1, #0x0 - str r1, [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 diff --git a/libcpu/arm/armv6/SConscript b/libcpu/arm/armv6/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/armv6/SConscript +++ b/libcpu/arm/armv6/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/armv6/cpuport.c b/libcpu/arm/armv6/cpuport.c index c8e9201722..f886e7e164 100644 --- a/libcpu/arm/armv6/cpuport.c +++ b/libcpu/arm/armv6/cpuport.c @@ -147,7 +147,7 @@ rt_base_t rt_hw_cpu_dcache_status() * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { rt_kprintf("Restarting system...\n"); @@ -162,7 +162,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/common/SConscript b/libcpu/arm/common/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/common/SConscript +++ b/libcpu/arm/common/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-a/SConscript b/libcpu/arm/cortex-a/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-a/SConscript +++ b/libcpu/arm/cortex-a/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c index 7c6bf58a4b..6775b781bc 100644 --- a/libcpu/arm/cortex-a/cpu.c +++ b/libcpu/arm/cortex-a/cpu.c @@ -74,7 +74,7 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) /*@{*/ /** shutdown CPU */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/cortex-a/gic.c b/libcpu/arm/cortex-a/gic.c index 2a46142b54..2e94b88277 100644 --- a/libcpu/arm/cortex-a/gic.c +++ b/libcpu/arm/cortex-a/gic.c @@ -74,9 +74,8 @@ void arm_gic_ack(rt_uint32_t index, int irq) irq = irq - _gic_table[index].offset; RT_ASSERT(irq >= 0); - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; } void arm_gic_mask(rt_uint32_t index, int irq) diff --git a/libcpu/arm/cortex-m0/SConscript b/libcpu/arm/cortex-m0/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m0/SConscript +++ b/libcpu/arm/cortex-m0/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m23/SConscript b/libcpu/arm/cortex-m23/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m23/SConscript +++ b/libcpu/arm/cortex-m23/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S index 067348181d..48f90413d9 100644 --- a/libcpu/arm/cortex-m23/context_gcc.S +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -137,7 +137,7 @@ pendsv_exit: /* restore interrupt */ MSR PRIMASK, R2 - MOVS R0, #0x04 + MOVS R0, #0x03 RSBS R0, R0, #0x00 BX R0 /* diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S index 4d50d0fdec..c7d85cc5e2 100644 --- a/libcpu/arm/cortex-m23/context_iar.S +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -139,7 +139,7 @@ pendsv_exit ; restore interrupt MSR PRIMASK, r2 - MOVS r0, #0x04 + MOVS r0, #0x03 RSBS r0, r0, #0x00 BX r0 diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S index 4486ceaf08..ca381d0f8f 100644 --- a/libcpu/arm/cortex-m23/context_rvds.S +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -143,7 +143,7 @@ pendsv_exit ; restore interrupt MSR PRIMASK, r2 - MOVS r0, #0x04 + MOVS r0, #0x03 RSBS r0, r0, #0x00 BX r0 ENDP diff --git a/libcpu/arm/cortex-m3/SConscript b/libcpu/arm/cortex-m3/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m3/SConscript +++ b/libcpu/arm/cortex-m3/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index d17d4fdf2e..b6c4c9743c 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/libcpu/arm/cortex-m3/cpuport.c @@ -344,7 +344,7 @@ void rt_hw_hard_fault_exception(struct exception_info * exception_info) /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); @@ -388,13 +388,13 @@ int __rt_ffs(int value) { __asm volatile( "CMP r0, #0x00 \n" - "BEQ exit \n" + "BEQ 1f \n" "RBIT r0, r0 \n" "CLZ r0, r0 \n" "ADDS r0, r0, #0x01 \n" - "exit: \n" + "1: \n" : "=r"(value) : "r"(value) diff --git a/libcpu/arm/cortex-m33/SConscript b/libcpu/arm/cortex-m33/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m33/SConscript +++ b/libcpu/arm/cortex-m33/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m33/cpuport.c b/libcpu/arm/cortex-m33/cpuport.c index 415f560911..42b5798507 100644 --- a/libcpu/arm/cortex-m33/cpuport.c +++ b/libcpu/arm/cortex-m33/cpuport.c @@ -431,7 +431,7 @@ void rt_hw_hard_fault_exception(struct exception_info *exception_info) /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); @@ -475,13 +475,13 @@ int __rt_ffs(int value) { __asm volatile( "CMP r0, #0x00 \n" - "BEQ exit \n" + "BEQ 1f \n" "RBIT r0, r0 \n" "CLZ r0, r0 \n" "ADDS r0, r0, #0x01 \n" - "exit: \n" + "1: \n" "BX lr \n" : "=r"(value) diff --git a/libcpu/arm/cortex-m33/trustzone.c b/libcpu/arm/cortex-m33/trustzone.c index 86654a7199..5f37ddbb8f 100644 --- a/libcpu/arm/cortex-m33/trustzone.c +++ b/libcpu/arm/cortex-m33/trustzone.c @@ -10,11 +10,19 @@ #include <rtthread.h> +#ifdef ARM_CM33_ENABLE_TRUSTZONE extern void TZ_InitContextSystem_S(void); extern rt_uint32_t TZ_AllocModuleContext_S (rt_uint32_t module); extern rt_uint32_t TZ_FreeModuleContext_S(rt_uint32_t id); extern rt_uint32_t TZ_LoadContext_S(rt_uint32_t id); extern rt_uint32_t TZ_StoreContext_S(rt_uint32_t id); +#else +void TZ_InitContextSystem_S(void){} +rt_uint32_t TZ_AllocModuleContext_S (rt_uint32_t module){return 0;} +rt_uint32_t TZ_FreeModuleContext_S(rt_uint32_t id) {return 0;} +rt_uint32_t TZ_LoadContext_S(rt_uint32_t id){return 0;}; +rt_uint32_t TZ_StoreContext_S(rt_uint32_t id){return 0;}; +#endif extern int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2); #define TZ_INIT_CONTEXT_ID (0x1001) diff --git a/libcpu/arm/cortex-m4/SConscript b/libcpu/arm/cortex-m4/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m4/SConscript +++ b/libcpu/arm/cortex-m4/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index f556ba0c26..2e47832259 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -428,7 +428,7 @@ void rt_hw_hard_fault_exception(struct exception_info *exception_info) /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); @@ -472,13 +472,13 @@ int __rt_ffs(int value) { __asm volatile( "CMP r0, #0x00 \n" - "BEQ exit \n" + "BEQ 1f \n" "RBIT r0, r0 \n" "CLZ r0, r0 \n" "ADDS r0, r0, #0x01 \n" - "exit: \n" + "1: \n" : "=r"(value) : "r"(value) diff --git a/libcpu/arm/cortex-m7/SConscript b/libcpu/arm/cortex-m7/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-m7/SConscript +++ b/libcpu/arm/cortex-m7/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-m7/cpuport.c b/libcpu/arm/cortex-m7/cpuport.c index c22242f140..aeb9f14ac5 100644 --- a/libcpu/arm/cortex-m7/cpuport.c +++ b/libcpu/arm/cortex-m7/cpuport.c @@ -428,7 +428,7 @@ void rt_hw_hard_fault_exception(struct exception_info *exception_info) /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); @@ -472,13 +472,13 @@ int __rt_ffs(int value) { __asm volatile( "CMP r0, #0x00 \n" - "BEQ exit \n" + "BEQ 1f \n" "RBIT r0, r0 \n" "CLZ r0, r0 \n" "ADDS r0, r0, #0x01 \n" - "exit: \n" + "1: \n" : "=r"(value) : "r"(value) diff --git a/libcpu/arm/cortex-r4/SConscript b/libcpu/arm/cortex-r4/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/cortex-r4/SConscript +++ b/libcpu/arm/cortex-r4/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/cortex-r4/cpu.c b/libcpu/arm/cortex-r4/cpu.c index d2e8130e7c..23c16e383c 100644 --- a/libcpu/arm/cortex-r4/cpu.c +++ b/libcpu/arm/cortex-r4/cpu.c @@ -20,7 +20,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -28,7 +28,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/dm36x/SConscript b/libcpu/arm/dm36x/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/dm36x/SConscript +++ b/libcpu/arm/dm36x/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/dm36x/cpuport.c b/libcpu/arm/dm36x/cpuport.c index f6e8a20056..99edb96260 100644 --- a/libcpu/arm/dm36x/cpuport.c +++ b/libcpu/arm/dm36x/cpuport.c @@ -145,7 +145,7 @@ rt_base_t rt_hw_cpu_dcache_status() * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { rt_kprintf("Restarting system...\n"); @@ -160,7 +160,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/lpc214x/SConscript b/libcpu/arm/lpc214x/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/lpc214x/SConscript +++ b/libcpu/arm/lpc214x/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/lpc214x/cpuport.c b/libcpu/arm/lpc214x/cpuport.c index 2543a5e0a9..54e7e9b0c8 100644 --- a/libcpu/arm/lpc214x/cpuport.c +++ b/libcpu/arm/lpc214x/cpuport.c @@ -163,7 +163,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, * this function will reset CPU * */ -void rt_hw_cpu_reset(void) +RT_WEAK void rt_hw_cpu_reset(void) { } @@ -171,7 +171,7 @@ void rt_hw_cpu_reset(void) * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/lpc24xx/SConscript b/libcpu/arm/lpc24xx/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/lpc24xx/SConscript +++ b/libcpu/arm/lpc24xx/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/lpc24xx/cpu.c b/libcpu/arm/lpc24xx/cpu.c index f3a61e16a3..0453722d1d 100644 --- a/libcpu/arm/lpc24xx/cpu.c +++ b/libcpu/arm/lpc24xx/cpu.c @@ -20,7 +20,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -28,7 +28,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/realview-a8-vmm/SConscript b/libcpu/arm/realview-a8-vmm/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/realview-a8-vmm/SConscript +++ b/libcpu/arm/realview-a8-vmm/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/realview-a8-vmm/cpu.c b/libcpu/arm/realview-a8-vmm/cpu.c index 2d78715011..dbdb4ac515 100644 --- a/libcpu/arm/realview-a8-vmm/cpu.c +++ b/libcpu/arm/realview-a8-vmm/cpu.c @@ -18,7 +18,7 @@ /*@{*/ /** shutdown CPU */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/realview-a8-vmm/interrupt.c b/libcpu/arm/realview-a8-vmm/interrupt.c index 5ef0bdc460..5fffb4ba36 100644 --- a/libcpu/arm/realview-a8-vmm/interrupt.c +++ b/libcpu/arm/realview-a8-vmm/interrupt.c @@ -26,9 +26,9 @@ extern volatile rt_uint8_t rt_interrupt_nest; struct rt_irq_desc isr_table[MAX_HANDLERS]; /* Those varibles will be accessed in ISR, so we need to share them. */ -rt_uint32_t rt_interrupt_from_thread SECTION(".bss.share.int"); -rt_uint32_t rt_interrupt_to_thread SECTION(".bss.share.int"); -rt_uint32_t rt_thread_switch_interrupt_flag SECTION(".bss.share.int"); +rt_uint32_t rt_interrupt_from_thread RT_SECTION(".bss.share.int"); +rt_uint32_t rt_interrupt_to_thread RT_SECTION(".bss.share.int"); +rt_uint32_t rt_thread_switch_interrupt_flag RT_SECTION(".bss.share.int"); const unsigned int VECTOR_BASE = 0x00; extern void rt_cpu_vector_set_base(unsigned int addr); diff --git a/libcpu/arm/s3c24x0/SConscript b/libcpu/arm/s3c24x0/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/s3c24x0/SConscript +++ b/libcpu/arm/s3c24x0/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/s3c24x0/cpu.c b/libcpu/arm/s3c24x0/cpu.c index 4d3bf3c1ab..2adf526a5c 100644 --- a/libcpu/arm/s3c24x0/cpu.c +++ b/libcpu/arm/s3c24x0/cpu.c @@ -148,7 +148,7 @@ rt_base_t rt_hw_cpu_dcache_status() * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { /* Disable all interrupt except the WDT */ INTMSK = (~((rt_uint32_t)1 << INTWDT)); @@ -171,7 +171,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/s3c24x0/rtc.c b/libcpu/arm/s3c24x0/rtc.c index d0c80bce6b..73de840b37 100644 --- a/libcpu/arm/s3c24x0/rtc.c +++ b/libcpu/arm/s3c24x0/rtc.c @@ -12,7 +12,7 @@ */ #include <rtthread.h> -#include <time.h> +#include <sys/time.h> #include <s3c24x0.h> // #define RTC_DEBUG @@ -125,27 +125,27 @@ static rt_size_t rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t static rt_err_t rtc_control(rt_device_t dev, int cmd, void *args) { - struct tm tm, *tm_ptr; + struct tm tm, *tm_ptr; time_t *time; - RT_ASSERT(dev != RT_NULL); + RT_ASSERT(dev != RT_NULL); - time = (time_t *)args; - switch (cmd) - { - case RT_DEVICE_CTRL_RTC_GET_TIME: - /* read device */ - rt_hw_rtc_get(&tm); - *((rt_time_t *)args) = mktime(&tm); - break; + time = (time_t *)args; + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + /* read device */ + rt_hw_rtc_get(&tm); + *((rt_time_t *)args) = timegm(&tm); + break; - case RT_DEVICE_CTRL_RTC_SET_TIME: - tm_ptr = localtime(time); - /* write device */ - rt_hw_rtc_set(tm_ptr); - break; - } + case RT_DEVICE_CTRL_RTC_SET_TIME: + /* write device */ + tm_ptr = gmtime(time); + rt_hw_rtc_set(tm_ptr); + break; + } - return RT_EOK; + return RT_EOK; } void rt_hw_rtc_init(void) diff --git a/libcpu/arm/s3c44b0/SConscript b/libcpu/arm/s3c44b0/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/s3c44b0/SConscript +++ b/libcpu/arm/s3c44b0/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/s3c44b0/cpu.c b/libcpu/arm/s3c44b0/cpu.c index 03ebefba18..9d60b09688 100644 --- a/libcpu/arm/s3c44b0/cpu.c +++ b/libcpu/arm/s3c44b0/cpu.c @@ -100,7 +100,7 @@ rt_base_t rt_hw_cpu_dcache_status() * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -108,7 +108,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/sep4020/SConscript b/libcpu/arm/sep4020/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/sep4020/SConscript +++ b/libcpu/arm/sep4020/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/sep4020/cpu.c b/libcpu/arm/sep4020/cpu.c index ee4eab626b..92ba2cf86a 100644 --- a/libcpu/arm/sep4020/cpu.c +++ b/libcpu/arm/sep4020/cpu.c @@ -152,7 +152,7 @@ rt_base_t rt_hw_cpu_dcache_status() * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { /* enable watchdog */ @@ -173,7 +173,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t UNUSED level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/zynq7000/SConscript b/libcpu/arm/zynq7000/SConscript index 9ff30a796b..28af7ba651 100644 --- a/libcpu/arm/zynq7000/SConscript +++ b/libcpu/arm/zynq7000/SConscript @@ -18,6 +18,6 @@ if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'iar': src += Glob('*_iar.S') -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/libcpu/arm/zynq7000/cpu.c b/libcpu/arm/zynq7000/cpu.c index 5f3a3e7b02..f6b7f5d852 100644 --- a/libcpu/arm/zynq7000/cpu.c +++ b/libcpu/arm/zynq7000/cpu.c @@ -16,7 +16,7 @@ * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { while (1); /* loop forever and wait for reset to happen */ @@ -27,7 +27,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/arm/zynq7000/gic.c b/libcpu/arm/zynq7000/gic.c index e23a359e6e..76404d4c46 100644 --- a/libcpu/arm/zynq7000/gic.c +++ b/libcpu/arm/zynq7000/gic.c @@ -37,7 +37,7 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; #define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + (n/32) * 4) #define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + (n/32) * 4) #define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + (n/32) * 4) #define GIC_DIST_ACTIVE_BIT(hw_base) __REG32((hw_base) + 0x300) #define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + (n/4) * 4) #define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + (n/4) * 4) @@ -68,9 +68,8 @@ void arm_gic_ack(rt_uint32_t index, int irq) irq = irq - _gic_table[index].offset; RT_ASSERT(irq >= 0); - GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; } void arm_gic_mask(rt_uint32_t index, int irq) diff --git a/libcpu/arm/zynq7000/mmu.c b/libcpu/arm/zynq7000/mmu.c index fbdacca10f..8674f9f60f 100644 --- a/libcpu/arm/zynq7000/mmu.c +++ b/libcpu/arm/zynq7000/mmu.c @@ -109,7 +109,7 @@ void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) /* level1 page table, each entry for 1MB memory. */ /* MMUTable is the name used by codes of Xilinx */ -volatile unsigned long MMUTable[4*1024] SECTION("mmu_tbl") __attribute__((aligned(16*1024))); +volatile unsigned long MMUTable[4*1024] RT_SECTION("mmu_tbl") __attribute__((aligned(16*1024))); void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, diff --git a/libcpu/arm/zynqmp-r5/SConscript b/libcpu/arm/zynqmp-r5/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/arm/zynqmp-r5/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/zynqmp-r5/armv7.h b/libcpu/arm/zynqmp-r5/armv7.h new file mode 100644 index 0000000000..4c34d7da8b --- /dev/null +++ b/libcpu/arm/zynqmp-r5/armv7.h @@ -0,0 +1,67 @@ +#ifndef __ARMV7_H__ +#define __ARMV7_H__ +/* + * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd + * + * All rights reserved. + * + * 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. + */ + +#ifndef VFP_DATA_NR +#define VFP_DATA_NR 32 +#endif + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + +#endif diff --git a/libcpu/arm/zynqmp-r5/cache.c b/libcpu/arm/zynqmp-r5/cache.c new file mode 100644 index 0000000000..aa8517e254 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/cache.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ +#include <rthw.h> +#include <rtdef.h> + +#include "xpseudo_asm_gcc.h" +#include "xreg_cortexr5.h" + +#define IRQ_FIQ_MASK 0xC0 /* Mask IRQ and FIQ interrupts in cpsr */ + +typedef intptr_t INTPTR; +typedef rt_uint32_t u32; + +#if defined (__GNUC__) +#define asm_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)) + +#define asm_clean_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)) + +#define asm_clean_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)) + +#define asm_inval_ic_line_mva_pou(param) __asm__ __volatile__("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)) +#elif defined (__ICCARM__) +#define asm_inval_dc_line_mva_poc(param) __asm volatile("mcr " \ + XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param)) + +#define asm_clean_inval_dc_line_sw(param) __asm volatile("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param)) + +#define asm_clean_inval_dc_line_mva_poc(param) __asm volatile("mcr " \ + XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param)) + +#define asm_inval_ic_line_mva_pou(param) __asm volatile("mcr " \ + XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param)) +#endif + + +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 I-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + + while (LocalAddr < end) { + + /* Invalidate L1 I-cache line */ + asm_inval_ic_line_mva_pou(LocalAddr); + + LocalAddr += cacheline; + } + } + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +void Xil_DCacheFlushLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); +} + +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len) +{ + const u32 cacheline = 32U; + u32 end; + u32 tempadr = adr; + u32 tempend; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + end = tempadr + len; + tempend = end; + /* Select L1 Data cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + + if ((tempadr & (cacheline-1U)) != 0U) { + tempadr &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempadr); + } + if ((tempend & (cacheline-1U)) != 0U) { + tempend &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempend); + } + + while (tempadr < tempend) { + + /* Invalidate Data cache line */ + asm_inval_dc_line_mva_poc(tempadr); + + tempadr += cacheline; + } + } + + dsb(); + mtcpsr(currmask); +} + +void Xil_DCacheFlushRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr &= ~(cacheline - 1U); + + while (LocalAddr < end) { + /* Flush Data cache line */ + asm_clean_inval_dc_line_mva_poc(LocalAddr); + + LocalAddr += cacheline; + } + } + dsb(); + mtcpsr(currmask); +} + +void rt_hw_cpu_icache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_INVALIDATE) + Xil_ICacheInvalidateRange((INTPTR)addr, size); +} + +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) + Xil_DCacheFlushRange((intptr_t)addr, size); + else if (ops == RT_HW_CACHE_INVALIDATE) + Xil_DCacheInvalidateRange((intptr_t)addr, size); +} + +rt_base_t rt_hw_cpu_icache_status(void) +{ + register u32 CtrlReg; +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + return CtrlReg & XREG_CP15_CONTROL_I_BIT; +} + +rt_base_t rt_hw_cpu_dcache_status(void) +{ + register u32 CtrlReg; +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + return CtrlReg & XREG_CP15_CONTROL_C_BIT; +} diff --git a/libcpu/arm/zynqmp-r5/context_gcc.S b/libcpu/arm/zynqmp-r5/context_gcc.S new file mode 100644 index 0000000000..0d660017da --- /dev/null +++ b/libcpu/arm/zynqmp-r5/context_gcc.S @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +.section .text, "ax" +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid if + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr, r0 + bx lr + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + ldmfd sp!, {r1} /* Restore floating point registers */ + vmsr FPEXC, r1 + ldmfd sp!, {r1} + vmsr FPSCR, r1 + vldmia sp!, {d0-d15} +#endif + + ldmfd sp!, {r4} @ pop new task spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc + + +.section .text.isr, "ax" +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + beq _ARM_MODE + orr r4, r4, #0x20 @ it's thumb code + +_ARM_MODE: + stmfd sp!, {r4} @ push cpsr + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + vstmdb sp!, {d0-d15} /* Store floating point registers */ + vmrs r4, FPSCR + stmfd sp!,{r4} + vmrs r4, FPEXC + stmfd sp!,{r4} +#endif + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + ldmfd sp!, {r1} /* Restore floating point registers */ + vmsr FPEXC, r1 + ldmfd sp!, {r1} + vmsr FPSCR, r1 + vldmia sp!, {d0-d15} +#endif + + ldmfd sp!, {r4} @ pop new task cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r3, [r2] + ldr r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + str r0, [r2] +_reswitch: + ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [r2] + bx lr diff --git a/libcpu/arm/zynqmp-r5/cpu.c b/libcpu/arm/zynqmp-r5/cpu.c new file mode 100644 index 0000000000..a2e3b85dc7 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/cpu.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +#include <rthw.h> +#include <rtthread.h> +#include "zynqmp-r5.h" + +void rt_hw_cpu_reset() +{ + __REG32(ZynqMP_CRL_APB_BASEADDR + ZynqMP_CRL_APB_RESET_CTRL) |= ZynqMP_RESET_MASK; + while (1); /* loop forever and wait for reset to happen */ + /* NEVER REACHED */ +} + +/** + * shutdown CPU + * + */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} diff --git a/libcpu/arm/zynqmp-r5/gic.c b/libcpu/arm/zynqmp-r5/gic.c new file mode 100644 index 0000000000..3acefbc9bf --- /dev/null +++ b/libcpu/arm/zynqmp-r5/gic.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +#include <rtthread.h> +#include "board.h" +#include "gic.h" + +/* ZynqMP-RPU uses the Arm PL-390 generic interrupt controller that is + * compliant to the GICv1 architecture specification. */ + +struct arm_gic +{ + rt_uint32_t offset; + + rt_uint32_t dist_hw_base; + rt_uint32_t cpu_hw_base; +}; + +static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; + +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18) + +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8) + +static unsigned int _gic_max_irq; + +int arm_gic_get_active_irq(rt_uint32_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base); + irq += _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_mask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) +{ + rt_uint32_t old_tgt; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); + + old_tgt &= ~(0x0FFUL << ((irq % 4)*8)); + old_tgt |= cpumask << ((irq % 4)*8); + + GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; +} + +void arm_gic_umask(rt_uint32_t index, int irq) +{ + rt_uint32_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_dump_type(rt_uint32_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1 << 10) ? "has" : "no", + gic_type); +} + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) +{ + unsigned int gic_type, i; + rt_uint32_t cpumask = 1 << 0; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020) + _gic_max_irq = 1020; + if (_gic_max_irq > ARM_GIC_NR_IRQS) + _gic_max_irq = ARM_GIC_NR_IRQS; + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + + GIC_DIST_CTRL(dist_base) = 0x0; + + /* Set all global interrupts to be level triggered, active low. */ + for (i = 32; i < _gic_max_irq; i += 16) + GIC_DIST_CONFIG(dist_base, i) = 0x0; + + /* Set all global interrupts to this CPU only. */ + for (i = 32; i < _gic_max_irq; i += 4) + GIC_DIST_TARGET(dist_base, i) = cpumask; + + /* Set priority on all interrupts. */ + for (i = 0; i < _gic_max_irq; i += 4) + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; + + /* Disable all interrupts. */ + for (i = 0; i < _gic_max_irq; i += 32) + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; + + /* Enable interrupt. */ + GIC_DIST_CTRL(dist_base) = 0x01; + + return 0; +} + +int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].cpu_hw_base = cpu_base; + + GIC_CPU_PRIMASK(cpu_base) = 0xf0; + /* Enable CPU interrupt */ + GIC_CPU_CTRL(cpu_base) = 0x01; + + return 0; +} + +void arm_gic_trigger(rt_uint32_t index, int target_cpu, int irq) +{ + unsigned int reg; + + RT_ASSERT(irq <= 15); + RT_ASSERT(target_cpu <= 255); + + reg = (target_cpu << 16) | irq; + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = reg; +} + +void arm_gic_clear_sgi(rt_uint32_t index, int target_cpu, int irq) +{ + /* SGI will be cleared automatically. */ +}
\ No newline at end of file diff --git a/libcpu/arm/zynqmp-r5/gic.h b/libcpu/arm/zynqmp-r5/gic.h new file mode 100644 index 0000000000..7cffec3f88 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/gic.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +#ifndef __GIC_H__ +#define __GIC_H__ + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base); + +void arm_gic_mask(rt_uint32_t index, int irq); +void arm_gic_umask(rt_uint32_t index, int irq); +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); + +int arm_gic_get_active_irq(rt_uint32_t index); +void arm_gic_ack(rt_uint32_t index, int irq); + +void arm_gic_trigger(rt_uint32_t index, int target_cpu, int irq); +void arm_gic_clear_sgi(rt_uint32_t index, int target_cpu, int irq); + +void arm_gic_dump_type(rt_uint32_t index); + +#endif + diff --git a/libcpu/arm/zynqmp-r5/interrupt.c b/libcpu/arm/zynqmp-r5/interrupt.c new file mode 100644 index 0000000000..12ba638345 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/interrupt.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +#include <rthw.h> +#include <rtthread.h> +#include "zynqmp-r5.h" +#include "interrupt.h" +#include "gic.h" + +#define MAX_HANDLERS IRQ_ZynqMP_MAXNR + +extern volatile rt_uint8_t rt_interrupt_nest; + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + + +void rt_hw_interrupt_handle(int vector, void *param) +{ + rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector); +} + +void rt_hw_interrupt_init(void) +{ + register rt_uint32_t idx; + + /* the initialization is done in fsbl */ + + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + for (idx = 0; idx < MAX_HANDLERS; idx++) + { + isr_table[idx].handler = rt_hw_interrupt_handle; + } + + /* initialize ARM GIC */ + arm_gic_dist_init(0, ZynqMP_GIC_DIST_BASE, 0); + arm_gic_cpu_init(0, ZynqMP_GIC_CPU_BASE); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + arm_gic_mask(0, vector); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + arm_gic_umask(0, vector); +} + +/** + * This function returns the active interrupt number. + * @param none + */ +int rt_hw_interrupt_get_irq(void) +{ + return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK; +} + +/** + * This function acknowledges the interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_ack(int vector) +{ + arm_gic_ack(0, vector); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param handler the interrupt service routine to be installed + * @param param the parameter for interrupt service routine + * @param name the interrupt name + * + * @return the old handler + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_snprintf(isr_table[vector].name, RT_NAME_MAX, "%s", name); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + /* set the interrupt to this cpu */ + arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id()); + } + + return old_handler; +} + +void rt_hw_interrupt_trigger(int vector) +{ + arm_gic_trigger(0, 1 << rt_cpu_get_smp_id(), vector); +} + +void rt_hw_interrupt_clear(int vector) +{ + /* SGI will be cleared automatically. */ +}
\ No newline at end of file diff --git a/libcpu/arm/zynqmp-r5/interrupt.h b/libcpu/arm/zynqmp-r5/interrupt.h new file mode 100644 index 0000000000..71459fa0a9 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/interrupt.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include <rthw.h> +#include <board.h> + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); +int rt_hw_interrupt_get_irq(void); +void rt_hw_interrupt_trigger(int vector); +void rt_hw_interrupt_clear(int vector); +void rt_hw_interrupt_ack(int vector); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif diff --git a/libcpu/arm/zynqmp-r5/mpu.c b/libcpu/arm/zynqmp-r5/mpu.c new file mode 100644 index 0000000000..dc33a5fe65 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/mpu.c @@ -0,0 +1,288 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file mpu.c +* +* This file contains initial configuration of the MPU. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------- +* 5.00 pkp 02/20/14 First release +* 5.04 pkp 12/18/15 Updated MPU initialization as per the proper address map +* 6.00 pkp 06/27/16 moving the Init_MPU code to .boot section since it is a +* part of processor boot process +* 6.2 mus 01/27/17 Updated to support IAR compiler +* 7.1 mus 09/11/19 Added warning message if DDR size is not in power of 2. +* Fix for CR#1038577. +* 7.2 asa 04/08/20 Fix warning in the function Init_MPU. +* </pre> +* +* @note +* +* None. +* +******************************************************************************/ +/***************************** Include Files *********************************/ +#include <rtthread.h> +#include "zynqmp-r5.h" +#include "xreg_cortexr5.h" +#include "xpseudo_asm_gcc.h" + +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ +typedef rt_int32_t s32; +typedef rt_uint64_t u64; +typedef rt_uint32_t u32; +/************************** Constant Definitions *****************************/ + +/************************** Variable Definitions *****************************/ + +static const struct { + u64 size; + unsigned int encoding; +}region_size[] = { + { 0x20, REGION_32B }, + { 0x40, REGION_64B }, + { 0x80, REGION_128B }, + { 0x100, REGION_256B }, + { 0x200, REGION_512B }, + { 0x400, REGION_1K }, + { 0x800, REGION_2K }, + { 0x1000, REGION_4K }, + { 0x2000, REGION_8K }, + { 0x4000, REGION_16K }, + { 0x8000, REGION_32K }, + { 0x10000, REGION_64K }, + { 0x20000, REGION_128K }, + { 0x40000, REGION_256K }, + { 0x80000, REGION_512K }, + { 0x100000, REGION_1M }, + { 0x200000, REGION_2M }, + { 0x400000, REGION_4M }, + { 0x800000, REGION_8M }, + { 0x1000000, REGION_16M }, + { 0x2000000, REGION_32M }, + { 0x4000000, REGION_64M }, + { 0x8000000, REGION_128M }, + { 0x10000000, REGION_256M }, + { 0x20000000, REGION_512M }, + { 0x40000000, REGION_1G }, + { 0x80000000, REGION_2G }, + { 0x100000000, REGION_4G }, +}; + +/************************** Function Prototypes ******************************/ +#if defined (__GNUC__) +void Init_MPU(void) __attribute__((__section__(".boot"))); +static void Xil_SetAttribute(u32 addr, u32 reg_size,s32 reg_num, u32 attrib) __attribute__((__section__(".boot"))); +static void Xil_DisableMPURegions(void) __attribute__((__section__(".boot"))); +#elif defined (__ICCARM__) +#pragma default_function_attributes = @ ".boot" +void Init_MPU(void); +static void Xil_SetAttribute(u32 addr, u32 reg_size,s32 reg_num, u32 attrib); +static void Xil_DisableMPURegions(void); +#endif +/***************************************************************************** +* +* Initialize MPU for a given address map and Enabled the background Region in +* MPU with default memory attributes for rest of address range for Cortex R5 +* processor. +* +* @param None. +* +* @return None. +* +* +******************************************************************************/ + +void Init_MPU(void) +{ + u32 Addr; + u32 RegSize = 0U; + u32 Attrib; + u32 RegNum = 0, i, Offset = 0; + u64 size; + + Xil_DisableMPURegions(); + + Addr = 0x00000000U; +#ifdef XPAR_PSU_R5_DDR_0_S_AXI_BASEADDR + /* If the DDR is present, configure region as per DDR size */ + size = (XPAR_PSU_R5_DDR_0_S_AXI_HIGHADDR - XPAR_PSU_R5_DDR_0_S_AXI_BASEADDR) + 1; + if (size < 0x80000000) { + /* Lookup the size. */ + for (i = 0; i < sizeof region_size / sizeof region_size[0]; i++) { + if (size <= region_size[i].size) { + RegSize = region_size[i].encoding; + + /* Check if DDR size is in power of 2*/ + if ( XPAR_PSU_R5_DDR_0_S_AXI_BASEADDR == 0x100000) + Offset = XPAR_PSU_R5_DDR_0_S_AXI_BASEADDR; + if (region_size[i].size > (size + Offset + 1)) { + rt_kprintf ("WARNING: DDR size mapped to Cortexr5 processor is not \ + in power of 2. As processor allocates MPU regions size \ + in power of 2, address range %llx to %x has been \ + incorrectly mapped as normal memory \n", \ + region_size[i].size - 1, ((u32)XPAR_PSU_R5_DDR_0_S_AXI_HIGHADDR + 1)); + } + break; + } + } + } else { + /* if the DDR size is > 2GB, truncate it to 2GB */ + RegSize = REGION_2G; + } +#else + /* For DDRless system, configure region for TCM */ + RegSize = REGION_256K; +#endif + Attrib = NORM_NSHARED_WB_WA | PRIV_RW_USER_RW; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* + * 1G of strongly ordered memory from 0x80000000 to 0xBFFFFFFF for PL. + * 512 MB - LPD-PL interface + * 256 MB - FPD-PL (HPM0) interface + * 256 MB - FPD-PL (HPM1) interface + */ + Addr = 0x80000000; + RegSize = REGION_1G; + Attrib = STRONG_ORDERD_SHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 512M of device memory from 0xC0000000 to 0xDFFFFFFF for QSPI */ + Addr = 0xC0000000U; + RegSize = REGION_512M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 256M of device memory from 0xE0000000 to 0xEFFFFFFF for PCIe Low */ + Addr = 0xE0000000U; + RegSize = REGION_256M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 16M of device memory from 0xF8000000 to 0xF8FFFFFF for STM_CORESIGHT */ + Addr = 0xF8000000U; + RegSize = REGION_16M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 1M of device memory from 0xF9000000 to 0xF90FFFFF for RPU_A53_GIC */ + Addr = 0xF9000000U; + RegSize = REGION_1M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 16M of device memory from 0xFD000000 to 0xFDFFFFFF for FPS slaves */ + Addr = 0xFD000000U; + RegSize = REGION_16M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 16M of device memory from 0xFE000000 to 0xFEFFFFFF for Upper LPS slaves */ + Addr = 0xFE000000U; + RegSize = REGION_16M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* + * 16M of device memory from 0xFF000000 to 0xFFFFFFFF for Lower LPS slaves, + * CSU, PMU, TCM, OCM + */ + Addr = 0xFF000000U; + RegSize = REGION_16M; + Attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + RegNum++; + + /* 256K of OCM RAM from 0xFFFC0000 to 0xFFFFFFFF marked as normal memory */ + Addr = 0xFFFC0000U; + RegSize = REGION_256K; + Attrib = NORM_NSHARED_WB_WA| PRIV_RW_USER_RW ; + Xil_SetAttribute(Addr,RegSize,RegNum, Attrib); + + /* A total of 10 MPU regions are allocated with another 6 being free for users */ + +} + +/***************************************************************************** +* +* Set the memory attributes for a section of memory with starting address addr +* of the region size defined by reg_size having attributes attrib of region number +* reg_num +* +* @param addr is the address for which attributes are to be set. +* @param attrib specifies the attributes for that memory region. +* @param reg_size specifies the size for that memory region. +* @param reg_num specifies the number for that memory region. +* @return None. +* +* +******************************************************************************/ +static void Xil_SetAttribute(u32 addr, u32 reg_size,s32 reg_num, u32 attrib) +{ + u32 Local_reg_size = reg_size; + + Local_reg_size = Local_reg_size<<1U; + Local_reg_size |= REGION_EN; + dsb(); + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num); + isb(); + mtcp(XREG_CP15_MPU_REG_BASEADDR,addr); /* Set base address of a region */ + mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL,attrib); /* Set the control attribute */ + mtcp(XREG_CP15_MPU_REG_SIZE_EN,Local_reg_size); /* set the region size and enable it*/ + dsb(); + isb(); /* synchronize context on this processor */ +} + + +/***************************************************************************** +* +* Disable all the MPU regions if any of them is enabled +* +* @param None. +* +* @return None. +* +* +******************************************************************************/ +static void Xil_DisableMPURegions(void) +{ + u32 Temp = 0U; + u32 Index = 0U; + for (Index = 0; Index <= 15; Index++) { + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,Index); +#if defined (__GNUC__) + Temp = mfcp(XREG_CP15_MPU_REG_SIZE_EN); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); +#endif + Temp &= (~REGION_EN); + dsb(); + mtcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); + dsb(); + isb(); + } + +} + +#if defined (__ICCARM__) +#pragma default_function_attributes = +#endif diff --git a/libcpu/arm/zynqmp-r5/stack.c b/libcpu/arm/zynqmp-r5/stack.c new file mode 100644 index 0000000000..c8ba712c49 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/stack.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + * 2020-11-24 WangHuachen porting to zynqmp-r5 + */ +#include <rtthread.h> +#include "armv7.h" + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + 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)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0xdeadbeef; /* r12 */ + *(--stk) = 0xdeadbeef; /* r11 */ + *(--stk) = 0xdeadbeef; /* r10 */ + *(--stk) = 0xdeadbeef; /* r9 */ + *(--stk) = 0xdeadbeef; /* r8 */ + *(--stk) = 0xdeadbeef; /* r7 */ + *(--stk) = 0xdeadbeef; /* r6 */ + *(--stk) = 0xdeadbeef; /* r5 */ + *(--stk) = 0xdeadbeef; /* r4 */ + *(--stk) = 0xdeadbeef; /* r3 */ + *(--stk) = 0xdeadbeef; /* r2 */ + *(--stk) = 0xdeadbeef; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + { + int i; + for (i = 0; i < VFP_DATA_NR; i++) + { + *(--stk) = 0; + } + /* FPSCR TODO: do we need to set the values other than 0? */ + *(--stk) = 0; + /* FPEXC. Enable the FVP if no lazy stacking. */ + *(--stk) = 0x40000000; + } +#endif + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + diff --git a/libcpu/arm/zynqmp-r5/start_gcc.S b/libcpu/arm/zynqmp-r5/start_gcc.S new file mode 100644 index 0000000000..faea0022be --- /dev/null +++ b/libcpu/arm/zynqmp-r5/start_gcc.S @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-19 WangHuachen first version + */ + +.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 I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.equ UND_Stack_Size, 0x00000000 +.equ SVC_Stack_Size, 0x00000000 +.equ ABT_Stack_Size, 0x00000000 +.equ FIQ_Stack_Size, 0x00000200 +.equ IRQ_Stack_Size, 0x00000200 +.equ USR_Stack_Size, 0x00000000 + +.set RPU_GLBL_CNTL, 0xFF9A0000 +.set RPU_ERR_INJ, 0xFF9A0020 +.set RPU_0_CFG, 0xFF9A0100 +.set RPU_1_CFG, 0xFF9A0200 +.set RST_LPD_DBG, 0xFF5E0240 +.set BOOT_MODE_USER, 0xFF5E0200 +.set fault_log_enable, 0x101 + +#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + FIQ_Stack_Size + IRQ_Stack_Size) + +.section .data.share.isr +/* stack */ +.globl stack_start +.globl stack_top + +.align 3 +.bss +stack_start: +.rept ISR_Stack_Size +.long 0 +.endr +stack_top: + +.section .boot,"axS" +/* reset entry */ +.globl _reset +_reset: + + /* Initialize processor registers to 0 */ + mov r0,#0 + mov r1,#0 + mov r2,#0 + mov r3,#0 + mov r4,#0 + mov r5,#0 + mov r6,#0 + mov r7,#0 + mov r8,#0 + mov r9,#0 + mov r10,#0 + mov r11,#0 + mov r12,#0 + + /* set the cpu to SVC32 mode and disable interrupt */ + cpsid if, #Mode_SVC + + /* setup stack */ + bl stack_setup + + /* + * Enable access to VFP by enabling access to Coprocessors 10 and 11. + * Enables Full Access i.e. in both privileged and non privileged modes + */ + mrc p15, 0, r0, c1, c0, 2 /* Read Coprocessor Access Control Register (CPACR) */ + orr r0, r0, #(0xF << 20) /* Enable access to CP 10 & 11 */ + mcr p15, 0, r0, c1, c0, 2 /* Write Coprocessor Access Control Register (CPACR) */ + isb + + /* enable fpu access */ + vmrs r3, FPEXC + orr r1, r3, #(1<<30) + vmsr FPEXC, r1 + + /* clear the floating point register*/ + mov r1,#0 + vmov d0,r1,r1 + vmov d1,r1,r1 + vmov d2,r1,r1 + vmov d3,r1,r1 + vmov d4,r1,r1 + vmov d5,r1,r1 + vmov d6,r1,r1 + vmov d7,r1,r1 + vmov d8,r1,r1 + vmov d9,r1,r1 + vmov d10,r1,r1 + vmov d11,r1,r1 + vmov d12,r1,r1 + vmov d13,r1,r1 + vmov d14,r1,r1 + vmov d15,r1,r1 + +#ifdef __SOFTFP__ +/* Disable the FPU if SOFTFP is defined*/ + vmsr FPEXC,r3 +#endif + + /* Disable MPU and caches */ + mrc p15, 0, r0, c1, c0, 0 /* Read CP15 Control Register*/ + bic r0, r0, #0x05 /* Disable MPU (M bit) and data cache (C bit) */ + bic r0, r0, #0x1000 /* Disable instruction cache (I bit) */ + dsb /* Ensure all previous loads/stores have completed */ + mcr p15, 0, r0, c1, c0, 0 /* Write CP15 Control Register */ + isb /* Ensure subsequent insts execute wrt new MPU settings */ + + /* Disable Branch prediction, TCM ECC checks */ + mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR */ + orr r0, r0, #(0x1 << 17) /* Enable RSDIS bit 17 to disable the return stack */ + orr r0, r0, #(0x1 << 16) /* Clear BP bit 15 and set BP bit 16:*/ + bic r0, r0, #(0x1 << 15) /* Branch always not taken and history table updates disabled*/ + orr r0, r0, #(0x1 << 27) /* Enable B1TCM ECC check */ + orr r0, r0, #(0x1 << 26) /* Enable B0TCM ECC check */ + orr r0, r0, #(0x1 << 25) /* Enable ATCM ECC check */ + bic r0, r0, #(0x1 << 5) /* Generate abort on parity errors, with [5:3]=b 000*/ + bic r0, r0, #(0x1 << 4) + bic r0, r0, #(0x1 << 3) + mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/ + dsb /* Complete all outstanding explicit memory operations*/ + + /* Invalidate caches */ + mov r0,#0 /* r0 = 0 */ + dsb + mcr p15, 0, r0, c7, c5, 0 /* invalidate icache */ + mcr p15, 0, r0, c15, c5, 0 /* Invalidate entire data cache*/ + isb + + /* enable fault log for lock step */ + ldr r0,=RPU_GLBL_CNTL + ldr r1, [r0] + ands r1, r1, #0x8 + /* branch to initialization if split mode*/ + bne init + /* check for boot mode if in lock step, branch to init if JTAG boot mode*/ + ldr r0,=BOOT_MODE_USER + ldr r1, [r0] + ands r1, r1, #0xF + beq init + /* reset the debug logic */ + ldr r0,=RST_LPD_DBG + ldr r1, [r0] + orr r1, r1, #(0x1 << 4) + orr r1, r1, #(0x1 << 5) + str r1, [r0] + /* enable fault log */ + ldr r0,=RPU_ERR_INJ + ldr r1,=fault_log_enable + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + nop + nop + +init: + bl Init_MPU /* Initialize MPU */ + + /* Enable Branch prediction */ + mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR*/ + bic r0, r0, #(0x1 << 17) /* Clear RSDIS bit 17 to enable return stack*/ + bic r0, r0, #(0x1 << 16) /* Clear BP bit 15 and BP bit 16:*/ + bic r0, r0, #(0x1 << 15) /* Normal operation, BP is taken from the global history table.*/ + orr r0, r0, #(0x1 << 14) /* Disable DBWR for errata 780125 */ + mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/ + + /* Enable icahce and dcache */ + mrc p15,0,r1,c1,c0,0 + ldr r0, =0x1005 + orr r1,r1,r0 + dsb + mcr p15,0,r1,c1,c0,0 /* Enable cache */ + isb /* isb flush prefetch buffer */ + + /* Set vector table in TCM/LOVEC */ + mrc p15, 0, r0, c1, c0, 0 + mvn r1, #0x2000 + and r0, r0, r1 + mcr p15, 0, r0, c1, c0, 0 + + /* Clear VINITHI to enable LOVEC on reset */ +#if 1 + ldr r0, =RPU_0_CFG +#else + ldr r0, =RPU_1_CFG +#endif + ldr r1, [r0] + bic r1, r1, #(0x1 << 2) + str r1, [r0] + + /* enable asynchronous abort exception */ + mrs r0, cpsr + bic r0, r0, #0x100 + msr cpsr_xsf, r0 + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* 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, _entry + +_entry: + .word entry + +stack_setup: + ldr r0, =stack_top + + @ Set the startup stack for svc + mov sp, r0 + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #UND_Stack_Size + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #FIQ_Stack_Size + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #IRQ_Stack_Size + + @ Switch back to SVC + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + + bx lr + +.section .text.isr, "ax" +/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ + .align 5 +.globl vector_fiq +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc,lr,#4 + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + + .align 5 +.globl vector_irq +vector_irq: + stmfd sp!, {r0-r12,lr} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + vstmdb sp!, {d0-d15} /* Store floating point registers */ + vmrs r1, FPSCR + stmfd sp!,{r1} + vmrs r1, FPEXC + stmfd sp!,{r1} +#endif + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + @ 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 + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + ldmfd sp!, {r1} /* Restore floating point registers */ + vmsr FPEXC, r1 + ldmfd sp!, {r1} + vmsr FPSCR, r1 + vldmia sp!, {d0-d15} +#endif + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + mov r1, #0 @ clear flag + str r1, [r0] + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + ldmfd sp!, {r1} /* Restore floating point registers */ + vmsr FPEXC, r1 + ldmfd sp!, {r1} + vmsr FPSCR, r1 + vldmia sp!, {d0-d15} +#endif + + mov r1, sp @ r1 point to {r0-r3} in stack + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr}@ reload saved registers + mrs r0, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + + @ Switch to SVC mode with no interrupt. + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r1-r4} @ push old task's r0-r3 + stmfd sp!, {r0} @ push old task's cpsr + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + vstmdb sp!, {d0-d15} /* Store floating point registers */ + vmrs r1, FPSCR + stmfd sp!,{r1} + vmrs r1, FPEXC + stmfd sp!,{r1} +#endif + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r7, [r6] + ldr sp, [r7] @ get new task's stack pointer + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) + ldmfd sp!, {r1} /* Restore floating point registers */ + vmsr FPEXC, r1 + ldmfd sp!, {r1} + vmsr FPSCR, r1 + vldmia sp!, {d0-d15} +#endif + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +.macro push_svc_reg + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + str lr, [r0, #15*4] @/* Push PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #Mode_SVC + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm + + .align 5 + .globl vector_swi +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . + + .align 5 + .globl vector_undef +vector_undef: + push_svc_reg + bl rt_hw_trap_undef + b . + + .align 5 + .globl vector_pabt +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . + + .align 5 + .globl vector_dabt +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . + + .align 5 + .globl vector_resv +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . diff --git a/libcpu/arm/zynqmp-r5/trap.c b/libcpu/arm/zynqmp-r5/trap.c new file mode 100644 index 0000000000..7a48a3c190 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/trap.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2020-11-24 WangHuachen porting to zynqmp-r5 + */ + +#include <rtthread.h> +#include <rthw.h> +#include <board.h> + +#include "armv7.h" +#include "interrupt.h" + +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register (struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("data abort:"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq(void) +{ + void *param; + int ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_irq(); + + if (ir == 1023) + { + /* Spurious interrupt */ + return; + } + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[ir].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[ir].param; + /* turn to interrupt service routine */ + isr_func(ir, param); + } + + /* end of interrupt */ + rt_hw_interrupt_ack(ir); +} + +void rt_hw_trap_fiq(void) +{ + void *param; + int ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_irq(); + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + param = isr_table[ir].param; + + /* turn to interrupt service routine */ + isr_func(ir, param); + + /* end of interrupt */ + rt_hw_interrupt_ack(ir); +} + diff --git a/libcpu/arm/zynqmp-r5/vector_gcc.S b/libcpu/arm/zynqmp-r5/vector_gcc.S new file mode 100644 index 0000000000..60d3c6cf1d --- /dev/null +++ b/libcpu/arm/zynqmp-r5/vector_gcc.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .vectors, "ax" +.code 32 + +.globl 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 + +.globl _reset +.globl vector_undef +.globl vector_swi +.globl vector_pabt +.globl vector_dabt +.globl vector_resv +.globl vector_irq +.globl vector_fiq + +_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 + +.balignl 16,0xdeadbeef diff --git a/libcpu/arm/zynqmp-r5/xpseudo_asm_gcc.h b/libcpu/arm/zynqmp-r5/xpseudo_asm_gcc.h new file mode 100644 index 0000000000..f3f978d9eb --- /dev/null +++ b/libcpu/arm/zynqmp-r5/xpseudo_asm_gcc.h @@ -0,0 +1,249 @@ +/****************************************************************************** +* +* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* +* +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xpseudo_asm_gcc.h +* +* This header file contains macros for using inline assembler code. It is +* written specifically for the GNU compiler. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- -------- -------- ----------------------------------------------- +* 5.00 pkp 05/21/14 First release +* 6.0 mus 07/27/16 Consolidated file for a53,a9 and r5 processors +* </pre> +* +******************************************************************************/ + +#ifndef XPSEUDO_ASM_GCC_H /* prevent circular inclusions */ +#define XPSEUDO_ASM_GCC_H /* by using protection macros */ + +/***************************** Include Files ********************************/ +#include <rtdef.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/* necessary for pre-processor */ +#define stringify(s) tostring(s) +#define tostring(s) #s + +#if defined (__aarch64__) +/* pseudo assembler instructions */ +#define mfcpsr() ({rt_uint32_t rval = 0U; \ + asm volatile("mrs %0, DAIF" : "=r" (rval));\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__ ("msr DAIF, %0" : : "r" (v)) + +#define cpsiei() //__asm__ __volatile__("cpsie i\n") +#define cpsidi() //__asm__ __volatile__("cpsid i\n") + +#define cpsief() //__asm__ __volatile__("cpsie f\n") +#define cpsidf() //__asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) /*__asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + )*/ + +#define mfgpr(rn) /*({rt_uint32_t rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + })*/ + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb sy") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__("dsb sy") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__("dmb sy") + + +/* Memory Operations */ +#define ldr(adr) ({u64 rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define mfelrel3() ({u64 rval = 0U; \ + asm volatile("mrs %0, ELR_EL3" : "=r" (rval));\ + rval;\ + }) + +#define mtelrel3(v) __asm__ __volatile__ ("msr ELR_EL3, %0" : : "r" (v)) + +#else + +/* pseudo assembler instructions */ +#define mfcpsr() ({rt_uint32_t rval = 0U; \ + __asm__ __volatile__(\ + "mrs %0, cpsr\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +#define mtcpsr(v) __asm__ __volatile__(\ + "msr cpsr,%0\n"\ + : : "r" (v)\ + ) + +#define cpsiei() __asm__ __volatile__("cpsie i\n") +#define cpsidi() __asm__ __volatile__("cpsid i\n") + +#define cpsief() __asm__ __volatile__("cpsie f\n") +#define cpsidf() __asm__ __volatile__("cpsid f\n") + + + +#define mtgpr(rn, v) __asm__ __volatile__(\ + "mov r" stringify(rn) ", %0 \n"\ + : : "r" (v)\ + ) + +#define mfgpr(rn) ({rt_uint32_t rval; \ + __asm__ __volatile__(\ + "mov %0,r" stringify(rn) "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) + +/* memory synchronization operations */ + +/* Instruction Synchronization Barrier */ +#define isb() __asm__ __volatile__ ("isb" : : : "memory") + +/* Data Synchronization Barrier */ +#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") + +/* Data Memory Barrier */ +#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") + + +/* Memory Operations */ +#define ldr(adr) ({rt_uint32_t rval; \ + __asm__ __volatile__(\ + "ldr %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#endif + +#define ldrb(adr) ({rt_uint8_t rval; \ + __asm__ __volatile__(\ + "ldrb %0,[%1]"\ + : "=r" (rval) : "r" (adr)\ + );\ + rval;\ + }) + +#define str(adr, val) __asm__ __volatile__(\ + "str %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +#define strb(adr, val) __asm__ __volatile__(\ + "strb %0,[%1]\n"\ + : : "r" (val), "r" (adr)\ + ) + +/* Count leading zeroes (clz) */ +#define clz(arg) ({rt_uint8_t rval; \ + __asm__ __volatile__(\ + "clz %0,%1"\ + : "=r" (rval) : "r" (arg)\ + );\ + rval;\ + }) + +#if defined (__aarch64__) +#define mtcpdc(reg,val) __asm__ __volatile__("dc " #reg ",%0" : : "r" (val)) +#define mtcpic(reg,val) __asm__ __volatile__("ic " #reg ",%0" : : "r" (val)) + +#define mtcpicall(reg) __asm__ __volatile__("ic " #reg) +#define mtcptlbi(reg) __asm__ __volatile__("tlbi " #reg) +#define mtcpat(reg,val) __asm__ __volatile__("at " #reg ",%0" : : "r" (val)) +/* CP15 operations */ +#define mfcp(reg) ({u64 rval = 0U;\ + __asm__ __volatile__("mrs %0, " #reg : "=r" (rval));\ + rval;\ + }) + +#define mtcp(reg,val) __asm__ __volatile__("msr " #reg ",%0" : : "r" (val)) + +#else +/* CP15 operations */ +#define mtcp(rn, v) __asm__ __volatile__(\ + "mcr " rn "\n"\ + : : "r" (v)\ + ); + +#define mfcp(rn) ({rt_uint32_t rval = 0U; \ + __asm__ __volatile__(\ + "mrc " rn "\n"\ + : "=r" (rval)\ + );\ + rval;\ + }) +#endif + +/************************** Variable Definitions ****************************/ + +/************************** Function Prototypes *****************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XPSEUDO_ASM_GCC_H */ diff --git a/libcpu/arm/zynqmp-r5/xreg_cortexr5.h b/libcpu/arm/zynqmp-r5/xreg_cortexr5.h new file mode 100644 index 0000000000..263f213567 --- /dev/null +++ b/libcpu/arm/zynqmp-r5/xreg_cortexr5.h @@ -0,0 +1,419 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xreg_cortexr5.h +* +* This header file contains definitions for using inline assembler code. It is +* written specifically for the GNU, IAR, ARMCC compiler. +* +* All of the ARM Cortex R5 GPRs, SPRs, and Debug Registers are defined along +* with the positions of the bits within the registers. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- -------- -------- ----------------------------------------------- +* 5.00 pkp 02/10/14 Initial version +* </pre> +* +******************************************************************************/ +#ifndef XREG_CORTEXR5_H /* prevent circular inclusions */ +#define XREG_CORTEXR5_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* GPRs */ +#define XREG_GPR0 r0 +#define XREG_GPR1 r1 +#define XREG_GPR2 r2 +#define XREG_GPR3 r3 +#define XREG_GPR4 r4 +#define XREG_GPR5 r5 +#define XREG_GPR6 r6 +#define XREG_GPR7 r7 +#define XREG_GPR8 r8 +#define XREG_GPR9 r9 +#define XREG_GPR10 r10 +#define XREG_GPR11 r11 +#define XREG_GPR12 r12 +#define XREG_GPR13 r13 +#define XREG_GPR14 r14 +#define XREG_GPR15 r15 +#define XREG_CPSR cpsr + +/* Coprocessor number defines */ +#define XREG_CP0 0 +#define XREG_CP1 1 +#define XREG_CP2 2 +#define XREG_CP3 3 +#define XREG_CP4 4 +#define XREG_CP5 5 +#define XREG_CP6 6 +#define XREG_CP7 7 +#define XREG_CP8 8 +#define XREG_CP9 9 +#define XREG_CP10 10 +#define XREG_CP11 11 +#define XREG_CP12 12 +#define XREG_CP13 13 +#define XREG_CP14 14 +#define XREG_CP15 15 + +/* Coprocessor control register defines */ +#define XREG_CR0 cr0 +#define XREG_CR1 cr1 +#define XREG_CR2 cr2 +#define XREG_CR3 cr3 +#define XREG_CR4 cr4 +#define XREG_CR5 cr5 +#define XREG_CR6 cr6 +#define XREG_CR7 cr7 +#define XREG_CR8 cr8 +#define XREG_CR9 cr9 +#define XREG_CR10 cr10 +#define XREG_CR11 cr11 +#define XREG_CR12 cr12 +#define XREG_CR13 cr13 +#define XREG_CR14 cr14 +#define XREG_CR15 cr15 + +/* Current Processor Status Register (CPSR) Bits */ +#define XREG_CPSR_THUMB_MODE 0x20U +#define XREG_CPSR_MODE_BITS 0x1FU +#define XREG_CPSR_SYSTEM_MODE 0x1FU +#define XREG_CPSR_UNDEFINED_MODE 0x1BU +#define XREG_CPSR_DATA_ABORT_MODE 0x17U +#define XREG_CPSR_SVC_MODE 0x13U +#define XREG_CPSR_IRQ_MODE 0x12U +#define XREG_CPSR_FIQ_MODE 0x11U +#define XREG_CPSR_USER_MODE 0x10U + +#define XREG_CPSR_IRQ_ENABLE 0x80U +#define XREG_CPSR_FIQ_ENABLE 0x40U + +#define XREG_CPSR_N_BIT 0x80000000U +#define XREG_CPSR_Z_BIT 0x40000000U +#define XREG_CPSR_C_BIT 0x20000000U +#define XREG_CPSR_V_BIT 0x10000000U + +/*MPU region definitions*/ +#define REGION_32B 0x00000004U +#define REGION_64B 0x00000005U +#define REGION_128B 0x00000006U +#define REGION_256B 0x00000007U +#define REGION_512B 0x00000008U +#define REGION_1K 0x00000009U +#define REGION_2K 0x0000000AU +#define REGION_4K 0x0000000BU +#define REGION_8K 0x0000000CU +#define REGION_16K 0x0000000DU +#define REGION_32K 0x0000000EU +#define REGION_64K 0x0000000FU +#define REGION_128K 0x00000010U +#define REGION_256K 0x00000011U +#define REGION_512K 0x00000012U +#define REGION_1M 0x00000013U +#define REGION_2M 0x00000014U +#define REGION_4M 0x00000015U +#define REGION_8M 0x00000016U +#define REGION_16M 0x00000017U +#define REGION_32M 0x00000018U +#define REGION_64M 0x00000019U +#define REGION_128M 0x0000001AU +#define REGION_256M 0x0000001BU +#define REGION_512M 0x0000001CU +#define REGION_1G 0x0000001DU +#define REGION_2G 0x0000001EU +#define REGION_4G 0x0000001FU + +#define REGION_EN 0x00000001U + + + +#define SHAREABLE 0x00000004U /*shareable */ +#define STRONG_ORDERD_SHARED 0x00000000U /*strongly ordered, always shareable*/ + +#define DEVICE_SHARED 0x00000001U /*device, shareable*/ +#define DEVICE_NONSHARED 0x00000010U /*device, non shareable*/ + +#define NORM_NSHARED_WT_NWA 0x00000002U /*Outer and Inner write-through, no write-allocate non-shareable*/ +#define NORM_SHARED_WT_NWA 0x00000006U /*Outer and Inner write-through, no write-allocate shareable*/ + +#define NORM_NSHARED_WB_NWA 0x00000003U /*Outer and Inner write-back, no write-allocate non shareable*/ +#define NORM_SHARED_WB_NWA 0x00000007U /*Outer and Inner write-back, no write-allocate shareable*/ + +#define NORM_NSHARED_NCACHE 0x00000008U /*Outer and Inner Non cacheable non shareable*/ +#define NORM_SHARED_NCACHE 0x0000000CU /*Outer and Inner Non cacheable shareable*/ + +#define NORM_NSHARED_WB_WA 0x0000000BU /*Outer and Inner write-back non shared*/ +#define NORM_SHARED_WB_WA 0x0000000FU /*Outer and Inner write-back shared*/ + +/* inner and outer cache policies can be combined for different combinations */ + +#define NORM_IN_POLICY_NCACHE 0x00000020U /*inner non cacheable*/ +#define NORM_IN_POLICY_WB_WA 0x00000021U /*inner write back write allocate*/ +#define NORM_IN_POLICY_WT_NWA 0x00000022U /*inner write through no write allocate*/ +#define NORM_IN_POLICY_WB_NWA 0x00000023U /*inner write back no write allocate*/ + +#define NORM_OUT_POLICY_NCACHE 0x00000020U /*outer non cacheable*/ +#define NORM_OUT_POLICY_WB_WA 0x00000028U /*outer write back write allocate*/ +#define NORM_OUT_POLICY_WT_NWA 0x00000030U /*outer write through no write allocate*/ +#define NORM_OUT_POLICY_WB_NWA 0x00000038U /*outer write back no write allocate*/ + +#define NO_ACCESS (0x00000000U<<8U) /*No access*/ +#define PRIV_RW_USER_NA (0x00000001U<<8U) /*Privileged access only*/ +#define PRIV_RW_USER_RO (0x00000002U<<8U) /*Writes in User mode generate permission faults*/ +#define PRIV_RW_USER_RW (0x00000003U<<8U) /*Full Access*/ +#define PRIV_RO_USER_NA (0x00000005U<<8U) /*Privileged eead only*/ +#define PRIV_RO_USER_RO (0x00000006U<<8U) /*Privileged/User read-only*/ + +#define EXECUTE_NEVER (0x00000001U<<12U) /* Bit 12*/ + + +/* CP15 defines */ + +/* C0 Register defines */ +#define XREG_CP15_MAIN_ID "p15, 0, %0, c0, c0, 0" +#define XREG_CP15_CACHE_TYPE "p15, 0, %0, c0, c0, 1" +#define XREG_CP15_TCM_TYPE "p15, 0, %0, c0, c0, 2" +#define XREG_CP15_TLB_TYPE "p15, 0, %0, c0, c0, 3" +#define XREG_CP15_MPU_TYPE "p15, 0, %0, c0, c0, 4" +#define XREG_CP15_MULTI_PROC_AFFINITY "p15, 0, %0, c0, c0, 5" + +#define XREG_CP15_PROC_FEATURE_0 "p15, 0, %0, c0, c1, 0" +#define XREG_CP15_PROC_FEATURE_1 "p15, 0, %0, c0, c1, 1" +#define XREG_CP15_DEBUG_FEATURE_0 "p15, 0, %0, c0, c1, 2" +#define XREG_CP15_MEMORY_FEATURE_0 "p15, 0, %0, c0, c1, 4" +#define XREG_CP15_MEMORY_FEATURE_1 "p15, 0, %0, c0, c1, 5" +#define XREG_CP15_MEMORY_FEATURE_2 "p15, 0, %0, c0, c1, 6" +#define XREG_CP15_MEMORY_FEATURE_3 "p15, 0, %0, c0, c1, 7" + +#define XREG_CP15_INST_FEATURE_0 "p15, 0, %0, c0, c2, 0" +#define XREG_CP15_INST_FEATURE_1 "p15, 0, %0, c0, c2, 1" +#define XREG_CP15_INST_FEATURE_2 "p15, 0, %0, c0, c2, 2" +#define XREG_CP15_INST_FEATURE_3 "p15, 0, %0, c0, c2, 3" +#define XREG_CP15_INST_FEATURE_4 "p15, 0, %0, c0, c2, 4" +#define XREG_CP15_INST_FEATURE_5 "p15, 0, %0, c0, c2, 5" + +#define XREG_CP15_CACHE_SIZE_ID "p15, 1, %0, c0, c0, 0" +#define XREG_CP15_CACHE_LEVEL_ID "p15, 1, %0, c0, c0, 1" +#define XREG_CP15_AUXILARY_ID "p15, 1, %0, c0, c0, 7" + +#define XREG_CP15_CACHE_SIZE_SEL "p15, 2, %0, c0, c0, 0" + +/* C1 Register Defines */ +#define XREG_CP15_SYS_CONTROL "p15, 0, %0, c1, c0, 0" +#define XREG_CP15_AUX_CONTROL "p15, 0, %0, c1, c0, 1" +#define XREG_CP15_CP_ACCESS_CONTROL "p15, 0, %0, c1, c0, 2" + + +/* XREG_CP15_CONTROL bit defines */ +#define XREG_CP15_CONTROL_TE_BIT 0x40000000U +#define XREG_CP15_CONTROL_AFE_BIT 0x20000000U +#define XREG_CP15_CONTROL_TRE_BIT 0x10000000U +#define XREG_CP15_CONTROL_NMFI_BIT 0x08000000U +#define XREG_CP15_CONTROL_EE_BIT 0x02000000U +#define XREG_CP15_CONTROL_HA_BIT 0x00020000U +#define XREG_CP15_CONTROL_RR_BIT 0x00004000U +#define XREG_CP15_CONTROL_V_BIT 0x00002000U +#define XREG_CP15_CONTROL_I_BIT 0x00001000U +#define XREG_CP15_CONTROL_Z_BIT 0x00000800U +#define XREG_CP15_CONTROL_SW_BIT 0x00000400U +#define XREG_CP15_CONTROL_B_BIT 0x00000080U +#define XREG_CP15_CONTROL_C_BIT 0x00000004U +#define XREG_CP15_CONTROL_A_BIT 0x00000002U +#define XREG_CP15_CONTROL_M_BIT 0x00000001U +/* C2 Register Defines */ +/* Not Used */ + +/* C3 Register Defines */ +/* Not Used */ + +/* C4 Register Defines */ +/* Not Used */ + +/* C5 Register Defines */ +#define XREG_CP15_DATA_FAULT_STATUS "p15, 0, %0, c5, c0, 0" +#define XREG_CP15_INST_FAULT_STATUS "p15, 0, %0, c5, c0, 1" + +#define XREG_CP15_AUX_DATA_FAULT_STATUS "p15, 0, %0, c5, c1, 0" +#define XREG_CP15_AUX_INST_FAULT_STATUS "p15, 0, %0, c5, c1, 1" + +/* C6 Register Defines */ +#define XREG_CP15_DATA_FAULT_ADDRESS "p15, 0, %0, c6, c0, 0" +#define XREG_CP15_INST_FAULT_ADDRESS "p15, 0, %0, c6, c0, 2" + +#define XREG_CP15_MPU_REG_BASEADDR "p15, 0, %0, c6, c1, 0" +#define XREG_CP15_MPU_REG_SIZE_EN "p15, 0, %0, c6, c1, 2" +#define XREG_CP15_MPU_REG_ACCESS_CTRL "p15, 0, %0, c6, c1, 4" + +#define XREG_CP15_MPU_MEMORY_REG_NUMBER "p15, 0, %0, c6, c2, 0" + +/* C7 Register Defines */ +#define XREG_CP15_NOP "p15, 0, %0, c7, c0, 4" + +#define XREG_CP15_INVAL_IC_POU "p15, 0, %0, c7, c5, 0" +#define XREG_CP15_INVAL_IC_LINE_MVA_POU "p15, 0, %0, c7, c5, 1" + +/* The CP15 register access below has been deprecated in favor of the new + * isb instruction in Cortex R5. + */ +#define XREG_CP15_INST_SYNC_BARRIER "p15, 0, %0, c7, c5, 4" +#define XREG_CP15_INVAL_BRANCH_ARRAY "p15, 0, %0, c7, c5, 6" +#define XREG_CP15_INVAL_BRANCH_ARRAY_LINE "p15, 0, %0, c7, c5, 7" + +#define XREG_CP15_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c6, 1" +#define XREG_CP15_INVAL_DC_LINE_SW "p15, 0, %0, c7, c6, 2" + + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POC "p15, 0, %0, c7, c10, 1" +#define XREG_CP15_CLEAN_DC_LINE_SW "p15, 0, %0, c7, c10, 2" + +#define XREG_CP15_INVAL_DC_ALL "p15, 0, %0, c15, c5, 0" +/* The next two CP15 register accesses below have been deprecated in favor + * of the new dsb and dmb instructions in Cortex R5. + */ +#define XREG_CP15_DATA_SYNC_BARRIER "p15, 0, %0, c7, c10, 4" +#define XREG_CP15_DATA_MEMORY_BARRIER "p15, 0, %0, c7, c10, 5" + +#define XREG_CP15_CLEAN_DC_LINE_MVA_POU "p15, 0, %0, c7, c11, 1" + +#define XREG_CP15_NOP2 "p15, 0, %0, c7, c13, 1" + +#define XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC "p15, 0, %0, c7, c14, 1" +#define XREG_CP15_CLEAN_INVAL_DC_LINE_SW "p15, 0, %0, c7, c14, 2" + +/* C8 Register Defines */ +/* Not Used */ + + +/* C9 Register Defines */ + +#define XREG_CP15_ATCM_REG_SIZE_ADDR "p15, 0, %0, c9, c1, 1" +#define XREG_CP15_BTCM_REG_SIZE_ADDR "p15, 0, %0, c9, c1, 0" +#define XREG_CP15_TCM_SELECTION "p15, 0, %0, c9, c2, 0" + +#define XREG_CP15_PERF_MONITOR_CTRL "p15, 0, %0, c9, c12, 0" +#define XREG_CP15_COUNT_ENABLE_SET "p15, 0, %0, c9, c12, 1" +#define XREG_CP15_COUNT_ENABLE_CLR "p15, 0, %0, c9, c12, 2" +#define XREG_CP15_V_FLAG_STATUS "p15, 0, %0, c9, c12, 3" +#define XREG_CP15_SW_INC "p15, 0, %0, c9, c12, 4" +#define XREG_CP15_EVENT_CNTR_SEL "p15, 0, %0, c9, c12, 5" + +#define XREG_CP15_PERF_CYCLE_COUNTER "p15, 0, %0, c9, c13, 0" +#define XREG_CP15_EVENT_TYPE_SEL "p15, 0, %0, c9, c13, 1" +#define XREG_CP15_PERF_MONITOR_COUNT "p15, 0, %0, c9, c13, 2" + +#define XREG_CP15_USER_ENABLE "p15, 0, %0, c9, c14, 0" +#define XREG_CP15_INTR_ENABLE_SET "p15, 0, %0, c9, c14, 1" +#define XREG_CP15_INTR_ENABLE_CLR "p15, 0, %0, c9, c14, 2" + +/* C10 Register Defines */ +/* Not used */ + +/* C11 Register Defines */ +/* Not used */ + +/* C12 Register Defines */ +/* Not used */ + +/* C13 Register Defines */ +#define XREG_CP15_CONTEXT_ID "p15, 0, %0, c13, c0, 1" +#define USER_RW_THREAD_PID "p15, 0, %0, c13, c0, 2" +#define USER_RO_THREAD_PID "p15, 0, %0, c13, c0, 3" +#define USER_PRIV_THREAD_PID "p15, 0, %0, c13, c0, 4" + +/* C14 Register Defines */ +/* not used */ + +/* C15 Register Defines */ +#define XREG_CP15_SEC_AUX_CTRL "p15, 0, %0, c15, c0, 0" + + + + +/* MPE register definitions */ +#define XREG_FPSID c0 +#define XREG_FPSCR c1 +#define XREG_MVFR1 c6 +#define XREG_MVFR0 c7 +#define XREG_FPEXC c8 +#define XREG_FPINST c9 +#define XREG_FPINST2 c10 + +/* FPSID bits */ +#define XREG_FPSID_IMPLEMENTER_BIT (24U) +#define XREG_FPSID_IMPLEMENTER_MASK (0x000000FFU << FPSID_IMPLEMENTER_BIT) +#define XREG_FPSID_SOFTWARE (0X00000001U << 23U) +#define XREG_FPSID_ARCH_BIT (16U) +#define XREG_FPSID_ARCH_MASK (0x0000000FU << FPSID_ARCH_BIT) +#define XREG_FPSID_PART_BIT (8U) +#define XREG_FPSID_PART_MASK (0x000000FFU << FPSID_PART_BIT) +#define XREG_FPSID_VARIANT_BIT (4U) +#define XREG_FPSID_VARIANT_MASK (0x0000000FU << FPSID_VARIANT_BIT) +#define XREG_FPSID_REV_BIT (0U) +#define XREG_FPSID_REV_MASK (0x0000000FU << FPSID_REV_BIT) + +/* FPSCR bits */ +#define XREG_FPSCR_N_BIT (0X00000001U << 31U) +#define XREG_FPSCR_Z_BIT (0X00000001U << 30U) +#define XREG_FPSCR_C_BIT (0X00000001U << 29U) +#define XREG_FPSCR_V_BIT (0X00000001U << 28U) +#define XREG_FPSCR_QC (0X00000001U << 27U) +#define XREG_FPSCR_AHP (0X00000001U << 26U) +#define XREG_FPSCR_DEFAULT_NAN (0X00000001U << 25U) +#define XREG_FPSCR_FLUSHTOZERO (0X00000001U << 24U) +#define XREG_FPSCR_ROUND_NEAREST (0X00000000U << 22U) +#define XREG_FPSCR_ROUND_PLUSINF (0X00000001U << 22U) +#define XREG_FPSCR_ROUND_MINUSINF (0X00000002U << 22U) +#define XREG_FPSCR_ROUND_TOZERO (0X00000003U << 22U) +#define XREG_FPSCR_RMODE_BIT (22U) +#define XREG_FPSCR_RMODE_MASK (0X00000003U << FPSCR_RMODE_BIT) +#define XREG_FPSCR_STRIDE_BIT (20U) +#define XREG_FPSCR_STRIDE_MASK (0X00000003U << FPSCR_STRIDE_BIT) +#define XREG_FPSCR_LENGTH_BIT (16U) +#define XREG_FPSCR_LENGTH_MASK (0X00000007U << FPSCR_LENGTH_BIT) +#define XREG_FPSCR_IDC (0X00000001U << 7U) +#define XREG_FPSCR_IXC (0X00000001U << 4U) +#define XREG_FPSCR_UFC (0X00000001U << 3U) +#define XREG_FPSCR_OFC (0X00000001U << 2U) +#define XREG_FPSCR_DZC (0X00000001U << 1U) +#define XREG_FPSCR_IOC (0X00000001U << 0U) + +/* MVFR0 bits */ +#define XREG_MVFR0_RMODE_BIT (28U) +#define XREG_MVFR0_RMODE_MASK (0x0000000FU << XREG_MVFR0_RMODE_BIT) +#define XREG_MVFR0_SHORT_VEC_BIT (24U) +#define XREG_MVFR0_SHORT_VEC_MASK (0x0000000FU << XREG_MVFR0_SHORT_VEC_BIT) +#define XREG_MVFR0_SQRT_BIT (20U) +#define XREG_MVFR0_SQRT_MASK (0x0000000FU << XREG_MVFR0_SQRT_BIT) +#define XREG_MVFR0_DIVIDE_BIT (16U) +#define XREG_MVFR0_DIVIDE_MASK (0x0000000FU << XREG_MVFR0_DIVIDE_BIT) +#define XREG_MVFR0_EXEC_TRAP_BIT (12U) +#define XREG_MVFR0_EXEC_TRAP_MASK (0x0000000FU << XREG_MVFR0_EXEC_TRAP_BIT) +#define XREG_MVFR0_DP_BIT (8U) +#define XREG_MVFR0_DP_MASK (0x0000000FU << XREG_MVFR0_DP_BIT) +#define XREG_MVFR0_SP_BIT (4U) +#define XREG_MVFR0_SP_MASK (0x0000000FU << XREG_MVFR0_SP_BIT) +#define XREG_MVFR0_A_SIMD_BIT (0U) +#define XREG_MVFR0_A_SIMD_MASK (0x0000000FU << MVFR0_A_SIMD_BIT) + +/* FPEXC bits */ +#define XREG_FPEXC_EX (0X00000001U << 31U) +#define XREG_FPEXC_EN (0X00000001U << 30U) +#define XREG_FPEXC_DEX (0X00000001U << 29U) + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XREG_CORTEXR5_H */ diff --git a/libcpu/avr32/uc3/SConscript b/libcpu/avr32/uc3/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/avr32/uc3/SConscript +++ b/libcpu/avr32/uc3/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/avr32/uc3/cpu.c b/libcpu/avr32/uc3/cpu.c index b77e78dc5b..fdd8a4d56c 100644 --- a/libcpu/avr32/uc3/cpu.c +++ b/libcpu/avr32/uc3/cpu.c @@ -23,7 +23,7 @@ * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { /*NOTREACHED*/ } diff --git a/libcpu/avr32/uc3/exception_gcc.S b/libcpu/avr32/uc3/exception_gcc.S index d5051af253..cdf2576f54 100644 --- a/libcpu/avr32/uc3/exception_gcc.S +++ b/libcpu/avr32/uc3/exception_gcc.S @@ -289,7 +289,7 @@ rt_hw_context_switch_interrupt_do: ld.w r12, r12[0] lda.w r11, rt_interrupt_to_thread /* Get new thread SP */ ld.w r11, r11[0] - st.w r12[0], sp /* Store old thead SP */ + st.w r12[0], sp /* Store old thread SP */ ld.w sp, r11[0] /* Load new thread SP */ ldm sp++, r0-r7 /* Pop R0-R7 (new thread) */ rete /* RETE pops R8-R12, LR, PC, SR automatically */ diff --git a/libcpu/blackfin/bf53x/SConscript b/libcpu/blackfin/bf53x/SConscript index af9ba4bc81..85882caf6f 100644 --- a/libcpu/blackfin/bf53x/SConscript +++ b/libcpu/blackfin/bf53x/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_vdsp.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/c-sky/ck802/SConscript b/libcpu/c-sky/ck802/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/c-sky/ck802/SConscript +++ b/libcpu/c-sky/ck802/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/c-sky/common/SConscript b/libcpu/c-sky/common/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/c-sky/common/SConscript +++ b/libcpu/c-sky/common/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/ia32/SConscript b/libcpu/ia32/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/ia32/SConscript +++ b/libcpu/ia32/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/ia32/__udivsi3.c b/libcpu/ia32/__udivsi3.c index ec7c59d1cb..5a5622f883 100644 --- a/libcpu/ia32/__udivsi3.c +++ b/libcpu/ia32/__udivsi3.c @@ -1,11 +1,7 @@ /* - * File : __udivsi3.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Develop Team + * Copyright (c) 2006-2021, 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://openlab.rt-thread.com/license/LICENSE + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes diff --git a/libcpu/ia32/__umodsi3.c b/libcpu/ia32/__umodsi3.c index 226a2c0800..d47fe3d295 100644 --- a/libcpu/ia32/__umodsi3.c +++ b/libcpu/ia32/__umodsi3.c @@ -1,11 +1,7 @@ /* - * File : __umodsi3.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Develop Team + * Copyright (c) 2006-2021, 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://openlab.rt-thread.com/license/LICENSE + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes diff --git a/libcpu/ia32/backtrace.c b/libcpu/ia32/backtrace.c deleted file mode 100644 index b8f094d90f..0000000000 --- a/libcpu/ia32/backtrace.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * File : backtrace.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2008-07-29 Bernard first version - */ - -#include <rtthread.h> - -void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry) -{ - /* no implementation */ -} diff --git a/libcpu/ia32/context_gcc.S b/libcpu/ia32/context_gcc.S index a8ad867b91..32233303c7 100644 --- a/libcpu/ia32/context_gcc.S +++ b/libcpu/ia32/context_gcc.S @@ -1,11 +1,7 @@ /* - * File : context_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * Copyright (c) 2006-2021, 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 @@ -83,31 +79,3 @@ rt_hw_context_switch_to: pop %ds add $4, %esp /* skip irqno */ iret - -/* - * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); - */ -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: - pushl %ebp - movl %esp, %ebp - movl 0xc(%ebp), %eax - movl 0x8(%ebp), %ebx - - movl $rt_thread_switch_interrupt_flag, %ecx - movl (%ecx), %edx - cmp $0x1, %edx - jz _reswitch - - movl $0x1, %edx /*set rt_thread_switch_interrupt_flag to 1*/ - movl %edx, (%ecx) - movl $rt_interrupt_from_thread, %edx /*set rt_interrupt_from_thread*/ - movl %ebx, (%edx) -_reswitch: - movl $rt_interrupt_to_thread, %edx /*set rt_interrupt_to_thread*/ - movl %eax, (%edx) - leave - ret diff --git a/libcpu/ia32/stack.c b/libcpu/ia32/cpuport.c index 9d656a73d6..69032c2f87 100644 --- a/libcpu/ia32/stack.c +++ b/libcpu/ia32/cpuport.c @@ -1,24 +1,43 @@ /* - * File : stack.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * Copyright (c) 2006-2021, 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://openlab.rt-thread.com/license/LICENSE + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2021/02/19 Bernard Implement rt_hw_context_switch_interrupt in C */ +#include <rthw.h> #include <rtthread.h> -#include <i386.h> +volatile rt_ubase_t rt_interrupt_from_thread = 0; +volatile rt_ubase_t rt_interrupt_to_thread = 0; +volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0; -/** - * @addtogroup I386 - */ -/*@{*/ +rt_base_t rt_hw_interrupt_disable(void) +{ + rt_base_t level; + + __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (level): :"memory"); + return level; +} + +void rt_hw_interrupt_enable(rt_base_t level) +{ + __asm__ __volatile__("pushl %0 ; popfl": :"g" (level):"memory", "cc"); +} + +void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) +{ + if (rt_thread_switch_interrupt_flag == 0) + rt_interrupt_from_thread = from; + + rt_interrupt_to_thread = to; + rt_thread_switch_interrupt_flag = 1; + + return ; +} /** * This function will initialize thread stack @@ -56,4 +75,3 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, /* return task's current stack address */ return (rt_uint8_t *)stk; } -/*@}*/ diff --git a/libcpu/ia32/hdisr_gcc.S b/libcpu/ia32/hdisr_gcc.S index 6f79fe4c2a..24c4c17990 100644 --- a/libcpu/ia32/hdisr_gcc.S +++ b/libcpu/ia32/hdisr_gcc.S @@ -1,11 +1,7 @@ /* - * File : hdisr_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * Copyright (c) 2006-2021, 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 diff --git a/libcpu/ia32/interrupt.c b/libcpu/ia32/interrupt.c index e620cbe76c..d597848c52 100644 --- a/libcpu/ia32/interrupt.c +++ b/libcpu/ia32/interrupt.c @@ -1,38 +1,20 @@ /* - * File : interrupt.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * Copyright (c) 2006-2021, 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 * 2015/9/15 Bernard Update to new interrupt framework. */ -#include <rtthread.h> #include <rthw.h> +#include <rtthread.h> #include <bsp.h> -extern rt_uint32_t rt_interrupt_nest; extern void rt_hw_idt_init(void); -rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; -rt_uint32_t rt_thread_switch_interrupt_flag; - /* exception and interrupt handler table */ struct rt_irq_desc irq_desc[MAX_HANDLERS]; @@ -50,45 +32,39 @@ void rt_hw_interrupt_handle(int vector, void* param); */ void rt_hw_pic_init() { - outb(IO_PIC1, 0x11); - outb(IO_PIC1+1, IRQ_OFFSET); - outb(IO_PIC1+1, 1<<IRQ_SLAVE); - outb(IO_PIC1+1, 0x3); - outb(IO_PIC1+1, 0xff); - outb(IO_PIC1, 0x68); - outb(IO_PIC1, 0x0a); - outb(IO_PIC2, 0x11); - outb(IO_PIC2+1, IRQ_OFFSET + 8); - outb(IO_PIC2+1, IRQ_SLAVE); - outb(IO_PIC2+1, 0x3); - outb(IO_PIC2+1, 0xff); - outb(IO_PIC2, 0x68); - outb(IO_PIC2, 0x0a); + outb(IO_PIC1, 0x11); + outb(IO_PIC1+1, IRQ_OFFSET); + outb(IO_PIC1+1, 1<<IRQ_SLAVE); + outb(IO_PIC1+1, 0x3); + outb(IO_PIC1+1, 0xff); + outb(IO_PIC1, 0x68); + outb(IO_PIC1, 0x0a); + outb(IO_PIC2, 0x11); + outb(IO_PIC2+1, IRQ_OFFSET + 8); + outb(IO_PIC2+1, IRQ_SLAVE); + outb(IO_PIC2+1, 0x3); + outb(IO_PIC2+1, 0xff); + outb(IO_PIC2, 0x68); + outb(IO_PIC2, 0x0a); - if (irq_mask_8259A != 0xFFFF) - { - outb(IO_PIC1+1, (char)irq_mask_8259A); - outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); - } - - /* init interrupt nest, and context */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + if (irq_mask_8259A != 0xFFFF) + { + outb(IO_PIC1+1, (char)irq_mask_8259A); + outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); + } } void rt_hw_interrupt_handle(int vector, void* param) { - rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } void rt_hw_isr(int vector) { - if (vector < MAX_HANDLERS) - { - irq_desc[vector].handler(vector, irq_desc[vector].param); - } + if (vector < MAX_HANDLERS) + { + irq_desc[vector].handler(vector, irq_desc[vector].param); + } } /** @@ -97,10 +73,10 @@ void rt_hw_isr(int vector) */ void rt_hw_interrupt_init(void) { - int idx; - - rt_hw_idt_init(); - rt_hw_pic_init(); + int idx; + + rt_hw_idt_init(); + rt_hw_pic_init(); /* init exceptions table */ for(idx=0; idx < MAX_HANDLERS; idx++) @@ -116,16 +92,16 @@ void rt_hw_interrupt_init(void) void rt_hw_interrupt_umask(int vector) { - irq_mask_8259A = irq_mask_8259A&~(1<<vector); - outb(IO_PIC1+1, (char)irq_mask_8259A); - outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); + irq_mask_8259A = irq_mask_8259A&~(1<<vector); + outb(IO_PIC1+1, (char)irq_mask_8259A); + outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); } void rt_hw_interrupt_mask(int vector) { - irq_mask_8259A = irq_mask_8259A | (1<<vector); - outb(IO_PIC1+1, (char)irq_mask_8259A); - outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); + irq_mask_8259A = irq_mask_8259A | (1<<vector); + outb(IO_PIC1+1, (char)irq_mask_8259A); + outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8)); } rt_isr_handler_t rt_hw_interrupt_install(int vector, @@ -152,17 +128,4 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, return old_handler; } -rt_base_t rt_hw_interrupt_disable(void) -{ - rt_base_t level; - - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (level): :"memory"); - return level; -} - -void rt_hw_interrupt_enable(rt_base_t level) -{ - __asm__ __volatile__("pushl %0 ; popfl": :"g" (level):"memory", "cc"); -} - /*@}*/ diff --git a/libcpu/ia32/showmem.c b/libcpu/ia32/showmem.c deleted file mode 100644 index 38f037f83d..0000000000 --- a/libcpu/ia32/showmem.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * File : showmem.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2008-07-29 Bernard first version from QiuYi implementation - */ - -#include <rtthread.h> - -void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size) -{ - int i = 0, j =0; - - RT_ASSERT(addr); - - addr = addr & ~0xF; - size = 4*((size + 3)/4); - - while(i < size) - { - rt_kprintf("0x%08x: ", addr ); - - for(j=0; j<4; j++) - { - rt_kprintf("0x%08x ", *(rt_uint32_t *)addr); - - addr += 4; - i++; - } - - rt_kprintf("\n"); - } - - return; -} diff --git a/libcpu/ia32/start_gcc.S b/libcpu/ia32/start_gcc.S index 84adc83fe2..ee7d2787fd 100644 --- a/libcpu/ia32/start_gcc.S +++ b/libcpu/ia32/start_gcc.S @@ -1,11 +1,7 @@ /* - * File : start.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * Copyright (c) 2006-2021, 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 @@ -52,8 +48,8 @@ multiboot_entry: pushl $0 popf - /*rebuild globe describe table*/ - lgdt mygdtdesc + /* rebuild globe describe table */ + lgdt __gdtdesc movl $0x10,%eax movw %ax,%ds @@ -77,7 +73,7 @@ spin: .data .p2align 2 -mygdt: +__gdt: .word 0,0,0,0 .word 0x07FF /* 8Mb - limit=2047 */ @@ -90,8 +86,8 @@ mygdt: .word 0x9200 /* data read/write */ .word 0x00C0 -mygdtdesc: +__gdtdesc: .word 0x17 - .long mygdt + .long __gdt /*@}*/ diff --git a/libcpu/ia32/trap.c b/libcpu/ia32/trap.c index 5e9a51d6d2..172a078273 100644 --- a/libcpu/ia32/trap.c +++ b/libcpu/ia32/trap.c @@ -1,18 +1,14 @@ /* - * File : trap.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * Copyright (c) 2006-2021, 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://openlab.rt-thread.com/license/LICENSE + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes */ - -#include <rtthread.h> + #include <rthw.h> +#include <rtthread.h> #include <bsp.h> @@ -29,6 +25,7 @@ struct Pseudodesc idt_pd = extern rt_isr_handler_t isr_table[]; extern rt_isr_handler_t trap_func[]; extern rt_isr_handler_t hdinterrupt_func[]; +extern void rt_hw_interrupt_handle(int vector, void* param); /** * @addtogroup I386 @@ -41,7 +38,7 @@ extern rt_isr_handler_t hdinterrupt_func[]; */ void rt_hw_idt_init(void) { - extern void Xdefault; + extern void Xdefault(void); int i, j, func; // install a default handler @@ -92,7 +89,7 @@ void rt_hw_trap_irq(int trapno) rt_kprintf("General protection interrupt\n"); RT_ASSERT(0); case T_DEFAULT: - rt_hw_interrupt_handle(T_DEFAULT); + rt_hw_interrupt_handle(T_DEFAULT, RT_NULL); return; } diff --git a/libcpu/ia32/trapisr_gcc.S b/libcpu/ia32/trapisr_gcc.S index be7e97a5fb..82887ecda3 100644 --- a/libcpu/ia32/trapisr_gcc.S +++ b/libcpu/ia32/trapisr_gcc.S @@ -1,11 +1,7 @@ /* - * File : trapisr_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team + * Copyright (c) 2006-2021, 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 @@ -22,6 +18,7 @@ .globl proc;\ .type proc,@function;\ proc: + #define TRAPFNC(name,num)\ ENTRY(name)\ pushl $(num);\ @@ -29,6 +26,7 @@ .data;\ .long name;\ .text + #define TRAPFNC_NOEC(name,num)\ ENTRY(name)\ pushl $0;\ @@ -54,17 +52,17 @@ TRAPFNC_NOEC(Xoflow, 4) TRAPFNC_NOEC(Xbound, 5) TRAPFNC_NOEC(Xillop, 6) TRAPFNC_NOEC(Xdevice, 7) -TRAPFNC (Xdblflt, 8) -TRAPFNC (Xtss, 9) -TRAPFNC (Xsegnp, 10) -TRAPFNC (Xstack, 11) -TRAPFNC (Xgpflt, 12) -TRAPFNC (Xpgflt, 13) +TRAPFNC (Xdblflt, 8) +TRAPFNC (Xtss, 9) +TRAPFNC (Xsegnp, 10) +TRAPFNC (Xstack, 11) +TRAPFNC (Xgpflt, 12) +TRAPFNC (Xpgflt, 13) TRAPFNC_NOEC(Xfperr, 14) -TRAPFNC (Xalign, 15) +TRAPFNC (Xalign, 15) /* default handler -- not for any specific trap */ -TRAPFNC (Xdefault, 500) +TRAPFNC (Xdefault, 500) .p2align 4,0x90 .globl _traps diff --git a/libcpu/m16c/m16c62p/SConscript b/libcpu/m16c/m16c62p/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/m16c/m16c62p/SConscript +++ b/libcpu/m16c/m16c62p/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/mips/common/SConscript b/libcpu/mips/common/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/mips/common/SConscript +++ b/libcpu/mips/common/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/mips/common/asm.h b/libcpu/mips/common/asm.h index 6a5353b803..1b39eea05a 100644 --- a/libcpu/mips/common/asm.h +++ b/libcpu/mips/common/asm.h @@ -261,11 +261,7 @@ symbol = value #define LONG_SRAV srav #define LONG .word -#ifdef ARCH_MIPS64 -#define LONGSIZE 8 -#else #define LONGSIZE 4 -#endif #define LONGMASK 3 #define LONGLOG 2 diff --git a/libcpu/mips/common/context_gcc.S b/libcpu/mips/common/context_gcc.S index cdcdede39a..3fdbe374c9 100644 --- a/libcpu/mips/common/context_gcc.S +++ b/libcpu/mips/common/context_gcc.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-12-04 Jiaxun Yang Initial version + * 2020-07-26 lizhirui Fixed some problems */ #ifndef __ASSEMBLY__ @@ -56,12 +57,12 @@ rt_hw_context_switch_interrupt: bnez t1, _reswitch nop li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */ - sw t1, 0(t0) + LONG_S t1, 0(t0) PTR_LA t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ - sw a0, 0(t0) + LONG_S a0, 0(t0) _reswitch: PTR_LA t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ - sw a1, 0(t0) + LONG_S a1, 0(t0) jr ra nop @@ -97,24 +98,24 @@ mips_irq_handle: * rt_hw_context_switch_interrupt_do and do not return */ PTR_LA k0, rt_thread_switch_interrupt_flag - lw k1, 0(k0) + LONG_L k1, 0(k0) beqz k1, spurious_interrupt nop - sw zero, 0(k0) /* clear flag */ + LONG_S zero, 0(k0) /* clear flag */ nop /* * switch to the new thread */ PTR_LA k0, rt_interrupt_from_thread - lw k1, 0(k0) + LONG_L k1, 0(k0) nop - sw sp, 0(k1) /* store sp in preempted task TCB */ + LONG_S sp, 0(k1) /* store sp in preempted task TCB */ PTR_LA k0, rt_interrupt_to_thread - lw k1, 0(k0) + LONG_L k1, 0(k0) nop - lw sp, 0(k1) /* get new task stack pointer */ + LONG_L sp, 0(k1) /* get new task stack pointer */ j spurious_interrupt nop diff --git a/libcpu/mips/common/exception.c b/libcpu/mips/common/exception.c index cd7d97e6c0..3da8ecead6 100644 --- a/libcpu/mips/common/exception.c +++ b/libcpu/mips/common/exception.c @@ -24,6 +24,41 @@ rt_ubase_t rt_interrupt_from_thread; rt_ubase_t rt_interrupt_to_thread; rt_ubase_t rt_thread_switch_interrupt_flag; +const char *exception_name[] = { + "Interrupt", + "(X)TLB Modify Exception", + "(X)TLB Read/Fetch Exception", + "(X)TLB Write Exception", + "Address Read/Fetch Exception", + "Address Write Exception", + "", + "", + "Syscall", + "Breakpoint", + "Reversed Instruction Exception", + "Coprocessor Unit Invalid", + "Overflow", + "Trap", + "FPU Exception in Vector Instruction", + "FPU Exception", + "Loongson Custom Exception", + "", + "", + "(X)TLB Read Denied Exception", + "(X)TLB Execute Denied Exception", + "Vector Module Disabled Exception", + "", + "", + "", + "", + "", + "", + "", + "", + "Cache Error Exception", + "" + }; + rt_base_t rt_hw_interrupt_disable(void) { rt_base_t status = read_c0_status(); @@ -39,7 +74,7 @@ void rt_hw_interrupt_enable(rt_base_t level) /** * exception handle table */ -#define RT_EXCEPTION_MAX 31 +#define RT_EXCEPTION_MAX 32 exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX]; /** @@ -59,10 +94,13 @@ exception_func_t rt_set_except_vector(int n, exception_func_t func) return old_handler; } -void mips_dump_regs(struct pt_regs *regs) { +void mips_dump_regs(struct pt_regs *regs) +{ int i, j; - for(i = 0; i < 32 / 4; i++) { - for(j = 0; j < 4; j++) { + for (i = 0; i < 32 / 4; i++) + { + for (j = 0; j < 4; j++) + { int reg = 4 * i + j; rt_kprintf("%d: 0x%08x, ", reg, regs->regs[reg]); } @@ -84,9 +122,15 @@ void cache_error_handler(void) static void unhandled_exception_handle(struct pt_regs *regs) { - rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause()); + rt_kprintf("Unknown Exception, EPC: 0x%p, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause()); + rt_kprintf("Exception Name:%s\n",exception_name[(read_c0_cause() >> 2) & 0x1f]); +#ifdef SOC_LS2K1000 + rt_kprintf("ExeCode = 0x%08x,BadAddr = 0x%p\n",(read_c0_cause() >> 2) & 0x1f,mmu_tlb_get_bad_vaddr()); +#else + rt_kprintf("ExeCode = 0x%08x\n",(read_c0_cause() >> 2) & 0x1f); +#endif rt_kprintf("ST0: 0x%08x ",regs->cp0_status); - rt_kprintf("ErrorPC: 0x%08x\n",read_c0_errorepc()); + rt_kprintf("ErrorPC: 0x%p\n",read_c0_errorepc()); mips_dump_regs(regs); rt_hw_cpu_shutdown(); } @@ -95,8 +139,9 @@ static void install_default_exception_handler(void) { rt_int32_t i; - for (i=0; i<RT_EXCEPTION_MAX; i++) - sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle; + for (i = 0; i < RT_EXCEPTION_MAX; i++) + sys_exception_handlers[i] = + (exception_func_t)unhandled_exception_handle; } int rt_hw_exception_init(void) @@ -117,14 +162,16 @@ int rt_hw_exception_init(void) void rt_general_exc_dispatch(struct pt_regs *regs) { - rt_ubase_t exccode = 0; - + rt_ubase_t cause, exccode; + cause = read_c0_cause(); + exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; - if (exccode == 0) { + if (exccode == 0) + { rt_ubase_t status, pending; - status = read_c0_status(); - pending = (CAUSEF_IP) & (status & ST0_IM); + status = read_c0_status(); + pending = (cause & CAUSEF_IP) & (status & ST0_IM); if (pending & CAUSEF_IP0) rt_do_mips_cpu_irq(0); if (pending & CAUSEF_IP1) @@ -141,7 +188,9 @@ void rt_general_exc_dispatch(struct pt_regs *regs) rt_do_mips_cpu_irq(6); if (pending & CAUSEF_IP7) rt_do_mips_cpu_irq(7); - } else { + } + else + { if (sys_exception_handlers[exccode]) sys_exception_handlers[exccode](regs); } diff --git a/libcpu/mips/common/exception_gcc.S b/libcpu/mips/common/exception_gcc.S index 9664438ac1..c685928a84 100644 --- a/libcpu/mips/common/exception_gcc.S +++ b/libcpu/mips/common/exception_gcc.S @@ -1,11 +1,12 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-12-04 Jiaxun Yang Initial version + * 2020-07-26 lizhirui Add xtlb exception entry */ #ifndef __ASSEMBLY__ #define __ASSEMBLY__ @@ -26,6 +27,11 @@ tlb_refill_exception: b _general_exception_handler nop + /* 0x080 - XTLB refill handler */ + .org ebase_start + 0x080 + b _general_exception_handler + nop + /* 0x100 - Cache error handler */ .org ebase_start + 0x100 j cache_error_handler diff --git a/libcpu/mips/common/stackframe.h b/libcpu/mips/common/stackframe.h index 258f9a994f..bb92a18c9c 100644 --- a/libcpu/mips/common/stackframe.h +++ b/libcpu/mips/common/stackframe.h @@ -22,7 +22,9 @@ #ifdef RT_USING_FPU /* Ensure CU1 (FPU) is enabled */ MFC0 v1, CP0_STATUS - ori v1, ST0_CU1 + lui t1, %hi(ST0_CU1) + addiu t1, t1, %lo(ST0_CU1) + or v1, v1, t1 MTC0 v1, CP0_STATUS SSNOP cfc1 v1, fcr31 @@ -125,11 +127,13 @@ #ifdef RT_USING_FPU /* Ensure CU1 (FPU) is enabled */ MFC0 v1, CP0_STATUS - ori v1, ST0_CU1 + lui t1, %hi(ST0_CU1) + addiu t1, t1, %lo(ST0_CU1) + or v1, v1, t1 MTC0 v1, CP0_STATUS SSNOP LONG_L v1, PT_FPU_FCSR31(sp) - ctc1 v1, fcsr31 + ctc1 v1, fcr31 l.d $f0, PT_FPU_R0(sp) l.d $f2, PT_FPU_R2(sp) l.d $f4, PT_FPU_R4(sp) @@ -202,6 +206,8 @@ li v1, ~(ST0_CU1 | ST0_FR | ST0_IM) and v0, v1 or v0, a0 + li v1, (ST0_KX | ST0_SX | ST0_UX) + or v0, v1 mtc0 v0, CP0_STATUS LONG_L v1, PT_EPC(sp) MTC0 v1, CP0_EPC diff --git a/libcpu/mips/gs232/SConscript b/libcpu/mips/gs232/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/mips/gs232/SConscript +++ b/libcpu/mips/gs232/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/mips/gs232/cpuport.c b/libcpu/mips/gs232/cpuport.c index 1b13719449..e3c078241f 100644 --- a/libcpu/mips/gs232/cpuport.c +++ b/libcpu/mips/gs232/cpuport.c @@ -23,7 +23,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset(void) +RT_WEAK void rt_hw_cpu_reset(void) { /* open the watch-dog */ WDT_EN = 0x01; /* watch dog enable */ @@ -38,7 +38,7 @@ void rt_hw_cpu_reset(void) * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); diff --git a/libcpu/mips/gs232/gs232.h b/libcpu/mips/gs232/gs232.h index 6e90f7ba66..95c81cf93e 100644 --- a/libcpu/mips/gs232/gs232.h +++ b/libcpu/mips/gs232/gs232.h @@ -17,7 +17,14 @@ #define INTC_BASE 0xBFD01040 +#ifdef SOC_LS1B +#define GS232_INTC_CELLS 4 +#endif + +#ifdef SOC_LS1C300 #define GS232_INTC_CELLS 5 +#endif + #define GS232_NR_IRQS (32 * GS232_INTC_CELLS) #define GMAC0_BASE 0xBFE10000 @@ -64,4 +71,4 @@ extern void rt_hw_timer_init(void); #endif -#endif
\ No newline at end of file +#endif diff --git a/libcpu/mips/gs232/interrupt.c b/libcpu/mips/gs232/interrupt.c index f3e0f80763..66abea379d 100644 --- a/libcpu/mips/gs232/interrupt.c +++ b/libcpu/mips/gs232/interrupt.c @@ -22,7 +22,6 @@ #define MAX_INTR (GS232_NR_IRQS) static struct rt_irq_desc irq_handle_table[MAX_INTR]; -void rt_interrupt_dispatch(void *ptreg); void rt_hw_timer_handler(); static struct gs232_intc_regs volatile *gs232_hw0_icregs diff --git a/libcpu/mips/gs232/ls1b.h b/libcpu/mips/gs232/ls1b.h index 071a4aeb82..a6f244ef4f 100644 --- a/libcpu/mips/gs232/ls1b.h +++ b/libcpu/mips/gs232/ls1b.h @@ -19,6 +19,15 @@ #define LS1B_UART1_IRQ 3 #define LS1B_UART2_IRQ 4 #define LS1B_UART3_IRQ 5 +#define LS1B_UART4_IRQ 29 +#define LS1B_UART5_IRQ 30 +#define LS1B_UART6_IRQ 2 //共享LS1B_UART0_IRQ +#define LS1B_UART7_IRQ 2 +#define LS1B_UART8_IRQ 2 +#define LS1B_UART9_IRQ 3 //共享LS1B_UART1_IRQ +#define LS1B_UART10_IRQ 3 +#define LS1B_UART11_IRQ 3 + #define LS1B_CAN0_IRQ 6 #define LS1B_CAN1_IRQ 7 #define LS1B_SPI0_IRQ 8 @@ -49,7 +58,7 @@ #define LS1B_GPIO_IRQ 64 #define LS1B_GPIO_FIRST_IRQ 64 -#define LS1B_GPIO_IRQ_COUNT 96 +#define LS1B_GPIO_IRQ_COUNT 64 #define LS1B_GPIO_LAST_IRQ (LS1B_GPIO_FIRST_IRQ + LS1B_GPIO_IRQ_COUNT-1) #define INT_PCI_INTA (1<<6) diff --git a/libcpu/mips/gs264/SConscript b/libcpu/mips/gs264/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/mips/gs264/SConscript +++ b/libcpu/mips/gs264/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/mips/gs264/cache.c b/libcpu/mips/gs264/cache.c new file mode 100644 index 0000000000..54d38d0d3f --- /dev/null +++ b/libcpu/mips/gs264/cache.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-29 quanzhao the first version + * 2020-07-26 lizhirui porting to ls2k + */ + +#include <rthw.h> +#include <rtdef.h> + +rt_inline rt_uint64_t rt_cpu_icache_line_size(void) +{ + rt_uint64_t ctr; + return 4 << (ctr & 0xF); +} + +rt_inline rt_uint64_t rt_cpu_dcache_line_size(void) +{ + rt_uint64_t ctr; + return 4 << ((ctr >> 16) & 0xF); +} + +void rt_hw_cpu_icache_invalidate(void *addr, int size) +{ + rt_uint64_t line_size = rt_cpu_icache_line_size(); + rt_uint64_t start_addr = (rt_uint64_t)addr; + rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1; +} + +void rt_hw_cpu_dcache_invalidate(void *addr, int size) +{ + rt_uint64_t line_size = rt_cpu_dcache_line_size(); + rt_uint64_t start_addr = (rt_uint64_t)addr; + rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1; +} + +void rt_hw_cpu_dcache_clean(void *addr, int size) +{ + rt_uint64_t line_size = rt_cpu_dcache_line_size(); + rt_uint64_t start_addr = (rt_uint64_t)addr; + rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1; +} + +void rt_hw_cpu_icache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_INVALIDATE) + rt_hw_cpu_icache_invalidate(addr, size); +} + +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) + rt_hw_cpu_dcache_clean(addr, size); + else if (ops == RT_HW_CACHE_INVALIDATE) + rt_hw_cpu_dcache_invalidate(addr, size); +} + +rt_base_t rt_hw_cpu_icache_status(void) +{ + return 0; +} + +rt_base_t rt_hw_cpu_dcache_status(void) +{ + return 0; +} diff --git a/libcpu/mips/gs264/cache.h b/libcpu/mips/gs264/cache.h new file mode 100644 index 0000000000..10a4afd899 --- /dev/null +++ b/libcpu/mips/gs264/cache.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-03-25 quanzhao the first version + */ +#ifndef __CACHE_H__ +#define __CACHE_H__ + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + +void rt_cpu_vector_set_base(unsigned int addr); + +#endif diff --git a/libcpu/mips/gs264/cpuinit_gcc.S b/libcpu/mips/gs264/cpuinit_gcc.S index bd84663350..592fedd88a 100644 --- a/libcpu/mips/gs264/cpuinit_gcc.S +++ b/libcpu/mips/gs264/cpuinit_gcc.S @@ -19,8 +19,8 @@ .globl rt_cpu_early_init rt_cpu_early_init: - mfc0 t0, CP0_CONFIG - ori t0, 3 - mtc0 t0, CP0_CONFIG + mfc0 t0, CP0_CONFIG + ori t0, 3 + mtc0 t0, CP0_CONFIG ehb - jr ra
\ No newline at end of file + jr ra diff --git a/libcpu/mips/gs264/mips_mmu.c b/libcpu/mips/gs264/mips_mmu.c new file mode 100644 index 0000000000..7bed69596a --- /dev/null +++ b/libcpu/mips/gs264/mips_mmu.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-07-26 lizhirui the first version + */ + +#include <string.h> +#include <stdlib.h> + +#include "mips.h" +#include "mips_mmu.h" + +void mmu_init() +{ + uint32_t status = read_c0_status(); + status |= 0x07 << 5;//ux = 1,sx = 1,kx = 1 + write_c0_status(status); + + mmu_clear_tlb(); + mmu_clear_itlb(); +} + +void mmu_set_cpu_mode(cpu_mode_t cpu_mode) +{ + uint32_t status = read_c0_status(); + status &= ~(0x03 << 3); + status |= ((uint32_t)cpu_mode & 0x03) << 3; + write_c0_status(status); +} + +cpu_mode_t mmu_get_cpu_mode() +{ + uint32_t status = read_c0_status(); + return (cpu_mode_t)((status >> 3) & 0x03); +} + +void mmu_clear_tlb() +{ + uint32_t max_tlb_index = mmu_get_max_tlb_index(); + uint64_t va = KSEG0BASE; + uint32_t entry; + tlb_item_t tlb_item; + + for(entry = 0;entry <= max_tlb_index;entry++) + { + mmu_tlb_item_init(&tlb_item); + mmu_tlb_write_indexed(entry,&tlb_item); + } +} + +void mmu_clear_itlb() +{ + uint32_t diag = read_c0_diag(); + write_c0_diag(diag | (0x01 << 2));//write ITLB bit + read_c0_entrylo0(); +} + +uint32_t mmu_get_max_tlb_index() +{ + uint32_t config1 = read_c0_config1(); + return ((config1 >> 25) & 0x3F); +} + +void mmu_tlb_write_indexed(uint32_t index,tlb_item_t *tlb_item) +{ + tlb_item -> entry_lo[0].g |= tlb_item -> entry_lo[1].g; + tlb_item -> entry_lo[1].g |= tlb_item -> entry_lo[0].g; + mmu_tlb_set_index(index); + write_c0_entrylo0(reg_type_convert(tlb_item -> entry_lo[0],uint64_t)); + write_c0_entrylo1(reg_type_convert(tlb_item -> entry_lo[1],uint64_t)); + write_c0_entryhi(reg_type_convert(tlb_item -> entry_hi,uint64_t)); + write_c0_pagemask(reg_type_convert(tlb_item -> page_mask,uint64_t)); + tlb_write_indexed(); + read_c0_entrylo0(); +} + +void mmu_tlb_write_random(tlb_item_t *tlb_item) +{ + tlb_item -> entry_lo[0].g |= tlb_item -> entry_lo[1].g; + tlb_item -> entry_lo[1].g |= tlb_item -> entry_lo[0].g; + write_c0_entrylo0(reg_type_convert(tlb_item -> entry_lo[0],uint64_t)); + write_c0_entrylo1(reg_type_convert(tlb_item -> entry_lo[1],uint64_t)); + write_c0_entryhi(reg_type_convert(tlb_item -> entry_hi,uint64_t)); + write_c0_pagemask(reg_type_convert(tlb_item -> page_mask,uint64_t)); + tlb_write_random(); + read_c0_entrylo0(); +} + +void mmu_tlb_read(uint32_t index,tlb_item_t *tlb_item) +{ + mmu_tlb_set_index(index); + tlb_read(); + uint64_t entrylo[2]; + uint64_t entryhi; + uint64_t page_mask; + entrylo[0] = read_c0_entrylo0(); + entrylo[1] = read_c0_entrylo1(); + entryhi = read_c0_entryhi(); + page_mask = read_c0_pagemask(); + tlb_item -> entry_lo[0] = reg_type_convert(entrylo[0],entry_lo_t); + tlb_item -> entry_lo[1] = reg_type_convert(entrylo[1],entry_lo_t); + tlb_item -> entry_hi = reg_type_convert(entryhi,entry_hi_t); + tlb_item -> page_mask = reg_type_convert(page_mask,page_mask_t); +} + +uint32_t mmu_tlb_find(uint64_t vpn,uint32_t asid,uint32_t *index) +{ + entry_hi_t entry_hi; + entry_hi.r = (vpn >> 62) & 0x03; + entry_hi.vpn2 = (vpn >> 13) & 0x7FFFFFFU; + entry_hi.asid = asid & 0xFFU; + tlb_item_t tlb_item; + //mmu_tlb_read(6,&tlb_item); + //tlb_dump(); + mmu_tlb_item_init(&tlb_item); + tlb_item.entry_lo[0].g = tlb_item.entry_lo[1].g = 1; + read_c0_entrylo0();//i don't know why,but if i don't read any register of mmu,tplb will be failed in qemu. + write_c0_entrylo0(reg_type_convert(tlb_item.entry_lo[0],uint64_t)); + write_c0_entrylo1(reg_type_convert(tlb_item.entry_lo[1],uint64_t)); + write_c0_entryhi(reg_type_convert(entry_hi,uint64_t)); + //__asm__ __volatile__("ehb"); + //read_c0_entryhi(); + //rt_kprintf("entry_hi = %p\n",read_c0_entryhi()); + tlb_probe(); + *index = mmu_tlb_get_index(); + return mmu_tlb_is_matched(); +} + +void mmu_tlb_item_init(tlb_item_t *tlb_item) +{ + memset(tlb_item,0,sizeof(tlb_item_t)); + tlb_item -> entry_lo[0].c = 0x03; + tlb_item -> entry_lo[1].c = 0x03; +} + +void mmu_set_map(uint64_t vpn,uint64_t ppn,page_mask_enum_t page_mask,uint32_t asid,uint32_t global) +{ + uint64_t page_mask_v = (uint64_t)page_mask; + + /*if(page_mask_v & (1 << 13)) + { + page_mask_v |= (1 << 12); + }*/ + + uint64_t lb = lowbit((~(page_mask_v)) << 12); + uint64_t pn_remained = ((~(page_mask_v)) << 12) | lb; + vpn &= pn_remained; + ppn &= pn_remained; + uint64_t odd_vpn = vpn | lb; + uint64_t even_vpn = vpn & (~lb); + uint32_t index; + tlb_item_t tlb_item,tlb2_item; + + mmu_tlb_item_init(&tlb_item); + mmu_tlb_item_init(&tlb2_item); + tlb_item.page_mask.mask = page_mask; + + if(mmu_tlb_find(vpn & (~lb),asid,&index)) + { + mmu_tlb_read(index,&tlb_item); + mmu_tlb_write_indexed(index,&tlb2_item); + } + + entry_lo_t *entry_lo = &tlb_item.entry_lo[vpn == even_vpn ? 0 : 1]; + tlb_item.entry_lo[0].g = tlb_item.entry_lo[1].g = global; + entry_lo -> d = 1; + entry_lo -> ri = 0; + entry_lo -> xi = 0; + entry_lo -> v = 1; + entry_lo -> pfn = ppn >> 12; + tlb_item.entry_hi.r = (vpn >> 62) & 0x03; + tlb_item.entry_hi.vpn2 = (vpn >> 13) & 0x7FFFFFFU; + tlb_item.entry_hi.asid = asid & 0xFFU; + mmu_tlb_write_random(&tlb_item); +} + +uint32_t mmu_tlb_get_random() +{ + return read_c0_random(); +} + +uint32_t mmu_tlb_get_index() +{ + return read_c0_index() & 0x3F; +} + +void mmu_tlb_set_index(uint32_t index) +{ + write_c0_index(index & 0x3F); +} + +uint32_t mmu_tlb_is_matched() +{ + return (read_c0_index() & 0x80000000) == 0; +} + +uint64_t mmu_tlb_get_bad_vaddr() +{ + return read_c0_badvaddr(); +} + +void tlb_dump() +{ + uint32_t max_index = mmu_get_max_tlb_index(); + //uint32_t max_index = 10; + uint32_t entry; + tlb_item_t tlb_item; + + for(entry = 0;entry <= max_index;entry++) + { + mmu_tlb_read(entry,&tlb_item); + //mmu_tlb_write_indexed(entry,&tlb_item); + //mmu_tlb_read(entry,&tlb_item); + rt_kprintf("vpn = 0x%p,ppn0 = 0x%p,ppn1 = 0x%p\n",(uint64_t)tlb_item.entry_hi.vpn2 << 13 | (uint64_t)tlb_item.entry_hi.asid << 62,(uint64_t)tlb_item.entry_lo[0].pfn << 12,(uint64_t)tlb_item.entry_lo[1].pfn << 12); + rt_kprintf("v = %d,d = %d,g = %d,ri = %d,xi = %d,c = %d\n",tlb_item.entry_lo[0].v,tlb_item.entry_lo[0].d,tlb_item.entry_lo[0].g,tlb_item.entry_lo[0].ri,tlb_item.entry_lo[0].xi,tlb_item.entry_lo[0].c); + rt_kprintf("v = %d,d = %d,g = %d,ri = %d,xi = %d,c = %d\n",tlb_item.entry_lo[1].v,tlb_item.entry_lo[1].d,tlb_item.entry_lo[1].g,tlb_item.entry_lo[1].ri,tlb_item.entry_lo[1].xi,tlb_item.entry_lo[1].c); + } +} diff --git a/libcpu/mips/gs264/mips_mmu.h b/libcpu/mips/gs264/mips_mmu.h new file mode 100644 index 0000000000..fcbcef3621 --- /dev/null +++ b/libcpu/mips/gs264/mips_mmu.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-07-26 lizhirui the first version + */ +#ifndef __MIPS_MMU_H__ +#define __MIPS_MMU_H__ + +typedef enum cpu_mode_t +{ + CPU_MODE_KERNEL = 0x00, + CPU_MODE_SUPERVISOR = 0x01, + CPU_MODE_USER = 0x02 +}cpu_mode_t; + +typedef enum page_mask_enum_t +{ + PAGE_MASK_4KB = 0x00, + PAGE_MASK_16KB = 0x03, + PAGE_MASK_64KB = 0x0F, + PAGE_MASK_256KB = 0x3F, + PAGE_MASK_1MB = 0xFF, + PAGE_MASK_4MB = 0x3FF, + PAGE_MASK_16MB = 0xFFF, + PAGE_MASK_64MB = 0x3FFF, + PAGE_MASK_256MB = 0xFFFF, + PAGE_MASK_1GB = 0x3FFFF +}page_mask_enum_t; + +typedef struct page_mask_t +{ + uint64_t : 11; + uint64_t : 2; + uint64_t mask : 18; + uint64_t : 33; +}page_mask_t; + +typedef struct entry_lo_t +{ + uint64_t g : 1; + uint64_t v : 1; + uint64_t d : 1; + uint64_t c : 3; + uint64_t pfn : 24; + uint64_t pfnx : 3; + uint64_t : 29; + uint64_t xi : 1; + uint64_t ri : 1; +}entry_lo_t; + +typedef struct entry_hi_t +{ + uint64_t asid : 8; + uint64_t : 5; + uint64_t vpn2 : 27; + uint64_t : 22; + uint64_t r : 2; +}entry_hi_t; + +typedef struct tlb_item_t +{ + entry_lo_t entry_lo[2]; + entry_hi_t entry_hi; + page_mask_t page_mask; +}tlb_item_t; + +#define read_c0_diag() __read_32bit_c0_register($22, 0) +#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) +#define read_c0_badvaddr() __read_64bit_c0_register($8, 0) +#define read_c0_random() __read_32bit_c0_register($1, 0) + +#define reg_type_convert(variable,new_type) *((new_type *)(&variable)) +#define lowbit(x) ((x) & (-(x))) + +void mmu_init(); +void mmu_set_cpu_mode(cpu_mode_t cpu_mode); +cpu_mode_t mmu_get_cpu_mode(); +void mmu_clear_tlb(); +void mmu_clear_itlb(); +uint32_t mmu_get_max_tlb_index(); +void mmu_tlb_write_indexed(uint32_t index,tlb_item_t *tlb_item); +void mmu_tlb_write_random(tlb_item_t *tlb_item); +void mmu_tlb_read(uint32_t index,tlb_item_t *tlb_item); +uint32_t mmu_tlb_find(uint64_t vpn,uint32_t asid,uint32_t *index); +void mmu_tlb_item_init(tlb_item_t *tlb_item); +void mmu_set_map(uint64_t vpn,uint64_t ppn,page_mask_enum_t page_mask,uint32_t asid,uint32_t global); +uint32_t mmu_tlb_get_random(); +uint32_t mmu_tlb_get_index(); +void mmu_tlb_set_index(uint32_t index); +uint32_t mmu_tlb_is_matched(); +uint64_t mmu_tlb_get_bad_vaddr(); + +void tlb_dump(); + +#endif
\ No newline at end of file diff --git a/libcpu/mips/gs264/mipscfg.c b/libcpu/mips/gs264/mipscfg.c new file mode 100644 index 0000000000..b2aed120ae --- /dev/null +++ b/libcpu/mips/gs264/mipscfg.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-07-28 lizhirui first version + */ +#include <rtthread.h> +#include <mips.h> + +mips32_core_cfg_t g_mips_core = +{ + 64, /* icache_line_size */ + 128, /* icache_lines_per_way */ + 4, /* icache_ways */ + 32768, + 64, /* dcache_line_size */ + 128, /* dcache_lines_per_way */ + 4, /* dcache_ways */ + 32768, + 64, /* max_tlb_entries */ +}; + +static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n) +{ + rt_uint16_t rets = 1; + + while (n--) + rets *= b; + + return rets; +} + +static rt_uint16_t m_log2(rt_uint16_t b) +{ + rt_uint16_t rets = 0; + + while (b != 1) + { + b /= 2; + rets++; + } + + return rets; +} + +/** + * read core attribute + */ +void mips32_cfg_init(void) +{ + rt_uint16_t val; + rt_uint32_t cp0_config1; + + cp0_config1 = read_c0_config(); + if (cp0_config1 & 0x80000000) + { + cp0_config1 = read_c0_config1(); + + val = (cp0_config1 & (7<<22))>>22; + g_mips_core.icache_lines_per_way = 64 * m_pow(2, val); + val = (cp0_config1 & (7<<19))>>19; + g_mips_core.icache_line_size = 2 * m_pow(2, val); + val = (cp0_config1 & (7<<16))>>16; + g_mips_core.icache_ways = val + 1; + + val = (cp0_config1 & (7<<13))>>13; + g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val); + val = (cp0_config1 & (7<<10))>>10; + g_mips_core.dcache_line_size = 2 * m_pow(2, val); + val = (cp0_config1 & (7<<7))>>7; + g_mips_core.dcache_ways = val + 1; + + val = (cp0_config1 & (0x3F<<25))>>25; + g_mips_core.max_tlb_entries = val + 1; + } +} diff --git a/libcpu/mips/gs264/mmu.c b/libcpu/mips/gs264/mmu.c new file mode 100644 index 0000000000..b5bedace50 --- /dev/null +++ b/libcpu/mips/gs264/mmu.c @@ -0,0 +1,819 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + * 2020-07-26 lizhirui porting to ls2k + */ + +#include <rtthread.h> +#include <rthw.h> +#include <board.h> + +#include "cache.h" +#include "mips_mmu.h" +#include "mmu.h" + +void *current_mmu_table = RT_NULL; + +void *mmu_table_get() +{ + return current_mmu_table; +} + +void switch_mmu(void *mmu_table) +{ + current_mmu_table = mmu_table; + + mmu_clear_tlb(); + mmu_clear_itlb(); +} + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + for (i = 0; i < 256; i++) + { + rt_uint32_t pte2 = ptb[i]; + if ((pte2 & 0x3) == 0) + { + if (fcnt == 0) + rt_kprintf(" "); + rt_kprintf("%04x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf(" %04x: %x: ", i, pte2); + if ((pte2 & 0x3) == 0x1) + { + rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, + (pte2 >> 15) & 0x1, + ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); + } + else + { + rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, + ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); + } + } +} + +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + rt_kprintf("page table@%p\n", ptb); + for (i = 0; i < 1024*4; i++) + { + rt_uint32_t pte1 = ptb[i]; + if ((pte1 & 0x3) == 0) + { + rt_kprintf("%03x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf("%03x: %08x: ", i, pte1); + if ((pte1 & 0x3) == 0x3) + { + rt_kprintf("LPAE\n"); + } + else if ((pte1 & 0x3) == 0x1) + { + rt_kprintf("pte,ns:%d,domain:%d\n", + (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); + /* + *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) + * - 0x80000000 + 0xC0000000)); + */ + } + else if (pte1 & (1 << 18)) + { + rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); + } + else + { + rt_kprintf("section,ns:%d,ap:%x," + "xn:%d,texcb:%02x,domain:%d\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + (((pte1 & (0x7 << 12)) >> 10) | + ((pte1 & 0x0c) >> 2)) & 0x1f, + (pte1 >> 5) & 0xf); + } + } +} + +/* level1 page table, each entry for 1MB memory. */ +volatile unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); +void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, + rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, + rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i, nSec; + pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for(i = 0; i <= nSec; i++) + { + *pTT = attr | (((paddrStart >> 20) + i) << 20); + pTT++; + } +} + +unsigned long rt_hw_set_domain_register(unsigned long domain_val) +{ + unsigned long old_domain; + + //asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); + //asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); + + return old_domain; +} + +void rt_hw_cpu_dcache_clean(void *addr, int size); +void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size) +{ + /* set page table */ + for(; size > 0; size--) + { + rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); + mdesc++; + } + rt_hw_cpu_dcache_clean((void*)MMUTable, sizeof MMUTable); +} + +void rt_hw_mmu_init(void) +{ + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + rt_hw_cpu_dcache_disable(); + rt_hw_cpu_icache_disable(); + rt_cpu_mmu_disable(); + + /*rt_hw_cpu_dump_page_table(MMUTable);*/ + rt_hw_set_domain_register(0x55555555); + + rt_cpu_tlb_set(MMUTable); + + rt_cpu_mmu_enable(); + + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); +} + +/* + mem map +*/ + +void rt_hw_cpu_dcache_clean(void *addr, int size); + +int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off) +{ + size_t l1_off, va_s, va_e; + rt_base_t level; + + if (!mmu_info || !vtable) + { + return -1; + } + + va_s = (size_t)v_address; + va_e = (size_t)v_address + size - 1; + + if ( va_e < va_s) + { + return -1; + } + + va_s >>= ARCH_SECTION_SHIFT; + va_e >>= ARCH_SECTION_SHIFT; + + if (va_s == 0) + { + return -1; + } + + level = rt_hw_interrupt_disable(); + + for (l1_off = va_s; l1_off <= va_e; l1_off++) + { + size_t v = vtable[l1_off]; + + if (v & ARCH_MMU_USED_MASK) + { + rt_kprintf("Error:vtable[%d] = 0x%p(is not zero),va_s = 0x%p,va_e = 0x%p!\n",l1_off,v,va_s,va_e); + rt_hw_interrupt_enable(level); + return -1; + } + } + + mmu_info->vtable = vtable; + mmu_info->vstart = va_s; + mmu_info->vend = va_e; + mmu_info->pv_off = pv_off; + + rt_hw_interrupt_enable(level); + + return 0; +} + +static size_t find_vaddr(rt_mmu_info *mmu_info, int pages) +{ + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + size_t find_off = 0; + size_t find_va = 0; + int n = 0; + + if (!pages) + { + return 0; + } + + if (!mmu_info) + { + return 0; + } + + for (l1_off = mmu_info->vstart; l1_off <= mmu_info->vend; l1_off++) + { + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + if (*mmu_l1 & ARCH_MMU_USED_MASK) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + for (l2_off = 0; l2_off < (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); l2_off++) + { + if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) + { + /* in use */ + n = 0; + } + else + { + if (!n) + { + find_va = l1_off; + find_off = l2_off; + } + n++; + if (n >= pages) + { + return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT); + } + } + } + } + else + { + if (!n) + { + find_va = l1_off; + find_off = 0; + } + n += (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); + if (n >= pages) + { + return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT); + } + } + } + return 0; +} + +#ifdef RT_USING_USERSPACE +static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages) +{ + size_t loop_va = (size_t)va & ~ARCH_PAGE_MASK; + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + + if (!pages) + { + return -1; + } + + if (!mmu_info) + { + return -1; + } + + while (pages--) + { + l1_off = (loop_va >> ARCH_SECTION_SHIFT); + l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT); + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + + if (*mmu_l1 & ARCH_MMU_USED_MASK) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) + { + return -1; + } + } + loop_va += ARCH_PAGE_SIZE; + } + return 0; +} +#endif + +static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t npages) +{ + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + size_t *ref_cnt; + + if (!mmu_info) + { + return; + } + + while (npages--) + { + l1_off = (loop_va >> ARCH_SECTION_SHIFT); + if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend) + { + return; + } + + l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT); + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + + if (*mmu_l1 & ARCH_MMU_USED_MASK) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + } + else + { + return; + } + + if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) + { + *(mmu_l2 + l2_off) = 0; + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4); + + ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); + (*ref_cnt)--; + if (!*ref_cnt) + { +#ifdef RT_USING_USERSPACE + rt_pages_free(mmu_l2, 0); +#else + rt_free_align(mmu_l2); +#endif + *mmu_l1 = 0; + + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l1, 4); + } + } + loop_va += ARCH_PAGE_SIZE; + } +} + +static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, size_t npages, size_t attr) +{ + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK; + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + size_t *ref_cnt; + + if (!mmu_info) + { + return -1; + } + + while (npages--) + { + l1_off = (loop_va >> ARCH_SECTION_SHIFT); + l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT); + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + + if (*mmu_l1 & ARCH_MMU_USED_MASK) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + } + else + { +#ifdef RT_USING_USERSPACE + mmu_l2 = (size_t*)rt_pages_alloc(0); +#else + mmu_l2 = (size_t*)rt_malloc_align(ARCH_PAGE_TBL_SIZE * 2, ARCH_PAGE_TBL_SIZE); +#endif + if (mmu_l2) + { + rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l2, ARCH_PAGE_TBL_SIZE); + + *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l1, 4); + } + else + { + /* error, unmap and quit */ + __rt_hw_mmu_unmap(mmu_info, v_addr, npages); + return -1; + } + } + + ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); + (*ref_cnt)++; + + *(mmu_l2 + l2_off) = (loop_pa | attr); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4); + + loop_va += ARCH_PAGE_SIZE; + loop_pa += ARCH_PAGE_SIZE; + } + return 0; +} + +static void rt_hw_cpu_tlb_invalidate(void) +{ + mmu_clear_tlb(); + mmu_clear_itlb(); +} + +#ifdef RT_USING_USERSPACE +void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr) +{ + size_t pa_s, pa_e; + size_t vaddr; + int pages; + int ret; + + if (!size) + { + return 0; + } + pa_s = (size_t)p_addr; + pa_e = (size_t)p_addr + size - 1; + pa_s >>= ARCH_PAGE_SHIFT; + pa_e >>= ARCH_PAGE_SHIFT; + pages = pa_e - pa_s + 1; + if (v_addr) + { + vaddr = (size_t)v_addr; + pa_s = (size_t)p_addr; + if ((vaddr & ARCH_PAGE_MASK) != (pa_s & ARCH_PAGE_MASK)) + { + return 0; + } + vaddr &= ~ARCH_PAGE_MASK; + if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0) + { + return 0; + } + } + else + { + vaddr = find_vaddr(mmu_info, pages); + } + if (vaddr) { + ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK)); + } + } + return 0; +} +#else +void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr) +{ + size_t pa_s, pa_e; + size_t vaddr; + int pages; + int ret; + + pa_s = (size_t)p_addr; + pa_e = (size_t)p_addr + size - 1; + pa_s >>= ARCH_PAGE_SHIFT; + pa_e >>= ARCH_PAGE_SHIFT; + pages = pa_e - pa_s + 1; + vaddr = find_vaddr(mmu_info, pages); + if (vaddr) { + ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK)); + } + } + return 0; +} +#endif + +#ifdef RT_USING_USERSPACE +static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void* v_addr, size_t npages, size_t attr) +{ + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + size_t loop_pa; + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + size_t *ref_cnt; + + if (!mmu_info) + { + return -1; + } + + while (npages--) + { + loop_pa = (size_t)rt_pages_alloc(0) + mmu_info->pv_off; + if (!loop_pa) + goto err; + + //rt_kprintf("vaddr = %08x is mapped to paddr = %08x\n",v_addr,loop_pa); + l1_off = (loop_va >> ARCH_SECTION_SHIFT); + l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT); + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + + if (*mmu_l1 & ARCH_MMU_USED_MASK) + { + mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + } + else + { + //mmu_l2 = (size_t*)rt_malloc_align(ARCH_PAGE_TBL_SIZE * 2, ARCH_PAGE_TBL_SIZE); + mmu_l2 = (size_t*)rt_pages_alloc(0); + if (mmu_l2) + { + rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l2, ARCH_PAGE_TBL_SIZE); + + *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l1, 4); + } + else + goto err; + } + + ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); + (*ref_cnt)++; + + //loop_pa += mmu_info->pv_off; + *(mmu_l2 + l2_off) = (loop_pa | attr); + /* cache maintain */ + rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4); + + loop_va += ARCH_PAGE_SIZE; + } + return 0; +err: + { + /* error, unmap and quit */ + int i; + void *va, *pa; + + va = (void*)((size_t)v_addr & ~ARCH_PAGE_MASK); + for (i = 0; i < npages; i++) + { + pa = rt_hw_mmu_v2p(mmu_info, va); + pa -= mmu_info->pv_off; + rt_pages_free(pa, 0); + va += ARCH_PAGE_SIZE; + } + + __rt_hw_mmu_unmap(mmu_info, v_addr, npages); + return -1; + } +} + +void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) +{ + size_t vaddr; + size_t offset; + int pages; + int ret; + + if (!size) + { + return 0; + } + offset = (size_t)v_addr & ARCH_PAGE_MASK; + size += (offset + ARCH_PAGE_SIZE - 1); + pages = (size >> ARCH_PAGE_SHIFT); + if (v_addr) + { + vaddr = (size_t)v_addr; + vaddr &= ~ARCH_PAGE_MASK; + if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0) + { + return 0; + } + } + else + { + vaddr = find_vaddr(mmu_info, pages); + } + if (vaddr) { + ret = __rt_hw_mmu_map_auto(mmu_info, (void*)vaddr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)vaddr + offset; + } + } + return 0; +} +#endif + +void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size) +{ + size_t va_s, va_e; + int pages; + + va_s = (size_t)v_addr; + va_e = (size_t)v_addr + size - 1; + va_s >>= ARCH_PAGE_SHIFT; + va_e >>= ARCH_PAGE_SHIFT; + pages = va_e - va_s + 1; + __rt_hw_mmu_unmap(mmu_info, v_addr, pages); + rt_hw_cpu_tlb_invalidate(); +} + +//va --> pa +void *rt_hw_kernel_virt_to_phys(void *v_addr, size_t size) +{ + void *p_addr = 0; + + return p_addr; +} + +//pa --> va +void *rt_hw_kernel_phys_to_virt(void *p_addr, size_t size) +{ + void *v_addr = 0; + + #ifdef RT_USING_USERSPACE + extern rt_mmu_info mmu_info; + v_addr = rt_hw_mmu_map(&mmu_info, 0, p_addr, size, MMU_MAP_K_RW); + #else + v_addr = p_addr; + #endif + + return v_addr; +} + +#ifdef RT_USING_USERSPACE +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr) +{ + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr); + rt_hw_interrupt_enable(level); + return ret; +} + +void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) +{ + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr); + rt_hw_interrupt_enable(level); + return ret; +} +#endif + +void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size) +{ + rt_base_t level; + + level = rt_hw_interrupt_disable(); + _rt_hw_mmu_unmap(mmu_info, v_addr, size); + rt_hw_interrupt_enable(level); +} + +void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr) +{ + size_t l1_off, l2_off; + size_t *mmu_l1, *mmu_l2; + size_t tmp; + size_t pa; + + l1_off = (size_t)v_addr >> ARCH_SECTION_SHIFT; + + if (!mmu_info) + { + return (void*)0; + } + + mmu_l1 = (size_t*)mmu_info->vtable + l1_off; + + tmp = *mmu_l1; + + switch (tmp & ARCH_MMU_USED_MASK) + { + case 0: /* not used */ + break; + case 1: /* page table */ + mmu_l2 = (size_t *)((tmp & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off); + l2_off = (((size_t)v_addr & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT); + pa = *(mmu_l2 + l2_off); + if (pa & ARCH_MMU_USED_MASK) + { + if ((pa & ARCH_MMU_USED_MASK) == 1) + { + /* lage page, not support */ + break; + } + pa &= ~(ARCH_PAGE_MASK); + pa += ((size_t)v_addr & ARCH_PAGE_MASK); + return (void*)pa; + } + break; + case 2: + case 3: + /* section */ + if (tmp & ARCH_TYPE_SUPERSECTION) + { + /* super section, not support */ + break; + } + pa = (tmp & ~ARCH_SECTION_MASK); + pa += ((size_t)v_addr & ARCH_SECTION_MASK); + return (void*)pa; + } + return (void*)0; +} + +void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr) +{ + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_v2p(mmu_info, v_addr); + rt_hw_interrupt_enable(level); + return ret; +} + +#ifdef RT_USING_USERSPACE +void init_mm_setup(unsigned int *mtbl, unsigned int size, unsigned int pv_off) { + unsigned int va; + + for (va = 0; va < 0x1000; va++) { + unsigned int vaddr = (va << 20); + if (vaddr >= KERNEL_VADDR_START && vaddr - KERNEL_VADDR_START < size) { + mtbl[va] = ((va << 20) + pv_off) | NORMAL_MEM; + } else if (vaddr >= (KERNEL_VADDR_START + pv_off) && vaddr - (KERNEL_VADDR_START + pv_off) < size) { + mtbl[va] = (va << 20) | NORMAL_MEM; + } else { + mtbl[va] = 0; + } + } +} +#endif diff --git a/libcpu/mips/gs264/mmu.h b/libcpu/mips/gs264/mmu.h new file mode 100644 index 0000000000..2472bf975f --- /dev/null +++ b/libcpu/mips/gs264/mmu.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-25 quanzhao the first version + * 2020-07-26 lizhirui porting to ls2k + */ +#ifndef __MMU_H_ +#define __MMU_H_ + +#include <rtthread.h> + +#define DESC_SEC (0x2) +#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */ +#define MEMWB (3<<2) /* write back, no write allocate */ +#define MEMWT (2<<2) /* write through, no write allocate */ +#define SHAREDEVICE (1<<2) /* shared device */ +#define STRONGORDER (0<<2) /* strong ordered */ +#define XN (1<<4) /* execute Never */ +#ifdef RT_USING_USERSPACE +#define AP_RW (1<<10) /* supervisor=RW, user=No */ +#define AP_RO ((1<<10) |(1 << 15)) /* supervisor=RW, user=No */ +#else +#define AP_RW (3<<10) /* supervisor=RW, user=RW */ +#define AP_RO ((2<<10) /* supervisor=RW, user=RO */ +#endif + +#define SHARED (1<<16) /* shareable */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +/* device mapping type */ +#define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC) + +#define STRONG_ORDER_MEM (SHARED|AP_RO|XN|DESC_SEC) + +struct mem_desc +{ + rt_uint32_t vaddr_start; + rt_uint32_t vaddr_end; + rt_uint32_t paddr_start; + rt_uint32_t attr; +}; + +#define MMU_MAP_MTBL_XN (1<<0) +#define MMU_MAP_MTBL_A (1<<1) +#define MMU_MAP_MTBL_B (1<<2) +#define MMU_MAP_MTBL_C (1<<3) +#define MMU_MAP_MTBL_AP01(x) (x<<4) +#define MMU_MAP_MTBL_TEX(x) (x<<6) +#define MMU_MAP_MTBL_AP2(x) (x<<9) +#define MMU_MAP_MTBL_SHARE (1<<10) + +#define MMU_MAP_K_RO (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_RWCB (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_RW (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_K_DEVICE (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RO (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RWCB (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_RW (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE) +#define MMU_MAP_U_DEVICE (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE) + +#define ARCH_SECTION_SHIFT 20 +#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT) +#define ARCH_SECTION_MASK (ARCH_SECTION_SIZE - 1) +#define ARCH_PAGE_SHIFT 14 +#define ARCH_PAGE_SIZE (1 << ARCH_PAGE_SHIFT) +#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1) +#define ARCH_PAGE_TBL_SHIFT 10 +#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT) +#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1) + +#define ARCH_MMU_USED_MASK 3 + +#define ARCH_TYPE_SUPERSECTION (1 << 18) + +typedef struct +{ + size_t *vtable; + size_t vstart; + size_t vend; + size_t pv_off; +} rt_mmu_info; + +void *mmu_table_get(); +void switch_mmu(void *mmu_table); + +int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off); +#ifdef RT_USING_USERSPACE +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr); +void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr); +#else +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr); +#endif +void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size); +void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr); + +void *rt_hw_kernel_phys_to_virt(void *p_addr, size_t size); +void *rt_hw_kernel_virt_to_phys(void *v_addr, size_t size); + +#endif diff --git a/libcpu/mips/pic32/SConscript b/libcpu/mips/pic32/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/mips/pic32/SConscript +++ b/libcpu/mips/pic32/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/nios/nios_ii/SConscript b/libcpu/nios/nios_ii/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/nios/nios_ii/SConscript +++ b/libcpu/nios/nios_ii/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/ppc/common/SConscript b/libcpu/ppc/common/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/ppc/common/SConscript +++ b/libcpu/ppc/common/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/ppc/ppc405/SConscript b/libcpu/ppc/ppc405/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/ppc/ppc405/SConscript +++ b/libcpu/ppc/ppc405/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/SConscript b/libcpu/risc-v/SConscript index 024cc5ba44..dece8b0423 100644 --- a/libcpu/risc-v/SConscript +++ b/libcpu/risc-v/SConscript @@ -10,10 +10,17 @@ group = [] list = os.listdir(cwd) # add common code files -if rtconfig.CPU != "nuclei": - group = group + SConscript(os.path.join('common', 'SConscript')) +if rtconfig.CPU == "e906" : + group = group +elif rtconfig.CPU == "nuclei" : + group = group +else : + group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) +if rtconfig.CPU == "e906" : + group = group + SConscript(os.path.join(cwd, rtconfig.VENDOR, rtconfig.CPU, 'SConscript')) +else : + group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/risc-v/bumblebee/SConscript b/libcpu/risc-v/bumblebee/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/risc-v/bumblebee/SConscript +++ b/libcpu/risc-v/bumblebee/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/common/SConscript b/libcpu/risc-v/common/SConscript index 2f698f530a..92133bfb47 100644 --- a/libcpu/risc-v/common/SConscript +++ b/libcpu/risc-v/common/SConscript @@ -7,6 +7,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/common/context_gcc.S b/libcpu/risc-v/common/context_gcc.S index 5c9f05c4e8..e5fc8536ea 100644 --- a/libcpu/risc-v/common/context_gcc.S +++ b/libcpu/risc-v/common/context_gcc.S @@ -7,6 +7,7 @@ * Date Author Notes * 2018/10/28 Bernard The unify RISC-V porting implementation * 2018/12/27 Jesven Add SMP support + * 2020/11/20 BalanceTWK Add FPU support */ #include "cpuport.h" @@ -47,7 +48,7 @@ rt_hw_context_switch_to: #ifdef RT_USING_SMP mv a0, a1 - jal rt_cpus_lock_status_restore + call rt_cpus_lock_status_restore #endif LOAD a0, 2 * REGBYTES(sp) csrw mstatus, a0 @@ -72,6 +73,43 @@ rt_hw_context_switch: * mstatus.mie -> sp(2) * x(i) -> sp(i-4) */ +#ifdef ARCH_RISCV_FPU + addi sp, sp, -32 * FREGBYTES + + FSTORE f0, 0 * FREGBYTES(sp) + FSTORE f1, 1 * FREGBYTES(sp) + FSTORE f2, 2 * FREGBYTES(sp) + FSTORE f3, 3 * FREGBYTES(sp) + FSTORE f4, 4 * FREGBYTES(sp) + FSTORE f5, 5 * FREGBYTES(sp) + FSTORE f6, 6 * FREGBYTES(sp) + FSTORE f7, 7 * FREGBYTES(sp) + FSTORE f8, 8 * FREGBYTES(sp) + FSTORE f9, 9 * FREGBYTES(sp) + FSTORE f10, 10 * FREGBYTES(sp) + FSTORE f11, 11 * FREGBYTES(sp) + FSTORE f12, 12 * FREGBYTES(sp) + FSTORE f13, 13 * FREGBYTES(sp) + FSTORE f14, 14 * FREGBYTES(sp) + FSTORE f15, 15 * FREGBYTES(sp) + FSTORE f16, 16 * FREGBYTES(sp) + FSTORE f17, 17 * FREGBYTES(sp) + FSTORE f18, 18 * FREGBYTES(sp) + FSTORE f19, 19 * FREGBYTES(sp) + FSTORE f20, 20 * FREGBYTES(sp) + FSTORE f21, 21 * FREGBYTES(sp) + FSTORE f22, 22 * FREGBYTES(sp) + FSTORE f23, 23 * FREGBYTES(sp) + FSTORE f24, 24 * FREGBYTES(sp) + FSTORE f25, 25 * FREGBYTES(sp) + FSTORE f26, 26 * FREGBYTES(sp) + FSTORE f27, 27 * FREGBYTES(sp) + FSTORE f28, 28 * FREGBYTES(sp) + FSTORE f29, 29 * FREGBYTES(sp) + FSTORE f30, 30 * FREGBYTES(sp) + FSTORE f31, 31 * FREGBYTES(sp) + +#endif addi sp, sp, -32 * REGBYTES STORE sp, (a0) @@ -123,7 +161,7 @@ save_mpie: #ifdef RT_USING_SMP mv a0, a2 - jal rt_cpus_lock_status_restore + call rt_cpus_lock_status_restore #endif /*RT_USING_SMP*/ j rt_hw_context_switch_exit @@ -174,7 +212,7 @@ rt_hw_context_switch_exit: LOAD x1, 1 * REGBYTES(sp) - li t0, 0x00001800 + li t0, 0x00007800 csrw mstatus, t0 LOAD a0, 2 * REGBYTES(sp) csrs mstatus, a0 @@ -209,4 +247,42 @@ rt_hw_context_switch_exit: LOAD x31, 31 * REGBYTES(sp) addi sp, sp, 32 * REGBYTES + +#ifdef ARCH_RISCV_FPU + FLOAD f0, 0 * FREGBYTES(sp) + FLOAD f1, 1 * FREGBYTES(sp) + FLOAD f2, 2 * FREGBYTES(sp) + FLOAD f3, 3 * FREGBYTES(sp) + FLOAD f4, 4 * FREGBYTES(sp) + FLOAD f5, 5 * FREGBYTES(sp) + FLOAD f6, 6 * FREGBYTES(sp) + FLOAD f7, 7 * FREGBYTES(sp) + FLOAD f8, 8 * FREGBYTES(sp) + FLOAD f9, 9 * FREGBYTES(sp) + FLOAD f10, 10 * FREGBYTES(sp) + FLOAD f11, 11 * FREGBYTES(sp) + FLOAD f12, 12 * FREGBYTES(sp) + FLOAD f13, 13 * FREGBYTES(sp) + FLOAD f14, 14 * FREGBYTES(sp) + FLOAD f15, 15 * FREGBYTES(sp) + FLOAD f16, 16 * FREGBYTES(sp) + FLOAD f17, 17 * FREGBYTES(sp) + FLOAD f18, 18 * FREGBYTES(sp) + FLOAD f19, 19 * FREGBYTES(sp) + FLOAD f20, 20 * FREGBYTES(sp) + FLOAD f21, 21 * FREGBYTES(sp) + FLOAD f22, 22 * FREGBYTES(sp) + FLOAD f23, 23 * FREGBYTES(sp) + FLOAD f24, 24 * FREGBYTES(sp) + FLOAD f25, 25 * FREGBYTES(sp) + FLOAD f26, 26 * FREGBYTES(sp) + FLOAD f27, 27 * FREGBYTES(sp) + FLOAD f28, 28 * FREGBYTES(sp) + FLOAD f29, 29 * FREGBYTES(sp) + FLOAD f30, 30 * FREGBYTES(sp) + FLOAD f31, 31 * FREGBYTES(sp) + + addi sp, sp, 32 * FREGBYTES +#endif + mret diff --git a/libcpu/risc-v/common/cpuport.c b/libcpu/risc-v/common/cpuport.c index a44dc40f79..6cb8aaf3e7 100644 --- a/libcpu/risc-v/common/cpuport.c +++ b/libcpu/risc-v/common/cpuport.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018/10/28 Bernard The unify RISC-V porting code. + * 2020/11/20 BalanceTWK Add FPU support */ #include <rthw.h> @@ -53,6 +54,40 @@ struct rt_hw_stack_frame rt_ubase_t t4; /* x29 - t4 - temporary register 4 */ rt_ubase_t t5; /* x30 - t5 - temporary register 5 */ rt_ubase_t t6; /* x31 - t6 - temporary register 6 */ +#ifdef ARCH_RISCV_FPU + rv_floatreg_t f0; /* f0 */ + rv_floatreg_t f1; /* f1 */ + rv_floatreg_t f2; /* f2 */ + rv_floatreg_t f3; /* f3 */ + rv_floatreg_t f4; /* f4 */ + rv_floatreg_t f5; /* f5 */ + rv_floatreg_t f6; /* f6 */ + rv_floatreg_t f7; /* f7 */ + rv_floatreg_t f8; /* f8 */ + rv_floatreg_t f9; /* f9 */ + rv_floatreg_t f10; /* f10 */ + rv_floatreg_t f11; /* f11 */ + rv_floatreg_t f12; /* f12 */ + rv_floatreg_t f13; /* f13 */ + rv_floatreg_t f14; /* f14 */ + rv_floatreg_t f15; /* f15 */ + rv_floatreg_t f16; /* f16 */ + rv_floatreg_t f17; /* f17 */ + rv_floatreg_t f18; /* f18 */ + rv_floatreg_t f19; /* f19 */ + rv_floatreg_t f20; /* f20 */ + rv_floatreg_t f21; /* f21 */ + rv_floatreg_t f22; /* f22 */ + rv_floatreg_t f23; /* f23 */ + rv_floatreg_t f24; /* f24 */ + rv_floatreg_t f25; /* f25 */ + rv_floatreg_t f26; /* f26 */ + rv_floatreg_t f27; /* f27 */ + rv_floatreg_t f28; /* f28 */ + rv_floatreg_t f29; /* f29 */ + rv_floatreg_t f30; /* f30 */ + rv_floatreg_t f31; /* f31 */ +#endif }; /** @@ -116,7 +151,7 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to) #endif /* end of RT_USING_SMP */ /** shutdown CPU */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/risc-v/common/cpuport.h b/libcpu/risc-v/common/cpuport.h index 95268732cb..d6cec2f0cf 100644 --- a/libcpu/risc-v/common/cpuport.h +++ b/libcpu/risc-v/common/cpuport.h @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2018-10-03 Bernard The first version + * 2020/11/20 BalanceTWK Add FPU support */ #ifndef CPUPORT_H__ @@ -24,4 +25,19 @@ #define REGBYTES 4 #endif +#ifdef ARCH_RISCV_FPU +#ifdef ARCH_RISCV_FPU_D +#define FSTORE fsd +#define FLOAD fld +#define FREGBYTES 8 +#define rv_floatreg_t rt_int64_t +#endif +#ifdef ARCH_RISCV_FPU_S +#define FSTORE fsw +#define FLOAD flw +#define FREGBYTES 4 +#define rv_floatreg_t rt_int32_t +#endif +#endif + #endif diff --git a/libcpu/risc-v/e310/SConscript b/libcpu/risc-v/e310/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/risc-v/e310/SConscript +++ b/libcpu/risc-v/e310/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/k210/SConscript b/libcpu/risc-v/k210/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/risc-v/k210/SConscript +++ b/libcpu/risc-v/k210/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S index 0393ea51f8..d695d04e4b 100644 --- a/libcpu/risc-v/k210/interrupt_gcc.S +++ b/libcpu/risc-v/k210/interrupt_gcc.S @@ -15,6 +15,43 @@ .align 2 .global trap_entry trap_entry: +#ifdef ARCH_RISCV_FPU + addi sp, sp, -32 * FREGBYTES + + FSTORE f0, 0 * FREGBYTES(sp) + FSTORE f1, 1 * FREGBYTES(sp) + FSTORE f2, 2 * FREGBYTES(sp) + FSTORE f3, 3 * FREGBYTES(sp) + FSTORE f4, 4 * FREGBYTES(sp) + FSTORE f5, 5 * FREGBYTES(sp) + FSTORE f6, 6 * FREGBYTES(sp) + FSTORE f7, 7 * FREGBYTES(sp) + FSTORE f8, 8 * FREGBYTES(sp) + FSTORE f9, 9 * FREGBYTES(sp) + FSTORE f10, 10 * FREGBYTES(sp) + FSTORE f11, 11 * FREGBYTES(sp) + FSTORE f12, 12 * FREGBYTES(sp) + FSTORE f13, 13 * FREGBYTES(sp) + FSTORE f14, 14 * FREGBYTES(sp) + FSTORE f15, 15 * FREGBYTES(sp) + FSTORE f16, 16 * FREGBYTES(sp) + FSTORE f17, 17 * FREGBYTES(sp) + FSTORE f18, 18 * FREGBYTES(sp) + FSTORE f19, 19 * FREGBYTES(sp) + FSTORE f20, 20 * FREGBYTES(sp) + FSTORE f21, 21 * FREGBYTES(sp) + FSTORE f22, 22 * FREGBYTES(sp) + FSTORE f23, 23 * FREGBYTES(sp) + FSTORE f24, 24 * FREGBYTES(sp) + FSTORE f25, 25 * FREGBYTES(sp) + FSTORE f26, 26 * FREGBYTES(sp) + FSTORE f27, 27 * FREGBYTES(sp) + FSTORE f28, 28 * FREGBYTES(sp) + FSTORE f29, 29 * FREGBYTES(sp) + FSTORE f30, 30 * FREGBYTES(sp) + FSTORE f31, 31 * FREGBYTES(sp) + +#endif /* save thread context to thread stack */ addi sp, sp, -32 * REGBYTES @@ -82,7 +119,7 @@ trap_entry: mv sp, s0 mv a0, s0 call rt_scheduler_do_irq_switch - j rt_hw_context_switch_exit + tail rt_hw_context_switch_exit #else @@ -106,4 +143,4 @@ trap_entry: #endif spurious_interrupt: - j rt_hw_context_switch_exit + tail rt_hw_context_switch_exit diff --git a/libcpu/risc-v/k210/startup_gcc.S b/libcpu/risc-v/k210/startup_gcc.S index f5c0d8fa94..f40ab1b6f8 100644 --- a/libcpu/risc-v/k210/startup_gcc.S +++ b/libcpu/risc-v/k210/startup_gcc.S @@ -67,38 +67,38 @@ _start: csrs mstatus, t0 fssr x0 - fmv.d.x f0, x0 - fmv.d.x f1, x0 - fmv.d.x f2, x0 - fmv.d.x f3, x0 - fmv.d.x f4, x0 - fmv.d.x f5, x0 - fmv.d.x f6, x0 - fmv.d.x f7, x0 - fmv.d.x f8, x0 - fmv.d.x f9, x0 - fmv.d.x f10,x0 - fmv.d.x f11,x0 - fmv.d.x f12,x0 - fmv.d.x f13,x0 - fmv.d.x f14,x0 - fmv.d.x f15,x0 - fmv.d.x f16,x0 - fmv.d.x f17,x0 - fmv.d.x f18,x0 - fmv.d.x f19,x0 - fmv.d.x f20,x0 - fmv.d.x f21,x0 - fmv.d.x f22,x0 - fmv.d.x f23,x0 - fmv.d.x f24,x0 - fmv.d.x f25,x0 - fmv.d.x f26,x0 - fmv.d.x f27,x0 - fmv.d.x f28,x0 - fmv.d.x f29,x0 - fmv.d.x f30,x0 - fmv.d.x f31,x0 + fmv.w.x f0, x0 + fmv.w.x f1, x0 + fmv.w.x f2, x0 + fmv.w.x f3, x0 + fmv.w.x f4, x0 + fmv.w.x f5, x0 + fmv.w.x f6, x0 + fmv.w.x f7, x0 + fmv.w.x f8, x0 + fmv.w.x f9, x0 + fmv.w.x f10,x0 + fmv.w.x f11,x0 + fmv.w.x f12,x0 + fmv.w.x f13,x0 + fmv.w.x f14,x0 + fmv.w.x f15,x0 + fmv.w.x f16,x0 + fmv.w.x f17,x0 + fmv.w.x f18,x0 + fmv.w.x f19,x0 + fmv.w.x f20,x0 + fmv.w.x f21,x0 + fmv.w.x f22,x0 + fmv.w.x f23,x0 + fmv.w.x f24,x0 + fmv.w.x f25,x0 + fmv.w.x f26,x0 + fmv.w.x f27,x0 + fmv.w.x f28,x0 + fmv.w.x f29,x0 + fmv.w.x f30,x0 + fmv.w.x f31,x0 .option push .option norelax @@ -116,18 +116,21 @@ _start: /* other cpu core, jump to cpu entry directly */ bnez a0, secondary_cpu_entry - j primary_cpu_entry + tail primary_cpu_entry secondary_cpu_entry: #ifdef RT_USING_SMP la a0, secondary_boot_flag ld a0, 0(a0) li a1, 0xa55a - beq a0, a1, secondary_cpu_c_start + beq a0, a1, 1f #endif j secondary_cpu_entry #ifdef RT_USING_SMP +1: + tail secondary_cpu_c_start + .data .global secondary_boot_flag .align 3 diff --git a/libcpu/risc-v/nuclei/SConscript b/libcpu/risc-v/nuclei/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/risc-v/nuclei/SConscript +++ b/libcpu/risc-v/nuclei/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/nuclei/cpuport.c b/libcpu/risc-v/nuclei/cpuport.c index fad9afdf4c..717e9bb1c7 100644 --- a/libcpu/risc-v/nuclei/cpuport.c +++ b/libcpu/risc-v/nuclei/cpuport.c @@ -19,7 +19,7 @@ #define SYSTICK_TICK_CONST (SOC_TIMER_FREQ / RT_TICK_PER_SECOND) /* Interrupt level for kernel systimer interrupt and software timer interrupt */ -#define RT_KERNEL_INTERRUPT_LEVEL 1 +#define RT_KERNEL_INTERRUPT_LEVEL 0 /* Initial CSR MSTATUS value when thread created */ #define RT_INITIAL_MSTATUS (MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL) @@ -152,7 +152,7 @@ void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to) * @brief shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/risc-v/rv32m1/SConscript b/libcpu/risc-v/rv32m1/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/risc-v/rv32m1/SConscript +++ b/libcpu/risc-v/rv32m1/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/risc-v/t-head/e906/SConscript b/libcpu/risc-v/t-head/e906/SConscript new file mode 100644 index 0000000000..92133bfb47 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/SConscript @@ -0,0 +1,12 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/t-head/e906/context_gcc.S b/libcpu/risc-v/t-head/e906/context_gcc.S new file mode 100644 index 0000000000..2f5223ae63 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/context_gcc.S @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting implementation + */ + +#include "cpuport.h" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + +/* + * Functions: vPortYield + */ +.global vPortYield +.type vPortYield, %function +vPortYield: + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + ret + + + +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread); + * #else + * void rt_hw_context_switch_to(rt_ubase_t to); + * #endif + * a0 --> to + * a1 --> to_thread + */ + .globl rt_hw_context_switch_to +rt_hw_context_switch_to: + /* save a0 to to_thread */ + la t0, rt_interrupt_to_thread + STORE a0, (t0) + + /* save 0 to from_thread */ + la t0, rt_interrupt_from_thread + li t1, 0 + STORE t1, (t0) + + /* set rt_thread_switch_interrupt_flag=1 */ + la t0, rt_thread_switch_interrupt_flag + li t1, 1 + STORE t1, (t0) + + /* enable mexstatus SPUSHEN and SPSWAPEN */ +#if ((CONFIG_CPU_E906==1) || (CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1)) + uint32_t mexstatus; + mexstatus = __get_MEXSTATUS(); + mexstatus |= (0x2 << 16); + __set_MEXSTATUS(mexstatus); +#endif + + csrw mscratch, sp + /* set software interrupt */ + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + /* enable global interrup */ + csrsi mstatus, 8 + + ret + +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * #else + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); + * #endif + * + * a0 --> from + * a1 --> to + * a2 --> to_thread + */ + .globl rt_hw_context_switch +rt_hw_context_switch: + .globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + /* check rt_thread_switch_interrupt_flag */ + la t0, rt_thread_switch_interrupt_flag + lw t1, (t0) + li t2, 1 + beq t1, t2, .reswitch + /* set rt_thread_switch_interrupt_flag=1 */ + STORE t2, (t0) + + /* update from_thread */ + la t0, rt_interrupt_from_thread + STORE a0, (t0) + +.reswitch: + /* update to_thread */ + la t0, rt_interrupt_to_thread + STORE a1, (t0) + /* set software interrupt */ + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + ret + +/* + * PendSV_Handler + */ +.global PendSV_Handler +.type PendSV_Handler, %function +PendSV_Handler: + + /* check rt_thread_switch_interrupt_flag */ + sw t0, (-4)(sp) + sw t1, (-8)(sp) + la t0, rt_thread_switch_interrupt_flag + lw t1, (t0) + beqz t1, .pendsv_exit + + /* clear rt_thread_switch_interrupt_flag */ + li t1, 0x0 + sw t1, (t0) + + /* check rt_interrupt_from_thread */ + la t0, rt_interrupt_from_thread + lw t1, (t0) + beqz t1, .switch_to_thead + + /* save from thread context */ + lw t0, (-4)(sp) + lw t1, (-8)(sp) + +#ifdef ARCH_RISCV_FPU + addi sp, sp, -32 * FREGBYTES + + FSTORE f0, 0 * FREGBYTES(sp) + FSTORE f1, 1 * FREGBYTES(sp) + FSTORE f2, 2 * FREGBYTES(sp) + FSTORE f3, 3 * FREGBYTES(sp) + FSTORE f4, 4 * FREGBYTES(sp) + FSTORE f5, 5 * FREGBYTES(sp) + FSTORE f6, 6 * FREGBYTES(sp) + FSTORE f7, 7 * FREGBYTES(sp) + FSTORE f8, 8 * FREGBYTES(sp) + FSTORE f9, 9 * FREGBYTES(sp) + FSTORE f10, 10 * FREGBYTES(sp) + FSTORE f11, 11 * FREGBYTES(sp) + FSTORE f12, 12 * FREGBYTES(sp) + FSTORE f13, 13 * FREGBYTES(sp) + FSTORE f14, 14 * FREGBYTES(sp) + FSTORE f15, 15 * FREGBYTES(sp) + FSTORE f16, 16 * FREGBYTES(sp) + FSTORE f17, 17 * FREGBYTES(sp) + FSTORE f18, 18 * FREGBYTES(sp) + FSTORE f19, 19 * FREGBYTES(sp) + FSTORE f20, 20 * FREGBYTES(sp) + FSTORE f21, 21 * FREGBYTES(sp) + FSTORE f22, 22 * FREGBYTES(sp) + FSTORE f23, 23 * FREGBYTES(sp) + FSTORE f24, 24 * FREGBYTES(sp) + FSTORE f25, 25 * FREGBYTES(sp) + FSTORE f26, 26 * FREGBYTES(sp) + FSTORE f27, 27 * FREGBYTES(sp) + FSTORE f28, 28 * FREGBYTES(sp) + FSTORE f29, 29 * FREGBYTES(sp) + FSTORE f30, 30 * FREGBYTES(sp) + FSTORE f31, 31 * FREGBYTES(sp) +#endif + + addi sp, sp, -32 * REGBYTES + + STORE x1, 1 * REGBYTES(sp) + csrr x1, mepc + STORE x1, 0 * REGBYTES(sp) + csrr x1, mstatus + andi x1, x1, 8 + beqz x1, .save_mpie + li x1, 0x80 +.save_mpie: + STORE x1, 2 * REGBYTES(sp) + /* x3 don't need save */ + STORE x4, 4 * REGBYTES(sp) + STORE x5, 5 * REGBYTES(sp) + STORE x6, 6 * REGBYTES(sp) + STORE x7, 7 * REGBYTES(sp) + STORE x8, 8 * REGBYTES(sp) + STORE x9, 9 * REGBYTES(sp) + STORE x10, 10 * REGBYTES(sp) + STORE x11, 11 * REGBYTES(sp) + STORE x12, 12 * REGBYTES(sp) + STORE x13, 13 * REGBYTES(sp) + STORE x14, 14 * REGBYTES(sp) + STORE x15, 15 * REGBYTES(sp) + STORE x16, 16 * REGBYTES(sp) + STORE x17, 17 * REGBYTES(sp) + STORE x18, 18 * REGBYTES(sp) + STORE x19, 19 * REGBYTES(sp) + STORE x20, 20 * REGBYTES(sp) + STORE x21, 21 * REGBYTES(sp) + STORE x22, 22 * REGBYTES(sp) + STORE x23, 23 * REGBYTES(sp) + STORE x24, 24 * REGBYTES(sp) + STORE x25, 25 * REGBYTES(sp) + STORE x26, 26 * REGBYTES(sp) + STORE x27, 27 * REGBYTES(sp) + STORE x28, 28 * REGBYTES(sp) + STORE x29, 29 * REGBYTES(sp) + STORE x30, 30 * REGBYTES(sp) + STORE x31, 31 * REGBYTES(sp) + + /* store from_thread sp */ + la t0, rt_interrupt_from_thread + lw t0, (t0) + sw sp, (t0) + +.switch_to_thead: + /* restore to thread context + * sp(0) -> epc; + * sp(1) -> ra; + * sp(i) -> x(i+2) + */ + la t0, rt_interrupt_to_thread + lw t0, (t0) + LOAD sp, (t0) + + /* restore ra to mepc */ + LOAD a1, 0 * REGBYTES(sp) + csrw mepc, a1 + LOAD x1, 1 * REGBYTES(sp) + + /* force to machin mode(MPP=11) */ + li a1, 0x1880 + csrs mstatus, a1 + LOAD a1, 2 * REGBYTES(sp) + csrs mstatus, a1 + /* x3 don't need restore */ + LOAD x4, 4 * REGBYTES(sp) + LOAD x5, 5 * REGBYTES(sp) + LOAD x6, 6 * REGBYTES(sp) + LOAD x7, 7 * REGBYTES(sp) + LOAD x8, 8 * REGBYTES(sp) + LOAD x9, 9 * REGBYTES(sp) + LOAD x10, 10 * REGBYTES(sp) + LOAD x11, 11 * REGBYTES(sp) + LOAD x12, 12 * REGBYTES(sp) + LOAD x13, 13 * REGBYTES(sp) + LOAD x14, 14 * REGBYTES(sp) + LOAD x15, 15 * REGBYTES(sp) + LOAD x16, 16 * REGBYTES(sp) + LOAD x17, 17 * REGBYTES(sp) + LOAD x18, 18 * REGBYTES(sp) + LOAD x19, 19 * REGBYTES(sp) + LOAD x20, 20 * REGBYTES(sp) + LOAD x21, 21 * REGBYTES(sp) + LOAD x22, 22 * REGBYTES(sp) + LOAD x23, 23 * REGBYTES(sp) + LOAD x24, 24 * REGBYTES(sp) + LOAD x25, 25 * REGBYTES(sp) + LOAD x26, 26 * REGBYTES(sp) + LOAD x27, 27 * REGBYTES(sp) + LOAD x28, 28 * REGBYTES(sp) + LOAD x29, 29 * REGBYTES(sp) + LOAD x30, 30 * REGBYTES(sp) + LOAD x31, 31 * REGBYTES(sp) + + addi sp, sp, 32 * REGBYTES + +#ifdef ARCH_RISCV_FPU + FLOAD f0, 0 * FREGBYTES(sp) + FLOAD f1, 1 * FREGBYTES(sp) + FLOAD f2, 2 * FREGBYTES(sp) + FLOAD f3, 3 * FREGBYTES(sp) + FLOAD f4, 4 * FREGBYTES(sp) + FLOAD f5, 5 * FREGBYTES(sp) + FLOAD f6, 6 * FREGBYTES(sp) + FLOAD f7, 7 * FREGBYTES(sp) + FLOAD f8, 8 * FREGBYTES(sp) + FLOAD f9, 9 * FREGBYTES(sp) + FLOAD f10, 10 * FREGBYTES(sp) + FLOAD f11, 11 * FREGBYTES(sp) + FLOAD f12, 12 * FREGBYTES(sp) + FLOAD f13, 13 * FREGBYTES(sp) + FLOAD f14, 14 * FREGBYTES(sp) + FLOAD f15, 15 * FREGBYTES(sp) + FLOAD f16, 16 * FREGBYTES(sp) + FLOAD f17, 17 * FREGBYTES(sp) + FLOAD f18, 18 * FREGBYTES(sp) + FLOAD f19, 19 * FREGBYTES(sp) + FLOAD f20, 20 * FREGBYTES(sp) + FLOAD f21, 21 * FREGBYTES(sp) + FLOAD f22, 22 * FREGBYTES(sp) + FLOAD f23, 23 * FREGBYTES(sp) + FLOAD f24, 24 * FREGBYTES(sp) + FLOAD f25, 25 * FREGBYTES(sp) + FLOAD f26, 26 * FREGBYTES(sp) + FLOAD f27, 27 * FREGBYTES(sp) + FLOAD f28, 28 * FREGBYTES(sp) + FLOAD f29, 29 * FREGBYTES(sp) + FLOAD f30, 30 * FREGBYTES(sp) + FLOAD f31, 31 * FREGBYTES(sp) + + addi sp, sp, 32 * FREGBYTES +#endif + +.pendsv_exit: + mret + + + diff --git a/libcpu/risc-v/t-head/e906/cpuport.c b/libcpu/risc-v/t-head/e906/cpuport.c new file mode 100644 index 0000000000..998bfdc340 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/cpuport.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting code. + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "cpuport.h" + +#ifndef RT_USING_SMP +volatile rt_ubase_t rt_interrupt_from_thread = 0; +volatile rt_ubase_t rt_interrupt_to_thread = 0; +volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0; +#endif + +struct rt_hw_stack_frame +{ + rt_ubase_t epc; /* epc - epc - program counter */ + rt_ubase_t ra; /* x1 - ra - return address for jumps */ + rt_ubase_t mstatus; /* - machine status register */ + rt_ubase_t gp; /* x3 - gp - global pointer */ + rt_ubase_t tp; /* x4 - tp - thread pointer */ + rt_ubase_t t0; /* x5 - t0 - temporary register 0 */ + rt_ubase_t t1; /* x6 - t1 - temporary register 1 */ + rt_ubase_t t2; /* x7 - t2 - temporary register 2 */ + rt_ubase_t s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */ + rt_ubase_t s1; /* x9 - s1 - saved register 1 */ + rt_ubase_t a0; /* x10 - a0 - return value or function argument 0 */ + rt_ubase_t a1; /* x11 - a1 - return value or function argument 1 */ + rt_ubase_t a2; /* x12 - a2 - function argument 2 */ + rt_ubase_t a3; /* x13 - a3 - function argument 3 */ + rt_ubase_t a4; /* x14 - a4 - function argument 4 */ + rt_ubase_t a5; /* x15 - a5 - function argument 5 */ + rt_ubase_t a6; /* x16 - a6 - function argument 6 */ + rt_ubase_t a7; /* x17 - s7 - function argument 7 */ + rt_ubase_t s2; /* x18 - s2 - saved register 2 */ + rt_ubase_t s3; /* x19 - s3 - saved register 3 */ + rt_ubase_t s4; /* x20 - s4 - saved register 4 */ + rt_ubase_t s5; /* x21 - s5 - saved register 5 */ + rt_ubase_t s6; /* x22 - s6 - saved register 6 */ + rt_ubase_t s7; /* x23 - s7 - saved register 7 */ + rt_ubase_t s8; /* x24 - s8 - saved register 8 */ + rt_ubase_t s9; /* x25 - s9 - saved register 9 */ + rt_ubase_t s10; /* x26 - s10 - saved register 10 */ + rt_ubase_t s11; /* x27 - s11 - saved register 11 */ + rt_ubase_t t3; /* x28 - t3 - temporary register 3 */ + rt_ubase_t t4; /* x29 - t4 - temporary register 4 */ + rt_ubase_t t5; /* x30 - t5 - temporary register 5 */ + rt_ubase_t t6; /* x31 - t6 - temporary register 6 */ +#ifdef ARCH_RISCV_FPU + rv_floatreg_t f0; /* f0 */ + rv_floatreg_t f1; /* f1 */ + rv_floatreg_t f2; /* f2 */ + rv_floatreg_t f3; /* f3 */ + rv_floatreg_t f4; /* f4 */ + rv_floatreg_t f5; /* f5 */ + rv_floatreg_t f6; /* f6 */ + rv_floatreg_t f7; /* f7 */ + rv_floatreg_t f8; /* f8 */ + rv_floatreg_t f9; /* f9 */ + rv_floatreg_t f10; /* f10 */ + rv_floatreg_t f11; /* f11 */ + rv_floatreg_t f12; /* f12 */ + rv_floatreg_t f13; /* f13 */ + rv_floatreg_t f14; /* f14 */ + rv_floatreg_t f15; /* f15 */ + rv_floatreg_t f16; /* f16 */ + rv_floatreg_t f17; /* f17 */ + rv_floatreg_t f18; /* f18 */ + rv_floatreg_t f19; /* f19 */ + rv_floatreg_t f20; /* f20 */ + rv_floatreg_t f21; /* f21 */ + rv_floatreg_t f22; /* f22 */ + rv_floatreg_t f23; /* f23 */ + rv_floatreg_t f24; /* f24 */ + rv_floatreg_t f25; /* f25 */ + rv_floatreg_t f26; /* f26 */ + rv_floatreg_t f27; /* f27 */ + rv_floatreg_t f28; /* f28 */ + rv_floatreg_t f29; /* f29 */ + rv_floatreg_t f30; /* f30 */ + rv_floatreg_t f31; /* f31 */ +#endif +}; + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, + rt_uint8_t *stack_addr, + void *texit) +{ + struct rt_hw_stack_frame *frame; + rt_uint8_t *stk; + int i; + + stk = stack_addr + sizeof(rt_ubase_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES); + stk -= sizeof(struct rt_hw_stack_frame); + + frame = (struct rt_hw_stack_frame *)stk; + + for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++) + { + ((rt_ubase_t *)frame)[i] = 0xdeadbeef; + } + + frame->ra = (rt_ubase_t)texit; + frame->a0 = (rt_ubase_t)parameter; + frame->epc = (rt_ubase_t)tentry; + + /* force to machine mode(MPP=11) and set MPIE to 1 */ + frame->mstatus = 0x00007880; + + return stk; +} + + +/** + * This function will disable global interrupt + * + * @param none + * + * @return zero + */ + +rt_base_t rt_hw_interrupt_disable(void) +{ + __asm volatile("csrc mstatus, 8"); + return 0; +} + +/** + * This function will ennable global interrupt + * + * @param level not used + * + * @return none + */ +void rt_hw_interrupt_enable(rt_base_t level) +{ + __asm volatile("csrs mstatus, 8"); +} + +/** shutdown CPU */ +RT_WEAK void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} diff --git a/libcpu/risc-v/t-head/e906/cpuport.h b/libcpu/risc-v/t-head/e906/cpuport.h new file mode 100644 index 0000000000..90efc07653 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/cpuport.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-08-20 zx.chen The first version + */ + +#ifndef CPUPORT_H__ +#define CPUPORT_H__ + +#include <rtconfig.h> + +/* bytes of register width */ +#ifdef ARCH_RISCV_64 +#define DFSTORE fsd +#define DFLOAD fld +#define SFSTORE fsw +#define SFLOAD flw +#define STORE sd +#define LOAD ld +#define REGBYTES 8 +#define SFREGBYTES 4 +#define DFREGBYTES 8 +#else +#define DFSTORE fsd +#define DFLOAD fld +#define SFSTORE fsw +#define SFLOAD flw +#define STORE sw +#define LOAD lw + +#define REGBYTES 4 +#define SFREGBYTES 4 +#define DFREGBYTES 8 +#endif + +#ifdef ARCH_RISCV_FPU +#ifdef ARCH_RISCV_FPU_D +#define FSTORE fsd +#define FLOAD fld +#define FREGBYTES 8 +#define rv_floatreg_t rt_int64_t +#endif +#ifdef ARCH_RISCV_FPU_S +#define FSTORE fsw +#define FLOAD flw +#define FREGBYTES 4 +#define rv_floatreg_t rt_int32_t +#endif +#endif + +#endif diff --git a/libcpu/rx/SConscript b/libcpu/rx/SConscript index e5890498c9..b7cb2f445a 100644 --- a/libcpu/rx/SConscript +++ b/libcpu/rx/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_iar.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/rx/cpuport.c b/libcpu/rx/cpuport.c index 681c0e8e6e..a01f598e99 100644 --- a/libcpu/rx/cpuport.c +++ b/libcpu/rx/cpuport.c @@ -182,7 +182,7 @@ void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to) * * @author LXZ (2014/11/8) */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); diff --git a/libcpu/sim/posix/SConscript b/libcpu/sim/posix/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/sim/posix/SConscript +++ b/libcpu/sim/posix/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/sim/win32/SConscript b/libcpu/sim/win32/SConscript index afab42d47c..530b5d1d78 100644 --- a/libcpu/sim/win32/SConscript +++ b/libcpu/sim/win32/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/sim/win32/cpu_port.c b/libcpu/sim/win32/cpu_port.c index 6bf3c79cf7..cc8ad9a25c 100644 --- a/libcpu/sim/win32/cpu_port.c +++ b/libcpu/sim/win32/cpu_port.c @@ -27,6 +27,8 @@ * The context switch is managed by the threads.So the task stack does not have to be managed directly, * although the stack stack is still used to hold an WinThreadState structure this is the only thing it * will be ever hold. +* YieldEvent used to make sure the thread does not execute before asynchronous SuspendThread() operation +* actually being performed. * the structure indirectly maps the task handle to a thread handle ********************************************************************************************************* */ @@ -35,6 +37,7 @@ typedef struct void *Param; //Thread param void (*Entry)(void *); //Thread entry void (*Exit)(void); //Thread exit + HANDLE YieldEvent; HANDLE ThreadHandle; DWORD ThreadID; }win_thread_t; @@ -171,6 +174,11 @@ rt_uint8_t* rt_hw_stack_init(void *pEntry,void *pParam,rt_uint8_t *pStackAddr,vo pWinThread->ThreadHandle = NULL; pWinThread->ThreadID = 0; + pWinThread->YieldEvent = CreateEvent(NULL, + FALSE, + FALSE, + NULL); + /* Create the winthread */ pWinThread->ThreadHandle = CreateThread(NULL, 0, @@ -277,6 +285,19 @@ void rt_hw_context_switch(rt_uint32_t from, //trigger YIELD exception(cause contex switch) TriggerSimulateInterrupt(CPU_INTERRUPT_YIELD); + // make sure the event is not already signaled + win_thread_t *WinThread = (win_thread_t *)rt_interrupt_from_thread; + ResetEvent(WinThread->YieldEvent); + + /* + * enable interrupt in advance so that scheduler can be executed.please note that interrupt + * maybe disable twice before. + */ + rt_hw_interrupt_enable(0); + rt_hw_interrupt_enable(0); + + // wait to suspend. + WaitForSingleObject(WinThread->YieldEvent, INFINITE); } /*** rt_hw_context_switch ***/ /* @@ -578,6 +599,7 @@ void RegisterSimulateInterrupt(rt_uint32_t IntIndex,rt_uint32_t (*IntHandler)(vo if ((WinThreadFrom != NULL) && (WinThreadFrom->ThreadHandle != NULL)) { SuspendThread(WinThreadFrom->ThreadHandle); + SetEvent(WinThreadFrom->YieldEvent); } ResumeThread(WinThreadTo->ThreadHandle); diff --git a/libcpu/sim/win32/cpu_port.h b/libcpu/sim/win32/cpu_port.h index 8ab8ae23bd..cccdd48d42 100644 --- a/libcpu/sim/win32/cpu_port.h +++ b/libcpu/sim/win32/cpu_port.h @@ -17,8 +17,8 @@ * CPU INTERRUPT PRIORITY ********************************************************************************************************* */ -#define CPU_INTERRUPT_YIELD 0x00 -#define CPU_INTERRUPT_TICK 0x01 +#define CPU_INTERRUPT_YIELD 0x01 // should be set to the lowest priority. +#define CPU_INTERRUPT_TICK 0x00 diff --git a/libcpu/sparc-v8/SConscript b/libcpu/sparc-v8/SConscript new file mode 100644 index 0000000000..f6ea13fb91 --- /dev/null +++ b/libcpu/sparc-v8/SConscript @@ -0,0 +1,16 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() + +# add common code files +group = SConscript(os.path.join('common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/sparc-v8/bm3803/SConscript b/libcpu/sparc-v8/bm3803/SConscript new file mode 100644 index 0000000000..03ce583dc1 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/sparc-v8/bm3803/bm3803.h b/libcpu/sparc-v8/bm3803/bm3803.h new file mode 100644 index 0000000000..17a9882eb2 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/bm3803.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#ifndef __BM3803_H__ +#define __BM3803_H__ + +struct lregs +{ + /* address = 0x80000000 */ + unsigned int memcfg1; /* 0x00 */ + unsigned int memcfg2; + unsigned int memcfg3; + unsigned int failaddr; + + unsigned int memstatus; /* 0x10 */ + unsigned int cachectrl; + unsigned int powerdown; + unsigned int writeprot1; + + unsigned int writeprot2; /* 0x20 */ + unsigned int pcr; + unsigned int dummy2; + unsigned int dummy3; + + unsigned int dummy4; /* 0x30 */ + unsigned int dummy5; + unsigned int dummy6; + unsigned int dummy7; + + unsigned int timercnt1; /* 0x40 */ + unsigned int timerload1; + unsigned int timerctrl1; + unsigned int wdog; + + unsigned int timercnt2; /* 0x50 */ + unsigned int timerload2; + unsigned int timerctrl2; + unsigned int dummy8; + + unsigned int scalercnt; /* 0x60 */ + unsigned int scalerload; + unsigned int dummy9; + unsigned int dummy10; + + unsigned int uartdata1; /* 0x70 */ + unsigned int uartstatus1; + unsigned int uartctrl1; + unsigned int uartscaler1; + + unsigned int uartdata2; /* 0x80 */ + unsigned int uartstatus2; + unsigned int uartctrl2; + unsigned int uartscaler2; + + unsigned int irqmask; /* 0x90 */ + unsigned int irqpend; + unsigned int irqforce; + unsigned int irqclear; + + unsigned int piodata; /* 0xA0 */ + unsigned int piodir; + unsigned int pioirq; + unsigned int dummy11; + + unsigned int imask2; /* 0xB0 */ + unsigned int ipend2; + unsigned int istat2; + unsigned int dummy12; + + unsigned int dummy13; /* 0xC0 */ + unsigned int dcomstatus; + unsigned int dcomctrl; + unsigned int dcomscaler; + + unsigned int dummy14; /* 0xD0 */ + unsigned int dummy15; + unsigned int dummy16; + unsigned int dummy17; + + unsigned int uartdata3; /* 0xE0 */ + unsigned int uartstatus3; + unsigned int uartctrl3; + unsigned int uartscaler3; +}; + +#define PREGS 0x80000000 + +#define UART1_BASE (PREGS + 0x70) + +#define TIMER2_TT 0x19 +#define UART1_TT 0x13 + +#endif diff --git a/libcpu/sparc-v8/bm3803/context_gcc.S b/libcpu/sparc-v8/bm3803/context_gcc.S new file mode 100644 index 0000000000..c0344a81d5 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/context_gcc.S @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define SPARC_PSR_PIL_MASK 0x00000F00 +#define SPARC_PSR_ET_MASK 0x00000020 + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mov %psr, %o0 + or %o0, SPARC_PSR_PIL_MASK, %o1 + mov %o1, %psr + nop + nop + nop + retl + nop + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + mov %o0, %psr + nop + nop + nop + retl + nop + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * o0 --> from + * o1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + ta 2 + retl + nop + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * o0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + mov %o0, %o1 + ta 3 + retl + nop + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + set rt_thread_switch_interrupt_flag, %o2 + ld [%o2], %o3 + cmp %o3, 1 + be _reswitch + nop + mov 1, %o3 + st %o3, [%o2] + set rt_interrupt_from_thread, %o2 + st %o0, [%o2] +_reswitch: + set rt_interrupt_to_thread, %o2 + st %o1, [%o2] + retl + nop diff --git a/libcpu/sparc-v8/bm3803/interrupt.c b/libcpu/sparc-v8/bm3803/interrupt.c new file mode 100644 index 0000000000..b3625862b4 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/interrupt.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "bm3803.h" +#include "interrupt.h" + +#define MAX_HANDLERS 256 + +extern volatile rt_uint8_t rt_interrupt_nest; +struct rt_irq_desc isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + if (vector > 0x1F || vector < 0x11) + return; + volatile struct lregs *regs = (struct lregs *)PREGS; + regs->irqmask &= ~(1 << (vector - 0x10)); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector > 0x1F || vector < 0x11) + return; + volatile struct lregs *regs = (struct lregs *)PREGS; + regs->irqmask |= 1 << (vector - 0x10); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS || vector >= 0) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +void rt_hw_interrupt_clear(int vector) +{ + if (vector > 0x1F || vector < 0x11) + return; + volatile struct lregs *regs = (struct lregs *)PREGS; + regs->irqclear |= 1 << (vector - 0x10); +} diff --git a/libcpu/sparc-v8/bm3803/interrupt.h b/libcpu/sparc-v8/bm3803/interrupt.h new file mode 100644 index 0000000000..666d5268f5 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/interrupt.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + * 2020-10-21 Dystopia Add new function + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +void rt_hw_interrupt_clear(int vector); + +#endif diff --git a/libcpu/sparc-v8/bm3803/stack.c b/libcpu/sparc-v8/bm3803/stack.c new file mode 100644 index 0000000000..2fdc37b539 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/stack.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#include <rtthread.h> + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + int window_index; + int register_index; + + 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 -= 24; + stk -= 8; + + for (register_index = 0; register_index != 8; register_index++) + stk[register_index] = 0xdeadbeef; + + for (window_index = 0; window_index != 8; window_index++) + { + stk -= 16; + for (register_index = 0; register_index != 16; register_index++) + stk[register_index] = 0xdeadbeef; + if (window_index == 0) + { + stk[8] = (rt_uint32_t)parameter; + stk[15] = (rt_uint32_t)texit - 8; + } + } + + stk -= 34; + for (register_index = 0; register_index != 34; register_index++) + stk[register_index] = 0; + + stk -= 4; + stk[0] = (rt_uint32_t)tentry; //pc + stk[1] = (rt_uint32_t)tentry + 4; //npc + stk[2] = 0x10C7; //psr + stk[3] = 0x2; //wim + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} diff --git a/libcpu/sparc-v8/bm3803/start_gcc.S b/libcpu/sparc-v8/bm3803/start_gcc.S new file mode 100644 index 0000000000..0f87aa17db --- /dev/null +++ b/libcpu/sparc-v8/bm3803/start_gcc.S @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define PSR_INIT 0x10C0 +#define PREGS 0x80000000 +#define IMASK 0x90 +#define ICLEAR 0x9c +#define NWINDOWS 8 +#define CPU_INTERRUPT_FRAME_SIZE (0x60 + 0x50 + 34 * 4) +#define SPARC_PSR_PIL_MASK 0x00000F00 +#define SPARC_PSR_ET_MASK 0x00000020 +#define SPARC_PSR_CWP_MASK 0x07 + +.text + +.globl system_vectors +.globl _reset +.globl _context_switch + +_reset: + mov %g0, %asr16 + mov %g0, %asr17 + nop + nop + nop + + set PSR_INIT, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %wim + nop + nop + nop + + mov %g0, %g1 + mov %g0, %g2 + mov %g0, %g3 + mov %g0, %g4 + mov %g0, %g5 + mov %g0, %g6 + mov %g0, %g7 + + mov 0x8, %g1 +1: + mov %g0, %l0 + mov %g0, %l1 + mov %g0, %l2 + mov %g0, %l3 + mov %g0, %l4 + mov %g0, %l5 + mov %g0, %l6 + mov %g0, %l7 + mov %g0, %i0 + mov %g0, %i1 + mov %g0, %i2 + mov %g0, %i3 + mov %g0, %i4 + mov %g0, %i5 + mov %g0, %i6 + mov %g0, %i7 + subcc %g1, 1, %g1 + save + bne 1b + nop + + set 2, %g1 + mov %g1, %wim + nop + nop + nop + + sethi %hi(system_vectors), %g1 + mov %g1, %tbr + nop + nop + nop + + set PREGS, %g1 + set 0xffff, %g2 + st %g2, [%g1 + ICLEAR] + st %g0, [%g1 + IMASK] + + set 0x7C47907F, %g2 + st %g2, [%g1 + 4] + + set PSR_INIT | 0x20, %g1 + mov %g1, %psr + nop + nop + nop + + set _fsrinit, %g1 + ld [%g1], %fsr + nop + nop + nop + + set _fpdata, %g1 + ldd [%g1], %f0 + ldd [%g1], %f2 + ldd [%g1], %f4 + ldd [%g1], %f6 + ldd [%g1], %f8 + ldd [%g1], %f10 + ldd [%g1], %f12 + ldd [%g1], %f14 + ldd [%g1], %f16 + ldd [%g1], %f18 + ldd [%g1], %f20 + ldd [%g1], %f22 + ldd [%g1], %f24 + ldd [%g1], %f26 + ldd [%g1], %f28 + ldd [%g1], %f30 + + set __bss_start, %g2 + set __bss_end, %g3 + mov %g0, %g1 +bss_loop: + std %g0, [%g2] + add %g2, 8, %g2 + cmp %g2, %g3 + bleu,a bss_loop + nop + + set 0x401FFF00, %g1 + mov %g1, %sp + + /* start RT-Thread Kernel */ + call rtthread_startup + nop + +/* +l0 = psr +l1 = pc +l2 = npc +l3 = tbr +*/ +.globl _ISR_Handler +_ISR_Handler: + mov %g4, %l4 + mov %g5, %l5 + mov %wim, %g4 + srl %g4, %l0, %g5 + cmp %g5, 1 + bne dont_do_the_window + nop + srl %g4, 1, %g5 + sll %g4, NWINDOWS - 1, %g4 + or %g4, %g5, %g4 + save + mov %g4, %wim + nop + nop + nop + + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + + restore + nop + +dont_do_the_window: + sub %fp, CPU_INTERRUPT_FRAME_SIZE, %sp + + std %l0, [%sp + 0x60] + st %l2, [%sp + 0x68] + st %g1, [%sp + 0x6c] + std %g2, [%sp + 0x70] + std %l4, [%sp + 0x78] + std %g6, [%sp + 0x80] + + std %i0, [%sp + 0x88] + std %i2, [%sp + 0x90] + std %i4, [%sp + 0x98] + std %i6, [%sp + 0xA0] + + mov %y, %g1 + st %g1, [%sp + 0xA8] + st %l6, [%sp + 0xAc] + + std %f0, [%sp + 0xB0 + 8 * 0x0] + std %f2, [%sp + 0xB0 + 8 * 0x1] + std %f4, [%sp + 0xB0 + 8 * 0x2] + std %f6, [%sp + 0xB0 + 8 * 0x3] + std %f8, [%sp + 0xB0 + 8 * 0x4] + std %f10, [%sp + 0xB0 + 8 * 0x5] + std %f12, [%sp + 0xB0 + 8 * 0x6] + std %f14, [%sp + 0xB0 + 8 * 0x7] + std %f16, [%sp + 0xB0 + 8 * 0x8] + std %f18, [%sp + 0xB0 + 8 * 0x9] + std %f20, [%sp + 0xB0 + 8 * 0xA] + std %f22, [%sp + 0xB0 + 8 * 0xB] + std %f24, [%sp + 0xB0 + 8 * 0xC] + std %f26, [%sp + 0xB0 + 8 * 0xD] + std %f28, [%sp + 0xB0 + 8 * 0xE] + std %f30, [%sp + 0xB0 + 8 * 0xF] + st %fsr, [%sp + 0xB0 + 8 * 0x10] + + mov %l0, %g5 + or %g5, SPARC_PSR_PIL_MASK, %g5 + wr %g5, SPARC_PSR_ET_MASK, %psr + nop + nop + nop + + call rt_interrupt_enter + nop + + and %l3, 0x0FF0, %l3 + srl %l3, 4, %o0 + mov %sp, %o1 + + call rt_hw_trap + nop + + call rt_interrupt_leave + nop + + mov %l0, %psr + nop + nop + nop + + ld [%sp + 0xA8], %l5 + mov %l5, %y + ldd [%sp + 0x60], %l0 + ld [%sp + 0x68], %l2 + + ld [%sp + 0x6c], %g1 + ldd [%sp + 0x70], %g2 + ldd [%sp + 0x78], %g4 + ldd [%sp + 0x80], %g6 + + ldd [%sp + 0x88], %i0 + ldd [%sp + 0x90], %i2 + ldd [%sp + 0x98], %i4 + ldd [%sp + 0xA0], %i6 + + ldd [%sp + 0xB0 + 8 * 0x0], %f0 + ldd [%sp + 0xB0 + 8 * 0x1], %f2 + ldd [%sp + 0xB0 + 8 * 0x2], %f4 + ldd [%sp + 0xB0 + 8 * 0x3], %f6 + ldd [%sp + 0xB0 + 8 * 0x4], %f8 + ldd [%sp + 0xB0 + 8 * 0x5], %f10 + ldd [%sp + 0xB0 + 8 * 0x6], %f12 + ldd [%sp + 0xB0 + 8 * 0x7], %f14 + ldd [%sp + 0xB0 + 8 * 0x8], %f16 + ldd [%sp + 0xB0 + 8 * 0x9], %f18 + ldd [%sp + 0xB0 + 8 * 0xA], %f20 + ldd [%sp + 0xB0 + 8 * 0xB], %f22 + ldd [%sp + 0xB0 + 8 * 0xC], %f24 + ldd [%sp + 0xB0 + 8 * 0xD], %f26 + ldd [%sp + 0xB0 + 8 * 0xE], %f28 + ldd [%sp + 0xB0 + 8 * 0xF], %f30 + ld [%sp + 0xB0 + 8 * 0x10], %fsr + nop + nop + nop + + mov %wim, %l4 + add %l0, 1, %l6 + and %l6, SPARC_PSR_CWP_MASK, %l6 + srl %l4, %l6, %l5 + cmp %l5, 1 + bne good_task_window + nop + sll %l4, 1, %l5 + srl %l4, NWINDOWS - 1, %l4 + or %l4, %l5, %l4 + mov %l4, %wim + nop + nop + nop + + restore + ldd [%sp + 0], %l0 ! Restore window from the stack + ldd [%sp + 8], %l2 + ldd [%sp + 16], %l4 + ldd [%sp + 24], %l6 + ldd [%sp + 32], %i0 + ldd [%sp + 40], %i2 + ldd [%sp + 48], %i4 + ldd [%sp + 56], %i6 + save + +good_task_window: + set rt_thread_switch_interrupt_flag, %l4 + ld [%l4], %l5 + cmp %l5, 1 + be rt_hw_context_switch_interrupt_do + nop + + mov %l0, %psr + nop + nop + nop + + jmp %l1 + rett %l2 + +rt_hw_context_switch_interrupt_do: + st %g0, [%l4] + + sub %fp, 0x20, %sp + std %g0, [%sp + 0x00] + std %g2, [%sp + 0x08] + std %g4, [%sp + 0x10] + std %g6, [%sp + 0x18] + + mov %sp, %g3 + mov %l1, %g4 + mov %l2, %g5 + mov %l0, %g6 + mov %wim, %g7 + + mov %g0, %wim + nop + nop + nop + set 0xFFFFFFF8, %g1 + and %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +save_loop: + save + sub %g3, 0x40, %g3 + std %l0, [%g3 + 0x00] + std %l2, [%g3 + 0x08] + std %l4, [%g3 + 0x10] + std %l6, [%g3 + 0x18] + std %i0, [%g3 + 0x20] + std %i2, [%g3 + 0x28] + std %i4, [%g3 + 0x30] + std %i6, [%g3 + 0x38] + inc %g1 + cmp %g1, NWINDOWS + bne save_loop + nop + + sub %g3, 0x88, %g3 + std %f0, [%g3 + 0x00] + std %f2, [%g3 + 0x08] + std %f4, [%g3 + 0x10] + std %f6, [%g3 + 0x18] + std %f8, [%g3 + 0x20] + std %f10, [%g3 + 0x28] + std %f12, [%g3 + 0x30] + std %f14, [%g3 + 0x38] + std %f16, [%g3 + 0x40] + std %f18, [%g3 + 0x48] + std %f20, [%g3 + 0x50] + std %f22, [%g3 + 0x58] + std %f24, [%g3 + 0x60] + std %f26, [%g3 + 0x68] + std %f28, [%g3 + 0x70] + std %f30, [%g3 + 0x78] + mov %y, %g1 + st %g1, [%g3 + 0x80] + st %fsr, [%g3 + 0x84] + + sub %g3, 0x10, %g3 + std %g4, [%g3 + 0x00] + std %g6, [%g3 + 0x08] + + set rt_interrupt_from_thread, %g1 + ld [%g1], %g2 + st %g3, [%g2] + + set rt_interrupt_to_thread, %g1 + ld [%g1], %g1 + ld [%g1], %g3 + + ldd [%g3 + 0x00], %g4 + ldd [%g3 + 0x08], %g6 + add %g3, 0x10, %g3 + + ldd [%g3 + 0x00], %f0 + ldd [%g3 + 0x08], %f2 + ldd [%g3 + 0x10], %f4 + ldd [%g3 + 0x18], %f6 + ldd [%g3 + 0x20], %f8 + ldd [%g3 + 0x28], %f10 + ldd [%g3 + 0x30], %f12 + ldd [%g3 + 0x38], %f14 + ldd [%g3 + 0x40], %f16 + ldd [%g3 + 0x48], %f18 + ldd [%g3 + 0x50], %f20 + ldd [%g3 + 0x58], %f22 + ldd [%g3 + 0x60], %f24 + ldd [%g3 + 0x68], %f26 + ldd [%g3 + 0x70], %f28 + ldd [%g3 + 0x78], %f30 + ld [%g3 + 0x80], %g1 + mov %g1, %y + ld [%g3 + 0x84], %fsr + add %g3, 0x88, %g3 + + set NWINDOWS - 1, %g1 + or %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +restore_loop: + restore + ldd [%g3 + 0x00], %l0 + ldd [%g3 + 0x08], %l2 + ldd [%g3 + 0x10], %l4 + ldd [%g3 + 0x18], %l6 + ldd [%g3 + 0x20], %i0 + ldd [%g3 + 0x28], %i2 + ldd [%g3 + 0x30], %i4 + ldd [%g3 + 0x38], %i6 + add %g3, 0x40, %g3 + inc %g1 + cmp %g1, NWINDOWS + bne restore_loop + nop + + mov %g6, %psr + nop + nop + nop + mov %g7, %wim + nop + nop + nop + + mov %g4, %l1 + mov %g5, %l2 + mov %g3, %sp + + ldd [%sp + 0x00], %g0 + ldd [%sp + 0x08], %g2 + ldd [%sp + 0x10], %g4 + ldd [%sp + 0x18], %g6 + add %sp, 0x20, %fp + jmp %l1 + rett %l2 + +/* +l0 = psr +l1 = pc +l2 = npc +l3 = tbr +*/ +_context_switch: + mov %l2, %l1 + add %l2, 4, %l2 + + mov %g4, %l4 + mov %g5, %l5 + mov %wim, %g4 + srl %g4, %l0, %g5 + cmp %g5, 1 + bne good_window + nop + srl %g4, 1, %g5 + sll %g4, NWINDOWS - 1, %g4 + or %g4, %g5, %g4 + save + mov %g4, %wim + nop + nop + nop + + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + + restore + nop + +good_window: + and %l3, 0x0FF0, %l3 + srl %l3, 4, %l4 + cmp %l4, 0x82 + bne switch_to + nop + + sub %fp, 0x20, %sp + std %g0, [%sp + 0x00] + std %g2, [%sp + 0x08] + std %g4, [%sp + 0x10] + std %g6, [%sp + 0x18] + + mov %sp, %g3 + mov %l1, %g4 + mov %l2, %g5 + mov %l0, %g6 + mov %wim, %g7 + + mov %g0, %wim + nop + nop + nop + set 0xFFFFFFF8, %g1 + and %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +save_window: + save + sub %g3, 0x40, %g3 + std %l0, [%g3 + 0x00] + std %l2, [%g3 + 0x08] + std %l4, [%g3 + 0x10] + std %l6, [%g3 + 0x18] + std %i0, [%g3 + 0x20] + std %i2, [%g3 + 0x28] + std %i4, [%g3 + 0x30] + std %i6, [%g3 + 0x38] + inc %g1 + cmp %g1, NWINDOWS + bne save_window + nop + + sub %g3, 0x88, %g3 + std %f0, [%g3 + 0x00] + std %f2, [%g3 + 0x08] + std %f4, [%g3 + 0x10] + std %f6, [%g3 + 0x18] + std %f8, [%g3 + 0x20] + std %f10, [%g3 + 0x28] + std %f12, [%g3 + 0x30] + std %f14, [%g3 + 0x38] + std %f16, [%g3 + 0x40] + std %f18, [%g3 + 0x48] + std %f20, [%g3 + 0x50] + std %f22, [%g3 + 0x58] + std %f24, [%g3 + 0x60] + std %f26, [%g3 + 0x68] + std %f28, [%g3 + 0x70] + std %f30, [%g3 + 0x78] + mov %y, %g1 + st %g1, [%g3 + 0x80] + st %fsr, [%g3 + 0x84] + + sub %g3, 0x10, %g3 + std %g4, [%g3 + 0x00] + std %g6, [%g3 + 0x08] + + mov %g6, %psr + nop + nop + nop + + st %g3, [%i0] +switch_to: + mov %g0, %wim + nop + nop + nop + ld [%i1], %g3 + + ldd [%g3 + 0x00], %g4 + ldd [%g3 + 0x08], %g6 + add %g3, 0x10, %g3 + + ldd [%g3 + 0x00], %f0 + ldd [%g3 + 0x08], %f2 + ldd [%g3 + 0x10], %f4 + ldd [%g3 + 0x18], %f6 + ldd [%g3 + 0x20], %f8 + ldd [%g3 + 0x28], %f10 + ldd [%g3 + 0x30], %f12 + ldd [%g3 + 0x38], %f14 + ldd [%g3 + 0x40], %f16 + ldd [%g3 + 0x48], %f18 + ldd [%g3 + 0x50], %f20 + ldd [%g3 + 0x58], %f22 + ldd [%g3 + 0x60], %f24 + ldd [%g3 + 0x68], %f26 + ldd [%g3 + 0x70], %f28 + ldd [%g3 + 0x78], %f30 + ld [%g3 + 0x80], %g1 + mov %g1, %y + ld [%g3 + 0x84], %fsr + add %g3, 0x88, %g3 + + set NWINDOWS - 1, %g1 + or %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +restore_window: + restore + ldd [%g3 + 0x00], %l0 + ldd [%g3 + 0x08], %l2 + ldd [%g3 + 0x10], %l4 + ldd [%g3 + 0x18], %l6 + ldd [%g3 + 0x20], %i0 + ldd [%g3 + 0x28], %i2 + ldd [%g3 + 0x30], %i4 + ldd [%g3 + 0x38], %i6 + add %g3, 0x40, %g3 + inc %g1 + cmp %g1, NWINDOWS + bne restore_window + nop + + mov %g6, %psr + nop + nop + nop + mov %g7, %wim + nop + nop + nop + + mov %g4, %l1 + mov %g5, %l2 + mov %g3, %sp + + ldd [%sp + 0x00], %g0 + ldd [%sp + 0x08], %g2 + ldd [%sp + 0x10], %g4 + ldd [%sp + 0x18], %g6 + add %sp, 0x20, %fp + jmp %l1 + rett %l2 + +.data +.align 8 +_fpdata: + .word 0, 0 +_fsrinit: + .word 0 diff --git a/libcpu/sparc-v8/bm3803/trap.c b/libcpu/sparc-v8/bm3803/trap.c new file mode 100644 index 0000000000..b896a0d941 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/trap.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#include <rtthread.h> +#include <rthw.h> + +extern struct rt_irq_desc isr_table[]; + +void rt_hw_trap(int tt, unsigned int *sp) +{ + void *param; + rt_isr_handler_t isr_func; + + /* get interrupt service routine */ + isr_func = isr_table[tt].handler; + param = isr_table[tt].param; + + /* turn to interrupt service routine */ + if (isr_func != RT_NULL) + isr_func(tt, param); +} diff --git a/libcpu/sparc-v8/bm3803/vector_gcc.S b/libcpu/sparc-v8/bm3803/vector_gcc.S new file mode 100644 index 0000000000..0d243bee33 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/vector_gcc.S @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define TRAPL(H) mov %g0, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); nop; +#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); nop; +#define TRAP_ENTRY(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); mov %tbr, %l3; +#define BAD_TRAP ta 0; nop; nop; nop; +#define SOFT_TRAP BAD_TRAP +#define NWINDOWS 8 + +.section .vectors, "ax" + +.globl _ISR_Handler +.globl _window_overflow +.globl _window_underflow +.globl _reset +.globl _context_switch + +.globl system_vectors +system_vectors: + TRAPL(_reset); ! 00 reset trap + BAD_TRAP; ! 01 instruction_access_exception + BAD_TRAP; ! 02 illegal_instruction + BAD_TRAP; ! 03 priveleged_instruction + BAD_TRAP; + TRAP(_window_overflow); ! 05 window_overflow + TRAP(_window_underflow); ! 06 window_underflow + BAD_TRAP; ! 07 memory_add0ress_not_aligned + BAD_TRAP; ! 08 fp_exception + BAD_TRAP; ! 09 data_access_exception + BAD_TRAP; ! 0A tag_overflow + BAD_TRAP; ! 0B undefined + BAD_TRAP; ! 0C undefined + BAD_TRAP; ! 0D undefined + BAD_TRAP; ! 0E undefined + BAD_TRAP; ! 0F undefined + BAD_TRAP; ! 10 undefined + + /* Interrupt entries */ + TRAP_ENTRY(_ISR_Handler) ! 11 interrupt level 1 + TRAP_ENTRY(_ISR_Handler) ! 12 interrupt level 2 + TRAP_ENTRY(_ISR_Handler) ! 13 interrupt level 3 + TRAP_ENTRY(_ISR_Handler) ! 14 interrupt level 4 + TRAP_ENTRY(_ISR_Handler) ! 15 interrupt level 5 + TRAP_ENTRY(_ISR_Handler) ! 16 interrupt level 6 + TRAP_ENTRY(_ISR_Handler) ! 17 interrupt level 7 + TRAP_ENTRY(_ISR_Handler) ! 18 interrupt level 8 + TRAP_ENTRY(_ISR_Handler) ! 19 interrupt level 9 + TRAP_ENTRY(_ISR_Handler) ! 1A interrupt level 1 + TRAP_ENTRY(_ISR_Handler) ! 1B interrupt level 11 + TRAP_ENTRY(_ISR_Handler) ! 1C interrupt level 12 + TRAP_ENTRY(_ISR_Handler) ! 1D interrupt level 13 + TRAP_ENTRY(_ISR_Handler) ! 1E interrupt level 14 + TRAP_ENTRY(_ISR_Handler) ! 1F interrupt level 15 + + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 24 - 27 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 28 - 2B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined + + /* Software traps */ + SOFT_TRAP; SOFT_TRAP; TRAP_ENTRY(_context_switch); TRAP_ENTRY(_context_switch) ! 80 - 83 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF + +_window_overflow: + mov %wim, %l3 ! Calculate next WIM + mov %g1, %l7 + srl %l3, 1, %g1 + sll %l3, NWINDOWS - 1, %l4 + or %l4, %g1, %g1 + save ! Get into window to be saved. + mov %g1, %wim + nop + nop + nop + std %l0, [%sp + 0] + std %l2, [%sp + 8] + std %l4, [%sp + 16] + std %l6, [%sp + 24] + std %i0, [%sp + 32] + std %i2, [%sp + 40] + std %i4, [%sp + 48] + std %i6, [%sp + 56] + restore ! Go back to trap window. + mov %l7, %g1 + jmp %l1 ! Re-execute save. + rett %l2 + +_window_underflow: + mov %wim, %l3 ! Calculate next WIM + sll %l3, 1, %l4 + srl %l3, NWINDOWS - 1, %l5 + or %l5, %l4, %l5 + mov %l5, %wim + nop + nop + nop + restore ! Two restores to get into the + restore ! window to restore + ldd [%sp + 0], %l0 ! Restore window from the stack + ldd [%sp + 8], %l2 + ldd [%sp + 16], %l4 + ldd [%sp + 24], %l6 + ldd [%sp + 32], %i0 + ldd [%sp + 40], %i2 + ldd [%sp + 48], %i4 + ldd [%sp + 56], %i6 + save ! Get back to the trap window. + save + jmp %l1 ! Re-execute restore. + rett %l2 diff --git a/libcpu/sparc-v8/common/SConscript b/libcpu/sparc-v8/common/SConscript new file mode 100644 index 0000000000..03ce583dc1 --- /dev/null +++ b/libcpu/sparc-v8/common/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/ti-dsp/c28x/SConscript b/libcpu/ti-dsp/c28x/SConscript index 08b274341b..760a715267 100644 --- a/libcpu/ti-dsp/c28x/SConscript +++ b/libcpu/ti-dsp/c28x/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*.s') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/ti-dsp/c28x/context.s b/libcpu/ti-dsp/c28x/context.s index f21e0ddb6e..323d97b180 100644 --- a/libcpu/ti-dsp/c28x/context.s +++ b/libcpu/ti-dsp/c28x/context.s @@ -8,6 +8,7 @@ ; 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. +; 2019-12-05 xiaolifan add support for hardware fpu32 ; .ref _rt_interrupt_to_thread @@ -24,6 +25,16 @@ .def _rt_hw_interrupt_thread_switch .def _rt_hw_interrupt_disable .def _rt_hw_interrupt_enable + +;workaround for importing fpu settings from the compiler + .cdecls C,NOLIST + %{ + #ifdef __TMS320C28XX_FPU32__ + #define __FPU32__ 1 + #else + #define __FPU32__ 0 + #endif + %} RT_CTX_SAVE .macro @@ -38,12 +49,37 @@ RT_CTX_SAVE .macro PUSH XAR7 PUSH XT PUSH RPC - + + .if __FPU32__ + PUSH RB + MOV32 *SP++, STF + MOV32 *SP++, R0H + MOV32 *SP++, R1H + MOV32 *SP++, R2H + MOV32 *SP++, R3H + MOV32 *SP++, R4H + MOV32 *SP++, R5H + MOV32 *SP++, R6H + MOV32 *SP++, R7H + .endif .endm RT_CTX_RESTORE .macro + + .if __FPU32__ + MOV32 R7H, *--SP, UNCF + MOV32 R6H, *--SP, UNCF + MOV32 R5H, *--SP, UNCF + MOV32 R4H, *--SP, UNCF + MOV32 R3H, *--SP, UNCF + MOV32 R2H, *--SP, UNCF + MOV32 R1H, *--SP, UNCF + MOV32 R0H, *--SP, UNCF + MOV32 STF, *--SP + POP RB + .endif POP RPC POP XT diff --git a/libcpu/ti-dsp/c28x/cpuport.c b/libcpu/ti-dsp/c28x/cpuport.c index 3f88606c65..15041fc846 100644 --- a/libcpu/ti-dsp/c28x/cpuport.c +++ b/libcpu/ti-dsp/c28x/cpuport.c @@ -7,6 +7,7 @@ * Date Author Notes * 2018-09-01 xuzhuoyi the first version. * 2019-07-03 zhaoxiaowei add support for __rt_ffs. + * 2019-12-05 xiaolifan add support for hardware fpu32 */ #include <rtthread.h> @@ -22,6 +23,7 @@ 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; @@ -49,6 +51,18 @@ struct stack_frame rt_uint32_t xt; rt_uint32_t rpc; +#ifdef __TMS320C28XX_FPU32__ + rt_uint32_t rb; + rt_uint32_t stf; + rt_uint32_t r0h; + rt_uint32_t r1h; + rt_uint32_t r2h; + rt_uint32_t r3h; + rt_uint32_t r4h; + rt_uint32_t r5h; + rt_uint32_t r6h; + rt_uint32_t r7h; +#endif }; @@ -83,6 +97,11 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, stack_frame->exception_stack_frame.return_address = (unsigned long)tentry; /* return_address */ stack_frame->rpc = (unsigned long)texit; +#ifdef __TMS320C28XX_FPU32__ + stack_frame->stf = 0x00000200; + stack_frame->rb = 0; +#endif + /* return task's current stack address */ return stk + sizeof(struct stack_frame); } @@ -121,7 +140,7 @@ int __rt_ffs(int value) /** * shutdown CPU */ -void rt_hw_cpu_shutdown(void) +RT_WEAK void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); diff --git a/libcpu/unicore32/sep6200/SConscript b/libcpu/unicore32/sep6200/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/unicore32/sep6200/SConscript +++ b/libcpu/unicore32/sep6200/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/unicore32/sep6200/cpu.c b/libcpu/unicore32/sep6200/cpu.c index ebea8750e1..9452b4e59d 100644 --- a/libcpu/unicore32/sep6200/cpu.c +++ b/libcpu/unicore32/sep6200/cpu.c @@ -259,7 +259,7 @@ static void sep6200_poweroff(void) * reset cpu by dog's time-out * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { rt_kprintf("Soft reset, Restarting system...\n"); @@ -274,7 +274,7 @@ void rt_hw_cpu_reset() * shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_uint32_t level; rt_kprintf("shutdown...\n"); diff --git a/libcpu/v850/70f34/SConscript b/libcpu/v850/70f34/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/v850/70f34/SConscript +++ b/libcpu/v850/70f34/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/xilinx/microblaze/SConscript b/libcpu/xilinx/microblaze/SConscript index b0ae20ba02..20f325b692 100644 --- a/libcpu/xilinx/microblaze/SConscript +++ b/libcpu/xilinx/microblaze/SConscript @@ -9,6 +9,6 @@ src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') CPPPATH = [cwd] ASFLAGS = '' -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) Return('group') diff --git a/libcpu/xilinx/microblaze/cpu.c b/libcpu/xilinx/microblaze/cpu.c index 50a0e34dcd..d37dcda350 100755 --- a/libcpu/xilinx/microblaze/cpu.c +++ b/libcpu/xilinx/microblaze/cpu.c @@ -18,7 +18,7 @@ * this function will reset CPU * */ -void rt_hw_cpu_reset() +RT_WEAK void rt_hw_cpu_reset() { } @@ -26,7 +26,7 @@ void rt_hw_cpu_reset() * this function will shutdown CPU * */ -void rt_hw_cpu_shutdown() +RT_WEAK void rt_hw_cpu_shutdown() { rt_kprintf("shutdown...\n"); |
