From a120c914bb003646010d1d385be36b5260284132 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Thu, 16 Apr 2020 16:42:07 +0800 Subject: add bsp/raspi4 readme --- libcpu/aarch64/cortex-a57/SConscript | 13 ---- libcpu/aarch64/cortex-a57/entry_point.S | 111 -------------------------------- libcpu/aarch64/cortex-a57/interrupt.c | 73 --------------------- libcpu/aarch64/cortex-a57/interrupt.h | 27 -------- libcpu/aarch64/cortex-a57/stack.c | 90 -------------------------- libcpu/aarch64/cortex-a57/trap.c | 98 ---------------------------- libcpu/aarch64/cortex-a72/SConscript | 13 ++++ libcpu/aarch64/cortex-a72/entry_point.S | 111 ++++++++++++++++++++++++++++++++ libcpu/aarch64/cortex-a72/interrupt.c | 73 +++++++++++++++++++++ libcpu/aarch64/cortex-a72/interrupt.h | 27 ++++++++ libcpu/aarch64/cortex-a72/stack.c | 90 ++++++++++++++++++++++++++ libcpu/aarch64/cortex-a72/trap.c | 98 ++++++++++++++++++++++++++++ 12 files changed, 412 insertions(+), 412 deletions(-) delete mode 100644 libcpu/aarch64/cortex-a57/SConscript delete mode 100644 libcpu/aarch64/cortex-a57/entry_point.S delete mode 100644 libcpu/aarch64/cortex-a57/interrupt.c delete mode 100644 libcpu/aarch64/cortex-a57/interrupt.h delete mode 100644 libcpu/aarch64/cortex-a57/stack.c delete mode 100644 libcpu/aarch64/cortex-a57/trap.c create mode 100644 libcpu/aarch64/cortex-a72/SConscript create mode 100644 libcpu/aarch64/cortex-a72/entry_point.S create mode 100644 libcpu/aarch64/cortex-a72/interrupt.c create mode 100644 libcpu/aarch64/cortex-a72/interrupt.h create mode 100644 libcpu/aarch64/cortex-a72/stack.c create mode 100644 libcpu/aarch64/cortex-a72/trap.c (limited to 'libcpu') diff --git a/libcpu/aarch64/cortex-a57/SConscript b/libcpu/aarch64/cortex-a57/SConscript deleted file mode 100644 index c6a4817802..0000000000 --- a/libcpu/aarch64/cortex-a57/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -# RT-Thread building script for component - -from building import * - -Import('rtconfig') - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') -CPPPATH = [cwd] - -group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/libcpu/aarch64/cortex-a57/entry_point.S b/libcpu/aarch64/cortex-a57/entry_point.S deleted file mode 100644 index 6d2c69226b..0000000000 --- a/libcpu/aarch64/cortex-a57/entry_point.S +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Date Author Notes - * 2020-01-15 bigmagic the first version - */ - -.section ".text.entrypoint" - -.set EL1_stack, __el1_stack - -.global _start - -// This symbol is set to 0x80000 in ld script. That is the address that raspi3's firmware -// loads 'kernel8.img' file in. -_start: - // read cpu id, stop slave cores - mrs x1, mpidr_el1 // MPIDR_EL1: Multi-Processor Affinity Register - and x1, x1, #3 - cbz x1, .L__cpu_0 // .L prefix is the local label in ELF - - // cpu id > 0, stop - // cpu id == 0 will also goto here after returned from entry() if possible -.L__current_cpu_idle: - wfe - b .L__current_cpu_idle - -.L__cpu_0: // cpu id == 0 - - // set stack before our code - - /* Define stack pointer for current exception level */ - // ldr x2, =EL1_stack - // mov sp, x2 - - ldr x1, =_start - - // set up EL1 - mrs x0, CurrentEL // CurrentEL Register. bit 2, 3. Others reserved - and x0, x0, #12 // clear reserved bits - - // running at EL3? - cmp x0, #12 // 1100b. So, EL3 - bne .L__not_in_el3 // 11? !EL3 -> 5: - - // should never be executed, just for completeness. (EL3) - mov x2, #0x5b1 - msr scr_el3, x2 // SCR_ELn Secure Configuration Register - mov x2, #0x3c9 - msr spsr_el3, x2 // SPSR_ELn. Saved Program Status Register. 1111001001 - adr x2, .L__not_in_el3 - msr elr_el3, x2 - eret // Exception Return: from EL3, continue from .L__not_in_el3 - - // running at EL2 or EL1 -.L__not_in_el3: - cmp x0, #4 // 0x04 0100 EL1 - beq .L__in_el1 // EL1 -> 5: - - // in EL2 - msr sp_el1, x1 // Set sp of EL1 to _start - - // enable CNTP for EL1 - mrs x0, cnthctl_el2 // Counter-timer Hypervisor Control register - orr x0, x0, #3 - msr cnthctl_el2, x0 - msr cntvoff_el2, xzr - - // enable AArch64 in EL1 - mov x0, #(1 << 31) // AArch64 - orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 - msr hcr_el2, x0 - mrs x0, hcr_el2 - - // change execution level to EL1 - mov x2, #0x3c4 - msr spsr_el2, x2 // 1111000100 - adr x2, .L__in_el1 - msr elr_el2, x2 - eret // exception return. from EL2. continue from .L__in_el1 - -.L__in_el1: - mov sp, x1 // in EL1. Set sp to _start - - // Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction - mov x1, #0x00300000 // Don't trap any SIMD/FP instructions in both EL0 and EL1 - msr cpacr_el1, x1 - - mrs x1, sctlr_el1 - orr x1, x1, #(1 << 12) - bic x1, x1, #(3 << 3) - bic x1, x1, #(1 << 1) - msr sctlr_el1, x1 - - // clear bss - ldr x1, =__bss_start - ldr w2, =__bss_size - -.L__clean_bss_loop: - cbz w2, .L__jump_to_entry - str xzr, [x1], #8 - sub w2, w2, #1 - cbnz w2, .L__clean_bss_loop - - // jump to C code, should not return -.L__jump_to_entry: - bl entry - // for failsafe, halt this core too - b .L__current_cpu_idle diff --git a/libcpu/aarch64/cortex-a57/interrupt.c b/libcpu/aarch64/cortex-a57/interrupt.c deleted file mode 100644 index d770259d61..0000000000 --- a/libcpu/aarch64/cortex-a57/interrupt.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-04-16 bigmagic first version - */ - -#include -#include -#include -#include -#include - -#define MAX_HANDLERS 256 - -#ifdef RT_USING_SMP -#define rt_interrupt_nest rt_cpu_self()->irq_nest -#else -extern volatile rt_uint8_t rt_interrupt_nest; -#endif - -extern int system_vectors; - -/* exception and interrupt handler table */ -struct rt_irq_desc isr_table[MAX_HANDLERS]; - -rt_ubase_t rt_interrupt_from_thread; -rt_ubase_t rt_interrupt_to_thread; -rt_ubase_t rt_thread_switch_interrupt_flag; - -void rt_hw_vector_init(void) -{ - rt_hw_set_current_vbar((rt_ubase_t)&system_vectors); // cpu_gcc.S -} - -/** - * This function will initialize hardware interrupt - */ -void rt_hw_interrupt_init(void) -{ - initIRQController(); -} - -/** - * 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) - { - 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; -} \ No newline at end of file diff --git a/libcpu/aarch64/cortex-a57/interrupt.h b/libcpu/aarch64/cortex-a57/interrupt.h deleted file mode 100644 index 0d2d4867c7..0000000000 --- a/libcpu/aarch64/cortex-a57/interrupt.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-04-16 bigmagic first version - */ - -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#include -#include - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -void rt_hw_interrupt_init(void); -void rt_hw_interrupt_mask(int vector); -void rt_hw_interrupt_umask(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/aarch64/cortex-a57/stack.c b/libcpu/aarch64/cortex-a57/stack.c deleted file mode 100644 index 68222c2c67..0000000000 --- a/libcpu/aarch64/cortex-a57/stack.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2006-2019, 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 - */ -#include -#include - -#include - -#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_EL0) -#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_EL0) -#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_EL0) - -/** - * 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_ubase_t *stk; - rt_ubase_t current_el; - - stk = (rt_ubase_t*)stack_addr; - - *(--stk) = ( rt_ubase_t ) 11; /* X1 */ - *(--stk) = ( rt_ubase_t ) parameter; /* X0 */ - *(--stk) = ( rt_ubase_t ) 33; /* X3 */ - *(--stk) = ( rt_ubase_t ) 22; /* X2 */ - *(--stk) = ( rt_ubase_t ) 55; /* X5 */ - *(--stk) = ( rt_ubase_t ) 44; /* X4 */ - *(--stk) = ( rt_ubase_t ) 77; /* X7 */ - *(--stk) = ( rt_ubase_t ) 66; /* X6 */ - *(--stk) = ( rt_ubase_t ) 99; /* X9 */ - *(--stk) = ( rt_ubase_t ) 88; /* X8 */ - *(--stk) = ( rt_ubase_t ) 11; /* X11 */ - *(--stk) = ( rt_ubase_t ) 10; /* X10 */ - *(--stk) = ( rt_ubase_t ) 13; /* X13 */ - *(--stk) = ( rt_ubase_t ) 12; /* X12 */ - *(--stk) = ( rt_ubase_t ) 15; /* X15 */ - *(--stk) = ( rt_ubase_t ) 14; /* X14 */ - *(--stk) = ( rt_ubase_t ) 17; /* X17 */ - *(--stk) = ( rt_ubase_t ) 16; /* X16 */ - *(--stk) = ( rt_ubase_t ) 19; /* X19 */ - *(--stk) = ( rt_ubase_t ) 18; /* X18 */ - *(--stk) = ( rt_ubase_t ) 21; /* X21 */ - *(--stk) = ( rt_ubase_t ) 20; /* X20 */ - *(--stk) = ( rt_ubase_t ) 23; /* X23 */ - *(--stk) = ( rt_ubase_t ) 22; /* X22 */ - *(--stk) = ( rt_ubase_t ) 25; /* X25 */ - *(--stk) = ( rt_ubase_t ) 24; /* X24 */ - *(--stk) = ( rt_ubase_t ) 27; /* X27 */ - *(--stk) = ( rt_ubase_t ) 26; /* X26 */ - *(--stk) = ( rt_ubase_t ) 29; /* X29 */ - *(--stk) = ( rt_ubase_t ) 28; /* X28 */ - *(--stk) = ( rt_ubase_t ) 0; /* XZR - has no effect, used so there are an even number of registers. */ - *(--stk) = ( rt_ubase_t ) texit; /* X30 - procedure call link register. */ - - current_el = rt_hw_get_current_el(); - - if(current_el == 3) - { - *(--stk) = INITIAL_SPSR_EL3; - } - else if(current_el == 2) - { - *(--stk) = INITIAL_SPSR_EL2; - } - else - { - *(--stk) = INITIAL_SPSR_EL1; - } - - *(--stk) = ( rt_ubase_t ) tentry; /* Exception return address. */ - - /* return task's current stack address */ - return (rt_uint8_t *)stk; -} diff --git a/libcpu/aarch64/cortex-a57/trap.c b/libcpu/aarch64/cortex-a57/trap.c deleted file mode 100644 index d93aa18fd6..0000000000 --- a/libcpu/aarch64/cortex-a57/trap.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Date Author Notes - * 2018-10-06 ZhaoXiaowei the first version - */ - -#include -#include - -#include "interrupt.h" -#include "armv8.h" - -extern struct rt_thread *rt_current_thread; -#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%16.16lx r01:0x%16.16lx r02:0x%16.16lx r03:0x%16.16lx\n", regs->x0, regs->x1, regs->x2, regs->x3); - rt_kprintf("r04:0x%16.16lx r05:0x%16.16lx r06:0x%16.16lx r07:0x%16.16lx\n", regs->x4, regs->x5, regs->x6, regs->x7); - rt_kprintf("r08:0x%16.16lx r09:0x%16.16lx r10:0x%16.16lx r11:0x%16.16lx\n", regs->x8, regs->x9, regs->x10, regs->x11); - rt_kprintf("r12:0x%16.16lx r13:0x%16.16lx r14:0x%16.16lx r15:0x%16.16lx\n", regs->x12, regs->x13, regs->x14, regs->x15); - rt_kprintf("r16:0x%16.16lx r17:0x%16.16lx r18:0x%16.16lx r19:0x%16.16lx\n", regs->x16, regs->x17, regs->x18, regs->x19); - rt_kprintf("r20:0x%16.16lx r21:0x%16.16lx r22:0x%16.16lx r23:0x%16.16lx\n", regs->x20, regs->x21, regs->x22, regs->x23); - rt_kprintf("r24:0x%16.16lx r25:0x%16.16lx r26:0x%16.16lx r27:0x%16.16lx\n", regs->x24, regs->x25, regs->x26, regs->x27); - rt_kprintf("r28:0x%16.16lx r29:0x%16.16lx r30:0x%16.16lx\n", regs->x28, regs->x29, regs->x30); - rt_kprintf("spsr:0x%16.16lx\n", regs->spsr); - rt_kprintf("return pc:0x%16.16lx\n", regs->pc); -} - -/** - * 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_error(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("error exception:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -#define GIC_ACK_INTID_MASK 0x000003ff - -int rt_hw_interrupt_get_irq(void); -void rt_hw_interrupt_ack(int fiq_irq); - -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) -{ -} diff --git a/libcpu/aarch64/cortex-a72/SConscript b/libcpu/aarch64/cortex-a72/SConscript new file mode 100644 index 0000000000..c6a4817802 --- /dev/null +++ b/libcpu/aarch64/cortex-a72/SConscript @@ -0,0 +1,13 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') +CPPPATH = [cwd] + +group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/aarch64/cortex-a72/entry_point.S b/libcpu/aarch64/cortex-a72/entry_point.S new file mode 100644 index 0000000000..6d2c69226b --- /dev/null +++ b/libcpu/aarch64/cortex-a72/entry_point.S @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2020-01-15 bigmagic the first version + */ + +.section ".text.entrypoint" + +.set EL1_stack, __el1_stack + +.global _start + +// This symbol is set to 0x80000 in ld script. That is the address that raspi3's firmware +// loads 'kernel8.img' file in. +_start: + // read cpu id, stop slave cores + mrs x1, mpidr_el1 // MPIDR_EL1: Multi-Processor Affinity Register + and x1, x1, #3 + cbz x1, .L__cpu_0 // .L prefix is the local label in ELF + + // cpu id > 0, stop + // cpu id == 0 will also goto here after returned from entry() if possible +.L__current_cpu_idle: + wfe + b .L__current_cpu_idle + +.L__cpu_0: // cpu id == 0 + + // set stack before our code + + /* Define stack pointer for current exception level */ + // ldr x2, =EL1_stack + // mov sp, x2 + + ldr x1, =_start + + // set up EL1 + mrs x0, CurrentEL // CurrentEL Register. bit 2, 3. Others reserved + and x0, x0, #12 // clear reserved bits + + // running at EL3? + cmp x0, #12 // 1100b. So, EL3 + bne .L__not_in_el3 // 11? !EL3 -> 5: + + // should never be executed, just for completeness. (EL3) + mov x2, #0x5b1 + msr scr_el3, x2 // SCR_ELn Secure Configuration Register + mov x2, #0x3c9 + msr spsr_el3, x2 // SPSR_ELn. Saved Program Status Register. 1111001001 + adr x2, .L__not_in_el3 + msr elr_el3, x2 + eret // Exception Return: from EL3, continue from .L__not_in_el3 + + // running at EL2 or EL1 +.L__not_in_el3: + cmp x0, #4 // 0x04 0100 EL1 + beq .L__in_el1 // EL1 -> 5: + + // in EL2 + msr sp_el1, x1 // Set sp of EL1 to _start + + // enable CNTP for EL1 + mrs x0, cnthctl_el2 // Counter-timer Hypervisor Control register + orr x0, x0, #3 + msr cnthctl_el2, x0 + msr cntvoff_el2, xzr + + // enable AArch64 in EL1 + mov x0, #(1 << 31) // AArch64 + orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 + msr hcr_el2, x0 + mrs x0, hcr_el2 + + // change execution level to EL1 + mov x2, #0x3c4 + msr spsr_el2, x2 // 1111000100 + adr x2, .L__in_el1 + msr elr_el2, x2 + eret // exception return. from EL2. continue from .L__in_el1 + +.L__in_el1: + mov sp, x1 // in EL1. Set sp to _start + + // Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction + mov x1, #0x00300000 // Don't trap any SIMD/FP instructions in both EL0 and EL1 + msr cpacr_el1, x1 + + mrs x1, sctlr_el1 + orr x1, x1, #(1 << 12) + bic x1, x1, #(3 << 3) + bic x1, x1, #(1 << 1) + msr sctlr_el1, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size + +.L__clean_bss_loop: + cbz w2, .L__jump_to_entry + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, .L__clean_bss_loop + + // jump to C code, should not return +.L__jump_to_entry: + bl entry + // for failsafe, halt this core too + b .L__current_cpu_idle diff --git a/libcpu/aarch64/cortex-a72/interrupt.c b/libcpu/aarch64/cortex-a72/interrupt.c new file mode 100644 index 0000000000..d770259d61 --- /dev/null +++ b/libcpu/aarch64/cortex-a72/interrupt.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-16 bigmagic first version + */ + +#include +#include +#include +#include +#include + +#define MAX_HANDLERS 256 + +#ifdef RT_USING_SMP +#define rt_interrupt_nest rt_cpu_self()->irq_nest +#else +extern volatile rt_uint8_t rt_interrupt_nest; +#endif + +extern int system_vectors; + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +rt_ubase_t rt_interrupt_from_thread; +rt_ubase_t rt_interrupt_to_thread; +rt_ubase_t rt_thread_switch_interrupt_flag; + +void rt_hw_vector_init(void) +{ + rt_hw_set_current_vbar((rt_ubase_t)&system_vectors); // cpu_gcc.S +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + initIRQController(); +} + +/** + * 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) + { + 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; +} \ No newline at end of file diff --git a/libcpu/aarch64/cortex-a72/interrupt.h b/libcpu/aarch64/cortex-a72/interrupt.h new file mode 100644 index 0000000000..0d2d4867c7 --- /dev/null +++ b/libcpu/aarch64/cortex-a72/interrupt.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-16 bigmagic first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(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/aarch64/cortex-a72/stack.c b/libcpu/aarch64/cortex-a72/stack.c new file mode 100644 index 0000000000..68222c2c67 --- /dev/null +++ b/libcpu/aarch64/cortex-a72/stack.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2006-2019, 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 + */ +#include +#include + +#include + +#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_EL0) +#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_EL0) +#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_EL0) + +/** + * 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_ubase_t *stk; + rt_ubase_t current_el; + + stk = (rt_ubase_t*)stack_addr; + + *(--stk) = ( rt_ubase_t ) 11; /* X1 */ + *(--stk) = ( rt_ubase_t ) parameter; /* X0 */ + *(--stk) = ( rt_ubase_t ) 33; /* X3 */ + *(--stk) = ( rt_ubase_t ) 22; /* X2 */ + *(--stk) = ( rt_ubase_t ) 55; /* X5 */ + *(--stk) = ( rt_ubase_t ) 44; /* X4 */ + *(--stk) = ( rt_ubase_t ) 77; /* X7 */ + *(--stk) = ( rt_ubase_t ) 66; /* X6 */ + *(--stk) = ( rt_ubase_t ) 99; /* X9 */ + *(--stk) = ( rt_ubase_t ) 88; /* X8 */ + *(--stk) = ( rt_ubase_t ) 11; /* X11 */ + *(--stk) = ( rt_ubase_t ) 10; /* X10 */ + *(--stk) = ( rt_ubase_t ) 13; /* X13 */ + *(--stk) = ( rt_ubase_t ) 12; /* X12 */ + *(--stk) = ( rt_ubase_t ) 15; /* X15 */ + *(--stk) = ( rt_ubase_t ) 14; /* X14 */ + *(--stk) = ( rt_ubase_t ) 17; /* X17 */ + *(--stk) = ( rt_ubase_t ) 16; /* X16 */ + *(--stk) = ( rt_ubase_t ) 19; /* X19 */ + *(--stk) = ( rt_ubase_t ) 18; /* X18 */ + *(--stk) = ( rt_ubase_t ) 21; /* X21 */ + *(--stk) = ( rt_ubase_t ) 20; /* X20 */ + *(--stk) = ( rt_ubase_t ) 23; /* X23 */ + *(--stk) = ( rt_ubase_t ) 22; /* X22 */ + *(--stk) = ( rt_ubase_t ) 25; /* X25 */ + *(--stk) = ( rt_ubase_t ) 24; /* X24 */ + *(--stk) = ( rt_ubase_t ) 27; /* X27 */ + *(--stk) = ( rt_ubase_t ) 26; /* X26 */ + *(--stk) = ( rt_ubase_t ) 29; /* X29 */ + *(--stk) = ( rt_ubase_t ) 28; /* X28 */ + *(--stk) = ( rt_ubase_t ) 0; /* XZR - has no effect, used so there are an even number of registers. */ + *(--stk) = ( rt_ubase_t ) texit; /* X30 - procedure call link register. */ + + current_el = rt_hw_get_current_el(); + + if(current_el == 3) + { + *(--stk) = INITIAL_SPSR_EL3; + } + else if(current_el == 2) + { + *(--stk) = INITIAL_SPSR_EL2; + } + else + { + *(--stk) = INITIAL_SPSR_EL1; + } + + *(--stk) = ( rt_ubase_t ) tentry; /* Exception return address. */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} diff --git a/libcpu/aarch64/cortex-a72/trap.c b/libcpu/aarch64/cortex-a72/trap.c new file mode 100644 index 0000000000..d93aa18fd6 --- /dev/null +++ b/libcpu/aarch64/cortex-a72/trap.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2018-10-06 ZhaoXiaowei the first version + */ + +#include +#include + +#include "interrupt.h" +#include "armv8.h" + +extern struct rt_thread *rt_current_thread; +#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%16.16lx r01:0x%16.16lx r02:0x%16.16lx r03:0x%16.16lx\n", regs->x0, regs->x1, regs->x2, regs->x3); + rt_kprintf("r04:0x%16.16lx r05:0x%16.16lx r06:0x%16.16lx r07:0x%16.16lx\n", regs->x4, regs->x5, regs->x6, regs->x7); + rt_kprintf("r08:0x%16.16lx r09:0x%16.16lx r10:0x%16.16lx r11:0x%16.16lx\n", regs->x8, regs->x9, regs->x10, regs->x11); + rt_kprintf("r12:0x%16.16lx r13:0x%16.16lx r14:0x%16.16lx r15:0x%16.16lx\n", regs->x12, regs->x13, regs->x14, regs->x15); + rt_kprintf("r16:0x%16.16lx r17:0x%16.16lx r18:0x%16.16lx r19:0x%16.16lx\n", regs->x16, regs->x17, regs->x18, regs->x19); + rt_kprintf("r20:0x%16.16lx r21:0x%16.16lx r22:0x%16.16lx r23:0x%16.16lx\n", regs->x20, regs->x21, regs->x22, regs->x23); + rt_kprintf("r24:0x%16.16lx r25:0x%16.16lx r26:0x%16.16lx r27:0x%16.16lx\n", regs->x24, regs->x25, regs->x26, regs->x27); + rt_kprintf("r28:0x%16.16lx r29:0x%16.16lx r30:0x%16.16lx\n", regs->x28, regs->x29, regs->x30); + rt_kprintf("spsr:0x%16.16lx\n", regs->spsr); + rt_kprintf("return pc:0x%16.16lx\n", regs->pc); +} + +/** + * 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_error(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("error exception:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +#define GIC_ACK_INTID_MASK 0x000003ff + +int rt_hw_interrupt_get_irq(void); +void rt_hw_interrupt_ack(int fiq_irq); + +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) +{ +} -- cgit v1.3.1