summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorShell <[email protected]>2022-12-10 22:16:42 +0800
committerGitHub <[email protected]>2022-12-10 22:16:42 +0800
commite991be9c51c54883b56ee3d9e7f30db33c404192 (patch)
tree33e4e9318e0d03c68bd0dcda029d9ce4b5b3bf6b /libcpu
parent190eda6ab03ca294238da59c3eb1069dac276a93 (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.c4
-rw-r--r--libcpu/risc-v/virt64/cpuport.c5
-rw-r--r--libcpu/risc-v/virt64/cpuport.h1
-rw-r--r--libcpu/risc-v/virt64/interrupt.c1
-rw-r--r--libcpu/risc-v/virt64/interrupt_gcc.S4
-rw-r--r--libcpu/risc-v/virt64/mmu.c5
-rw-r--r--libcpu/risc-v/virt64/plic.c91
-rw-r--r--libcpu/risc-v/virt64/plic.h24
-rw-r--r--libcpu/risc-v/virt64/sbi.c4
-rw-r--r--libcpu/risc-v/virt64/sbi.h1
-rw-r--r--libcpu/risc-v/virt64/syscall_c.c3
-rw-r--r--libcpu/risc-v/virt64/trap.c16
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));