Przeglądaj źródła

Merge pull request #5207 from BernardXiong/riscv_smode

Fix risc-v s-mode issue.
Bernard Xiong 3 lat temu
rodzic
commit
34cbc64ff8

+ 2 - 16
bsp/qemu-riscv-virt64/driver/Kconfig

@@ -1,21 +1,7 @@
-
-
-menu "RISCV qemu virt64 configs"
-
-menuconfig BSP_USING_UART1
-    bool "Enable UART1"
-    default n
-    if BSP_USING_UART1
-        config BSP_UART1_TXD_PIN
-            int "uart1 TXD pin number"
-            default 20
-        config BSP_UART1_RXD_PIN
-            int "uart1 RXD pin number"
-            default 21
-    endif
+menu "RISC-V QEMU virt64 configs"
 
 config RISCV_S_MODE
-    bool "RT-Thread run in riscv smode"
+    bool "RT-Thread run in RISC-V S-Mode(supervisor mode)"
     default y
 
 endmenu

+ 0 - 1
bsp/qemu-riscv-virt64/driver/board.c

@@ -67,4 +67,3 @@ void rt_hw_cpu_reset(void)
     while(1);
 }
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
-

+ 5 - 5
bsp/qemu-riscv-virt64/driver/plic.c

@@ -35,7 +35,7 @@ void plic_set_priority(int irq, int priority)
 */
 void plic_irq_enable(int irq)
 {
-    int hart = r_mhartid();
+    int hart = __raw_hartid();
     *(uint32_t*)PLIC_ENABLE(hart) = ((*(uint32_t*)PLIC_ENABLE(hart)) | (1 << irq));
 #ifdef  RISCV_S_MODE
     set_csr(sie, read_csr(sie) | MIP_SEIP);
@@ -46,7 +46,7 @@ void plic_irq_enable(int irq)
 
 void plic_irq_disable(int irq)
 {
-    int hart = r_mhartid();
+    int hart = __raw_hartid();
     *(uint32_t*)PLIC_ENABLE(hart) = (((*(uint32_t*)PLIC_ENABLE(hart)) & (~(1 << irq))));
 }
 
@@ -59,7 +59,7 @@ void plic_irq_disable(int irq)
 */
 void plic_set_threshold(int threshold)
 {
-    int hart = r_mhartid();
+    int hart = __raw_hartid();
     *(uint32_t*)PLIC_THRESHOLD(hart) = threshold;
 }
 
@@ -77,7 +77,7 @@ void plic_set_threshold(int threshold)
  */
 int plic_claim(void)
 {
-    int hart = r_mhartid();
+    int hart = __raw_hartid();
     int irq = *(uint32_t*)PLIC_CLAIM(hart);
     return irq;
 }
@@ -94,6 +94,6 @@ int plic_claim(void)
  */
 void plic_complete(int irq)
 {
-    int hart = r_mhartid();
+    int hart = __raw_hartid();
     *(uint32_t*)PLIC_COMPLETE(hart) = irq;
 }

+ 27 - 22
bsp/qemu-riscv-virt64/driver/plic.h

@@ -6,48 +6,53 @@
  * Change Logs:
  * Date           Author       Notes
  * 2021-05-20     bigmagic     first version
+ * 2021-10-20     bernard      fix s-mode issue
  */
 
 #ifndef PLIC_H
 #define PLIC_H
 
 #include <rtconfig.h>
+
 /*
  * This machine puts platform-level interrupt controller (PLIC) here.
  * Here only list PLIC registers in Machine mode.
  *
  */
 
-#define VIRT_PLIC_BASE 0x0c000000L
+#define VIRT_PLIC_BASE                  0x0c000000L
+
+#define PLIC_PRIORITY_OFFSET            (0x0)
+#define PLIC_PENDING_OFFSET             (0x1000)
 
-#define PLIC_PRIORITY_OFFSET                (0x0)
-#define PLIC_PENDING_OFFSET                 (0x1000)
+#define PLIC_ENABLE_STRIDE              0x80
+#define PLIC_CONTEXT_STRIDE             0x1000
 
 #ifndef RISCV_S_MODE
-#define PLIC_MENABLE_OFFSET                 (0x2000)
-#define PLIC_MTHRESHOLD_OFFSET              (0x200000)
-#define PLIC_MCLAIM_OFFSET                  (0x200004)
-#define PLIC_MCOMPLETE_OFFSET               (0x200004)
+#define PLIC_MENABLE_OFFSET             (0x2000)
+#define PLIC_MTHRESHOLD_OFFSET          (0x200000)
+#define PLIC_MCLAIM_OFFSET              (0x200004)
+#define PLIC_MCOMPLETE_OFFSET           (0x200004)
 
-#define PLIC_ENABLE(hart)             (VIRT_PLIC_BASE + PLIC_MENABLE_OFFSET + (hart) * 0x80)
-#define PLIC_THRESHOLD(hart)          (VIRT_PLIC_BASE + PLIC_MTHRESHOLD_OFFSET + (hart) * 0x1000)
-#define PLIC_CLAIM(hart)              (VIRT_PLIC_BASE + PLIC_MCLAIM_OFFSET + (hart) * 0x1000)
-#define PLIC_COMPLETE(hart)           (VIRT_PLIC_BASE + PLIC_MCOMPLETE_OFFSET + (hart) * 0x1000)
+#define PLIC_ENABLE(hart)               (VIRT_PLIC_BASE + PLIC_MENABLE_OFFSET +     (hart * 2) * PLIC_ENABLE_STRIDE)
+#define PLIC_THRESHOLD(hart)            (VIRT_PLIC_BASE + PLIC_MTHRESHOLD_OFFSET +  (hart * 2) * PLIC_CONTEXT_STRIDE)
+#define PLIC_CLAIM(hart)                (VIRT_PLIC_BASE + PLIC_MCLAIM_OFFSET +      (hart * 2) * PLIC_CONTEXT_STRIDE)
+#define PLIC_COMPLETE(hart)             (VIRT_PLIC_BASE + PLIC_MCOMPLETE_OFFSET +   (hart * 2) * PLIC_CONTEXT_STRIDE)
 
 #else
-#define PLIC_SENABLE_OFFSET                 (0x2080)
-#define PLIC_STHRESHOLD_OFFSET              (0x201000)
-#define PLIC_SCLAIM_OFFSET                  (0x201004)
-#define PLIC_SCOMPLETE_OFFSET               (0x201004)
-
-#define PLIC_ENABLE(hart)             (VIRT_PLIC_BASE + PLIC_SENABLE_OFFSET + (hart) * 0x80)
-#define PLIC_THRESHOLD(hart)          (VIRT_PLIC_BASE + PLIC_STHRESHOLD_OFFSET + (hart) * 0x1000)
-#define PLIC_CLAIM(hart)              (VIRT_PLIC_BASE + PLIC_SCLAIM_OFFSET + (hart) * 0x1000)
-#define PLIC_COMPLETE(hart)           (VIRT_PLIC_BASE + PLIC_SCOMPLETE_OFFSET + (hart) * 0x1000)
+#define PLIC_SENABLE_OFFSET             (0x2000   + PLIC_ENABLE_STRIDE)
+#define PLIC_STHRESHOLD_OFFSET          (0x200000 + PLIC_CONTEXT_STRIDE)
+#define PLIC_SCLAIM_OFFSET              (0x200004 + PLIC_CONTEXT_STRIDE)
+#define PLIC_SCOMPLETE_OFFSET           (0x200004 + PLIC_CONTEXT_STRIDE)
+
+#define PLIC_ENABLE(hart)               (VIRT_PLIC_BASE + PLIC_SENABLE_OFFSET +     (hart * 2) * PLIC_ENABLE_STRIDE)
+#define PLIC_THRESHOLD(hart)            (VIRT_PLIC_BASE + PLIC_STHRESHOLD_OFFSET +  (hart * 2) * PLIC_CONTEXT_STRIDE)
+#define PLIC_CLAIM(hart)                (VIRT_PLIC_BASE + PLIC_SCLAIM_OFFSET +      (hart * 2) * PLIC_CONTEXT_STRIDE)
+#define PLIC_COMPLETE(hart)             (VIRT_PLIC_BASE + PLIC_SCOMPLETE_OFFSET +   (hart * 2) * PLIC_CONTEXT_STRIDE)
 #endif
 
-#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 PLIC_PRIORITY(id)               (VIRT_PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4)
+#define PLIC_PENDING(id)                (VIRT_PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32))
 
 void plic_set_priority(int irq, int priority);
 void plic_irq_enable(int irq);

+ 6 - 3
libcpu/risc-v/virt64/interrupt.c

@@ -14,7 +14,6 @@
 #include "riscv.h"
 #include "interrupt.h"
 
-#define CPU_NUM         2
 #define MAX_HANDLERS    128
 
 static struct rt_irq_desc irq_desc[MAX_HANDLERS];
@@ -60,7 +59,6 @@ void rt_hw_interrupt_init(void)
     /* init exceptions table */
     for (idx = 0; idx < MAX_HANDLERS; idx++)
     {
-        //rt_hw_interrupt_mask(idx);
         irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
         irq_desc[idx].param = RT_NULL;
 #ifdef RT_USING_INTERRUPT_INFO
@@ -68,6 +66,8 @@ void rt_hw_interrupt_init(void)
         irq_desc[idx].counter = 0;
 #endif
     }
+
+    plic_set_threshold(0);
 }
 
 /**
@@ -86,7 +86,7 @@ void rt_hw_interrupt_mask(int vector)
 void rt_hw_interrupt_umask(int vector)
 {
     plic_set_priority(vector, 1);
-    plic_set_threshold(0);
+
     rt_hw_plic_irq_enable(vector);
 }
 
@@ -182,6 +182,7 @@ void handle_trap(rt_size_t xcause,rt_size_t xtval,rt_size_t xepc,struct rt_hw_st
 {
     int cause = (xcause & 0xFFFFFFFF);
     int plic_irq = 0;
+
     if (xcause & (1UL << 63))
     {
         switch (cause)
@@ -197,11 +198,13 @@ void handle_trap(rt_size_t xcause,rt_size_t xtval,rt_size_t xepc,struct rt_hw_st
             case IRQ_S_TIMER:
                 tick_isr();
                 break;
+
             case IRQ_S_EXT:
                 plic_irq = plic_claim();
                 plic_complete(plic_irq);
                 irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
                 break;
+
             case IRQ_M_EXT:
                 plic_irq = plic_claim();
                 plic_complete(plic_irq);

+ 5 - 5
libcpu/risc-v/virt64/riscv_io.h

@@ -10,15 +10,15 @@
 #ifndef __RISCV_IO_H__
 #define __RISCV_IO_H__
 
-// which hart (core) is this?
-static inline uint32_t  r_mhartid()
+static inline uint32_t  __raw_hartid(void)
 {
-#ifndef RISCV_S_MODE
+#ifdef RISCV_S_MODE
+    extern int boot_hartid;
+    return boot_hartid;
+#else
     uint32_t x;
     asm volatile("csrr %0, mhartid" : "=r" (x) );
     return x;
-#else
-    return 0;
 #endif
 }
 

+ 10 - 2
libcpu/risc-v/virt64/startup_gcc.S

@@ -14,10 +14,18 @@
 #define XSTATUS_PUM        (1 << 18) 
 #include <cpuport.h>
 
+boot_hartid: .int
+  .global      boot_hartid
+
   .global	_start
   .section ".start", "ax"
 _start:
-#ifndef RISCV_S_MODE
+#ifdef RISCV_S_MODE
+  # save hartid
+  la t0, boot_hartid                # global varible rt_boot_hartid
+  mv t1, a0                         # get hartid in S-mode frome a0 register
+  sw t1, (t0)                       # store t1 register low 4 bits in memory address which is stored in t0
+#else
   # setup stacks per hart
   csrr t0, mhartid                  # read current hart id
   slli t0, t0, 10                   # shift left the hart id by 1024
@@ -54,4 +62,4 @@ _start:
 
 park:
     wfi
-    j park
+    j park

+ 2 - 2
libcpu/risc-v/virt64/tick.c

@@ -36,7 +36,7 @@ int tick_isr(void)
 #ifdef RISCV_S_MODE
     sbi_set_timer(get_ticks() + tick_cycles);
 #else
-    *(uint64_t*)CLINT_MTIMECMP(r_mhartid()) = *(uint64_t*)CLINT_MTIME + tick_cycles;
+    *(uint64_t*)CLINT_MTIMECMP(__raw_hartid()) = *(uint64_t*)CLINT_MTIME + tick_cycles;
 #endif
 
     return 0;
@@ -62,7 +62,7 @@ int rt_hw_tick_init(void)
 #else
     clear_csr(mie, MIP_MTIP);
     clear_csr(mip, MIP_MTIP);
-    *(uint64_t*)CLINT_MTIMECMP(r_mhartid()) = *(uint64_t*)CLINT_MTIME + interval;
+    *(uint64_t*)CLINT_MTIMECMP(__raw_hartid()) = *(uint64_t*)CLINT_MTIME + interval;
     set_csr(mie, MIP_MTIP);
 #endif
     return 0;