diff options
| author | Shell <[email protected]> | 2022-12-10 22:16:42 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-10 22:16:42 +0800 |
| commit | e991be9c51c54883b56ee3d9e7f30db33c404192 (patch) | |
| tree | 33e4e9318e0d03c68bd0dcda029d9ce4b5b3bf6b /libcpu | |
| parent | 190eda6ab03ca294238da59c3eb1069dac276a93 (diff) | |
[smart][risc-v/libcpu] port rv64 cpu code (#6704)
* [risc-v/libcpu] porting Smart & RTOS
* [fix] rv64 plic
* [risc-v/rv64] remove macro in rtdef
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/risc-v/virt64/backtrace.c | 4 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/cpuport.c | 5 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/cpuport.h | 1 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/interrupt.c | 1 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/interrupt_gcc.S | 4 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/mmu.c | 5 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/plic.c | 91 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/plic.h | 24 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/sbi.c | 4 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/sbi.h | 1 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/syscall_c.c | 3 | ||||
| -rw-r--r-- | libcpu/risc-v/virt64/trap.c | 16 |
12 files changed, 96 insertions, 63 deletions
diff --git a/libcpu/risc-v/virt64/backtrace.c b/libcpu/risc-v/virt64/backtrace.c index 47e742b67b..11651daa16 100644 --- a/libcpu/risc-v/virt64/backtrace.c +++ b/libcpu/risc-v/virt64/backtrace.c @@ -6,7 +6,9 @@ * Change Logs: * Date Author Notes */ + #include <rtthread.h> +#ifdef RT_USING_SMART #include <lwp_arch.h> #define TRANCE_LEVEL 20 @@ -132,3 +134,5 @@ static char *_get_elf_name(size_t sepc) { return IN_USERSPACE ? rt_current_thread->name : "rtthread.elf"; } + +#endif /* RT_USING_SMART */ diff --git a/libcpu/risc-v/virt64/cpuport.c b/libcpu/risc-v/virt64/cpuport.c index 8325259bce..0979f227e8 100644 --- a/libcpu/risc-v/virt64/cpuport.c +++ b/libcpu/risc-v/virt64/cpuport.c @@ -14,9 +14,8 @@ #include "cpuport.h" #include "stack.h" -#include "sbi.h" - -#include <lwp_arch.h> +#include <sbi.h> +#include <encoding.h> #define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM | SSTATUS_FS) diff --git a/libcpu/risc-v/virt64/cpuport.h b/libcpu/risc-v/virt64/cpuport.h index 3dde250bc3..37b86910cc 100644 --- a/libcpu/risc-v/virt64/cpuport.h +++ b/libcpu/risc-v/virt64/cpuport.h @@ -60,6 +60,7 @@ typedef union { #endif #ifndef __ASSEMBLY__ +#include <rtthread.h> rt_inline void rt_hw_dsb() { asm volatile("fence":::"memory"); diff --git a/libcpu/risc-v/virt64/interrupt.c b/libcpu/risc-v/virt64/interrupt.c index e6c9ea3777..f627210dac 100644 --- a/libcpu/risc-v/virt64/interrupt.c +++ b/libcpu/risc-v/virt64/interrupt.c @@ -10,7 +10,6 @@ */ #include <plic.h> #include <mmu.h> -#include <lwp_arch.h> #include "tick.h" #include "encoding.h" #include "riscv.h" diff --git a/libcpu/risc-v/virt64/interrupt_gcc.S b/libcpu/risc-v/virt64/interrupt_gcc.S index 6cc26731f1..83d995bd88 100644 --- a/libcpu/risc-v/virt64/interrupt_gcc.S +++ b/libcpu/risc-v/virt64/interrupt_gcc.S @@ -43,10 +43,12 @@ _save_context: // now we are ready to enter interrupt / excepiton handler _distinguish_syscall: csrr t0, scause +#ifdef RT_USING_SMART // TODO swap 8 with config macro name li t1, 8 beq t0, t1, syscall_entry // syscall never return here +#endif _handle_interrupt_and_exception: mv a0, t0 @@ -70,9 +72,11 @@ _context_switch: jal rt_hw_context_switch _resume_execution: +#ifdef RT_USING_SMART LOAD t0, FRAME_OFF_SSTATUS(sp) andi t0, t0, SSTATUS_SPP beqz t0, arch_ret_to_user +#endif _resume_kernel: RESTORE_ALL diff --git a/libcpu/risc-v/virt64/mmu.c b/libcpu/risc-v/virt64/mmu.c index 92bac7cf52..3a9daee3dc 100644 --- a/libcpu/risc-v/virt64/mmu.c +++ b/libcpu/risc-v/virt64/mmu.c @@ -10,6 +10,9 @@ #include <rtthread.h> #include <rthw.h> + +#ifdef RT_USING_SMART + #include <board.h> #include <page.h> #include <stdlib.h> @@ -639,3 +642,5 @@ void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr) rt_hw_mmu_switch((void *)MMUTable); } + +#endif /* RT_USING_SMART */ diff --git a/libcpu/risc-v/virt64/plic.c b/libcpu/risc-v/virt64/plic.c index 05167549d2..0fe8da9567 100644 --- a/libcpu/risc-v/virt64/plic.c +++ b/libcpu/risc-v/virt64/plic.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2021-05-20 bigmagic first version + * 2022-09-16 WangXiaoyao Porting to rv64 */ #include <rthw.h> #include <rtthread.h> @@ -18,31 +19,39 @@ #include <string.h> #include <stdlib.h> +#ifdef RT_USING_SMART +#include <ioremap.h> +#else +#define rt_ioremap(addr, ...) (addr) +#endif + +size_t plic_base = 0x0c000000L; + /* -* Each PLIC interrupt source can be assigned a priority by writing -* to its 32-bit memory-mapped priority register. -* The QEMU-virt (the same as FU540-C000) supports 7 levels of priority. -* A priority value of 0 is reserved to mean "never interrupt" and -* effectively disables the interrupt. -* Priority 1 is the lowest active priority, and priority 7 is the highest. -* Ties between global interrupts of the same priority are broken by -* the Interrupt ID; interrupts with the lowest ID have the highest -* effective priority. -*/ + * Each PLIC interrupt source can be assigned a priority by writing + * to its 32-bit memory-mapped priority register. + * The QEMU-virt (the same as FU540-C000) supports 7 levels of priority. + * A priority value of 0 is reserved to mean "never interrupt" and + * effectively disables the interrupt. + * Priority 1 is the lowest active priority, and priority 7 is the highest. + * Ties between global interrupts of the same priority are broken by + * the Interrupt ID; interrupts with the lowest ID have the highest + * effective priority. + */ void plic_set_priority(int irq, int priority) { - *(uint32_t*)PLIC_PRIORITY(irq) = priority; + *(uint32_t *)PLIC_PRIORITY(irq) = priority; } /* -* Each global interrupt can be enabled by setting the corresponding -* bit in the enables registers. -*/ + * Each global interrupt can be enabled by setting the corresponding + * bit in the enables registers. + */ void plic_irq_enable(int irq) { int hart = __raw_hartid(); - *(uint32_t*)PLIC_ENABLE(hart) = ((*(uint32_t*)PLIC_ENABLE(hart)) | (1 << irq)); -#ifdef RISCV_S_MODE + *(uint32_t *)PLIC_ENABLE(hart) = ((*(uint32_t *)PLIC_ENABLE(hart)) | (1 << irq)); +#ifdef RISCV_S_MODE set_csr(sie, read_csr(sie) | MIP_SEIP); #else set_csr(mie, read_csr(mie) | MIP_MEIP); @@ -52,20 +61,20 @@ void plic_irq_enable(int irq) void plic_irq_disable(int irq) { int hart = __raw_hartid(); - *(uint32_t*)PLIC_ENABLE(hart) = (((*(uint32_t*)PLIC_ENABLE(hart)) & (~(1 << irq)))); + *(uint32_t *)PLIC_ENABLE(hart) = (((*(uint32_t *)PLIC_ENABLE(hart)) & (~(1 << irq)))); } /* -* PLIC will mask all interrupts of a priority less than or equal to threshold. -* Maximum threshold is 7. -* For example, a threshold value of zero permits all interrupts with -* non-zero priority, whereas a value of 7 masks all interrupts. -* Notice, the threshold is global for PLIC, not for each interrupt source. -*/ + * PLIC will mask all interrupts of a priority less than or equal to threshold. + * Maximum threshold is 7. + * For example, a threshold value of zero permits all interrupts with + * non-zero priority, whereas a value of 7 masks all interrupts. + * Notice, the threshold is global for PLIC, not for each interrupt source. + */ void plic_set_threshold(int threshold) { int hart = __raw_hartid(); - *(uint32_t*)PLIC_THRESHOLD(hart) = threshold; + *(uint32_t *)PLIC_THRESHOLD(hart) = threshold; } /* @@ -83,13 +92,13 @@ void plic_set_threshold(int threshold) int plic_claim(void) { int hart = __raw_hartid(); - int irq = *(uint32_t*)PLIC_CLAIM(hart); + int irq = *(uint32_t *)PLIC_CLAIM(hart); return irq; } /* * DESCRIPTION: - * Writing the interrupt ID it received from the claim (irq) to the + * Writing the interrupt ID it received from the claim (irq) to the * complete register would signal the PLIC we've served this IRQ. * The PLIC does not check whether the completion ID is the same as the * last claim ID for that target. If the completion ID does not match an @@ -100,35 +109,33 @@ int plic_claim(void) void plic_complete(int irq) { int hart = __raw_hartid(); - *(uint32_t*)PLIC_COMPLETE(hart) = irq; + *(uint32_t *)PLIC_COMPLETE(hart) = irq; } void plic_set_ie(rt_uint32_t word_index, rt_uint32_t val) { - volatile void *plic_ie = (void *)(rt_size_t)(PLIC_BASE_ADDR + PLIC_ENABLE_BASE + word_index * 4); + volatile void *plic_ie = (void *)(rt_size_t)(plic_base + PLIC_ENABLE_BASE + 0x80 + word_index * 4); writel(val, plic_ie); } +static void _set_sie(int hartid) +{ + for (size_t i = hartid * WORD_CNT_BYTE; i < 32; i++) + plic_set_ie(i, 0xffffffff); +} + void plic_init() { - int i; + // PLIC takes up 64 MB space + plic_base = (size_t)rt_ioremap((void *)plic_base, 64 * 1024 * 1024); plic_set_threshold(0); - for(i = 0;i < 128;i++) + for (int i = 0; i < CONFIG_IRQ_NR; i++) { - plic_set_priority(i,7); + plic_set_priority(i, 1); } - plic_set_ie(0,0xffffffff); - plic_set_ie(1,0xffffffff); - plic_set_ie(2,0xffffffff); - plic_set_ie(3,0xffffffff); - - rt_uint64_t addr; - - for(addr = 0xC001000;addr <= 0xC1F1F80;addr += 4) - { - *((rt_uint32_t *)addr) = 0xffffffff; - } + // in a single core system, only current context was set + _set_sie(__raw_hartid()); } diff --git a/libcpu/risc-v/virt64/plic.h b/libcpu/risc-v/virt64/plic.h index b1509f1fd1..d24c2e5a53 100644 --- a/libcpu/risc-v/virt64/plic.h +++ b/libcpu/risc-v/virt64/plic.h @@ -15,20 +15,14 @@ #include <rtconfig.h> #include <rthw.h> -/* - * This machine puts platform-level interrupt controller (PLIC) here. - * Here only list PLIC registers in Machine mode. - * - */ +#define PLIC_PRIORITY_BASE 0x0 +#define PLIC_PENDING_BASE 0x1000 +#define PLIC_ENABLE_BASE 0x2000 +#define PLIC_CONTEXT_BASE 0x200000 -#define PLIC_PRIORITY_BASE 0x0 -#define PLIC_PENDING_BASE 0x1000 -#define PLIC_ENABLE_BASE 0x2000 -#define PLIC_CONTEXT_BASE 0x200000 +extern size_t plic_base; -#define PLIC_BASE_ADDR 0xC000000 - -#define VIRT_PLIC_BASE 0x0c000000L +#define VIRT_PLIC_BASE (plic_base) #define PLIC_PRIORITY_OFFSET (0x0) #define PLIC_PENDING_OFFSET (0x1000) @@ -62,6 +56,12 @@ #define PLIC_PRIORITY(id) (VIRT_PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4) #define PLIC_PENDING(id) (VIRT_PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32)) +#define WORD_CNT_BYTE (1024 / 8) + +/* IRQ config in system, max 1024 (from 0 to 1023) */ +#define CONFIG_IRQ_NR (128) +#define CONFIG_IRQ_WORD (CONFIG_IRQ_NR / 32) + void plic_set_priority(int irq, int priority); void plic_irq_enable(int irq); void plic_irq_disable(int irq); diff --git a/libcpu/risc-v/virt64/sbi.c b/libcpu/risc-v/virt64/sbi.c index 5dd021df8a..93084bd441 100644 --- a/libcpu/risc-v/virt64/sbi.c +++ b/libcpu/risc-v/virt64/sbi.c @@ -71,8 +71,8 @@ sbi_get_impl_version(void) void sbi_print_version(void) { - u_int major; - u_int minor; + uint32_t major; + uint32_t minor; /* For legacy SBI implementations. */ if (sbi_spec_version == 0) diff --git a/libcpu/risc-v/virt64/sbi.h b/libcpu/risc-v/virt64/sbi.h index 0e95ede334..a5ab83d27d 100644 --- a/libcpu/risc-v/virt64/sbi.h +++ b/libcpu/risc-v/virt64/sbi.h @@ -48,6 +48,7 @@ #ifndef _MACHINE_SBI_H_ #define _MACHINE_SBI_H_ +#include <stdint.h> #include <rtdef.h> /* SBI Specification Version */ diff --git a/libcpu/risc-v/virt64/syscall_c.c b/libcpu/risc-v/virt64/syscall_c.c index 8f27db5ffd..9a946d98b9 100644 --- a/libcpu/risc-v/virt64/syscall_c.c +++ b/libcpu/risc-v/virt64/syscall_c.c @@ -12,6 +12,8 @@ #include <rthw.h> #include <rtthread.h> +#ifdef RT_USING_SMART + #define DBG_TAG "syscall" #define DBG_LVL DBG_WARNING #include <rtdbg.h> @@ -58,3 +60,4 @@ void syscall_handler(struct rt_hw_stack_frame *regs) regs->epc += 4; // skip ecall instruction LOG_I("[0x%lx] %s ret: 0x%lx", rt_thread_self(), syscall_name, regs->a0); } +#endif /* RT_USING_SMART */ diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index 35392559d6..0a5c082f30 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -5,9 +5,11 @@ * * Change Logs: * Date Author Notes + * 2022-12-08 RT-Thread first version */ #include <rthw.h> #include <rtthread.h> +#include <stdint.h> #include "encoding.h" #include "stack.h" @@ -15,7 +17,13 @@ #include "riscv.h" #include "tick.h" #include "plic.h" -#include "lwp_arch.h" +#include "riscv_mmu.h" + +#ifdef RT_USING_SMART +#include <lwp_arch.h> +#else +#define rt_hw_backtrace(...) (0) +#endif void dump_regs(struct rt_hw_stack_frame *regs) { @@ -147,11 +155,11 @@ static const char *get_exception_msg(int id) return msg; } +#ifdef RT_USING_SMART void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp) { rt_size_t id = __MASKVALUE(scause, __MASK(63UL)); -#ifdef RT_USING_USERSPACE /* user page fault */ if (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT) @@ -161,7 +169,6 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw return; } } -#endif LOG_E("[FATAL ERROR] Exception %ld:%s\n", id, get_exception_msg(id)); LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc); dump_regs(sp); @@ -171,6 +178,7 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw LOG_E("User Fault, killing thread: %s", rt_thread_self()->name); sys_exit(-1); } +#endif static void vector_enable(struct rt_hw_stack_frame *sp) { @@ -282,12 +290,14 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw goto _exit; } #endif /* ENABLE_VECTOR */ +#ifdef RT_USING_SMART if (!(sp->sstatus & 0x100)) { handle_user(scause, stval, sepc, sp); // if handle_user() return here, jump to u mode then goto _exit; } +#endif // handle kernel exception: rt_kprintf("Unhandled Exception %ld:%s\n", id, get_exception_msg(id)); |
