Merge pull request #5207 from BernardXiong/riscv_smode
Fix risc-v s-mode issue.
This commit is contained in:
commit
34cbc64ff8
|
@ -1,21 +1,7 @@
|
||||||
|
menu "RISC-V QEMU virt64 configs"
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
config RISCV_S_MODE
|
config RISCV_S_MODE
|
||||||
bool "RT-Thread run in riscv smode"
|
bool "RT-Thread run in RISC-V S-Mode(supervisor mode)"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -67,4 +67,3 @@ void rt_hw_cpu_reset(void)
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
|
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void plic_set_priority(int irq, int priority)
|
||||||
*/
|
*/
|
||||||
void plic_irq_enable(int irq)
|
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));
|
*(uint32_t*)PLIC_ENABLE(hart) = ((*(uint32_t*)PLIC_ENABLE(hart)) | (1 << irq));
|
||||||
#ifdef RISCV_S_MODE
|
#ifdef RISCV_S_MODE
|
||||||
set_csr(sie, read_csr(sie) | MIP_SEIP);
|
set_csr(sie, read_csr(sie) | MIP_SEIP);
|
||||||
|
@ -46,7 +46,7 @@ void plic_irq_enable(int irq)
|
||||||
|
|
||||||
void plic_irq_disable(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))));
|
*(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)
|
void plic_set_threshold(int threshold)
|
||||||
{
|
{
|
||||||
int hart = r_mhartid();
|
int hart = __raw_hartid();
|
||||||
*(uint32_t*)PLIC_THRESHOLD(hart) = threshold;
|
*(uint32_t*)PLIC_THRESHOLD(hart) = threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ void plic_set_threshold(int threshold)
|
||||||
*/
|
*/
|
||||||
int plic_claim(void)
|
int plic_claim(void)
|
||||||
{
|
{
|
||||||
int hart = r_mhartid();
|
int hart = __raw_hartid();
|
||||||
int irq = *(uint32_t*)PLIC_CLAIM(hart);
|
int irq = *(uint32_t*)PLIC_CLAIM(hart);
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,6 @@ int plic_claim(void)
|
||||||
*/
|
*/
|
||||||
void plic_complete(int irq)
|
void plic_complete(int irq)
|
||||||
{
|
{
|
||||||
int hart = r_mhartid();
|
int hart = __raw_hartid();
|
||||||
*(uint32_t*)PLIC_COMPLETE(hart) = irq;
|
*(uint32_t*)PLIC_COMPLETE(hart) = irq;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,48 +6,53 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2021-05-20 bigmagic first version
|
* 2021-05-20 bigmagic first version
|
||||||
|
* 2021-10-20 bernard fix s-mode issue
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLIC_H
|
#ifndef PLIC_H
|
||||||
#define PLIC_H
|
#define PLIC_H
|
||||||
|
|
||||||
#include <rtconfig.h>
|
#include <rtconfig.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This machine puts platform-level interrupt controller (PLIC) here.
|
* This machine puts platform-level interrupt controller (PLIC) here.
|
||||||
* Here only list PLIC registers in Machine mode.
|
* 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_PRIORITY_OFFSET (0x0)
|
||||||
#define PLIC_PENDING_OFFSET (0x1000)
|
#define PLIC_PENDING_OFFSET (0x1000)
|
||||||
|
|
||||||
|
#define PLIC_ENABLE_STRIDE 0x80
|
||||||
|
#define PLIC_CONTEXT_STRIDE 0x1000
|
||||||
|
|
||||||
#ifndef RISCV_S_MODE
|
#ifndef RISCV_S_MODE
|
||||||
#define PLIC_MENABLE_OFFSET (0x2000)
|
#define PLIC_MENABLE_OFFSET (0x2000)
|
||||||
#define PLIC_MTHRESHOLD_OFFSET (0x200000)
|
#define PLIC_MTHRESHOLD_OFFSET (0x200000)
|
||||||
#define PLIC_MCLAIM_OFFSET (0x200004)
|
#define PLIC_MCLAIM_OFFSET (0x200004)
|
||||||
#define PLIC_MCOMPLETE_OFFSET (0x200004)
|
#define PLIC_MCOMPLETE_OFFSET (0x200004)
|
||||||
|
|
||||||
#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_MENABLE_OFFSET + (hart) * 0x80)
|
#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) * 0x1000)
|
#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) * 0x1000)
|
#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) * 0x1000)
|
#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_MCOMPLETE_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define PLIC_SENABLE_OFFSET (0x2080)
|
#define PLIC_SENABLE_OFFSET (0x2000 + PLIC_ENABLE_STRIDE)
|
||||||
#define PLIC_STHRESHOLD_OFFSET (0x201000)
|
#define PLIC_STHRESHOLD_OFFSET (0x200000 + PLIC_CONTEXT_STRIDE)
|
||||||
#define PLIC_SCLAIM_OFFSET (0x201004)
|
#define PLIC_SCLAIM_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE)
|
||||||
#define PLIC_SCOMPLETE_OFFSET (0x201004)
|
#define PLIC_SCOMPLETE_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE)
|
||||||
|
|
||||||
#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_SENABLE_OFFSET + (hart) * 0x80)
|
#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) * 0x1000)
|
#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) * 0x1000)
|
#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) * 0x1000)
|
#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_SCOMPLETE_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PLIC_PRIORITY(id) (VIRT_PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4)
|
#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_PENDING(id) (VIRT_PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32))
|
||||||
|
|
||||||
void plic_set_priority(int irq, int priority);
|
void plic_set_priority(int irq, int priority);
|
||||||
void plic_irq_enable(int irq);
|
void plic_irq_enable(int irq);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "riscv.h"
|
#include "riscv.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
|
||||||
#define CPU_NUM 2
|
|
||||||
#define MAX_HANDLERS 128
|
#define MAX_HANDLERS 128
|
||||||
|
|
||||||
static struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
static struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
||||||
|
@ -60,7 +59,6 @@ void rt_hw_interrupt_init(void)
|
||||||
/* init exceptions table */
|
/* init exceptions table */
|
||||||
for (idx = 0; idx < MAX_HANDLERS; idx++)
|
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].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
|
||||||
irq_desc[idx].param = RT_NULL;
|
irq_desc[idx].param = RT_NULL;
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
#ifdef RT_USING_INTERRUPT_INFO
|
||||||
|
@ -68,6 +66,8 @@ void rt_hw_interrupt_init(void)
|
||||||
irq_desc[idx].counter = 0;
|
irq_desc[idx].counter = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plic_set_threshold(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +86,7 @@ void rt_hw_interrupt_mask(int vector)
|
||||||
void rt_hw_interrupt_umask(int vector)
|
void rt_hw_interrupt_umask(int vector)
|
||||||
{
|
{
|
||||||
plic_set_priority(vector, 1);
|
plic_set_priority(vector, 1);
|
||||||
plic_set_threshold(0);
|
|
||||||
rt_hw_plic_irq_enable(vector);
|
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 cause = (xcause & 0xFFFFFFFF);
|
||||||
int plic_irq = 0;
|
int plic_irq = 0;
|
||||||
|
|
||||||
if (xcause & (1UL << 63))
|
if (xcause & (1UL << 63))
|
||||||
{
|
{
|
||||||
switch (cause)
|
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:
|
case IRQ_S_TIMER:
|
||||||
tick_isr();
|
tick_isr();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRQ_S_EXT:
|
case IRQ_S_EXT:
|
||||||
plic_irq = plic_claim();
|
plic_irq = plic_claim();
|
||||||
plic_complete(plic_irq);
|
plic_complete(plic_irq);
|
||||||
irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
|
irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRQ_M_EXT:
|
case IRQ_M_EXT:
|
||||||
plic_irq = plic_claim();
|
plic_irq = plic_claim();
|
||||||
plic_complete(plic_irq);
|
plic_complete(plic_irq);
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
#ifndef __RISCV_IO_H__
|
#ifndef __RISCV_IO_H__
|
||||||
#define __RISCV_IO_H__
|
#define __RISCV_IO_H__
|
||||||
|
|
||||||
// which hart (core) is this?
|
static inline uint32_t __raw_hartid(void)
|
||||||
static inline uint32_t r_mhartid()
|
|
||||||
{
|
{
|
||||||
#ifndef RISCV_S_MODE
|
#ifdef RISCV_S_MODE
|
||||||
|
extern int boot_hartid;
|
||||||
|
return boot_hartid;
|
||||||
|
#else
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
asm volatile("csrr %0, mhartid" : "=r" (x) );
|
asm volatile("csrr %0, mhartid" : "=r" (x) );
|
||||||
return x;
|
return x;
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,18 @@
|
||||||
#define XSTATUS_PUM (1 << 18)
|
#define XSTATUS_PUM (1 << 18)
|
||||||
#include <cpuport.h>
|
#include <cpuport.h>
|
||||||
|
|
||||||
|
boot_hartid: .int
|
||||||
|
.global boot_hartid
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
.section ".start", "ax"
|
.section ".start", "ax"
|
||||||
_start:
|
_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
|
# setup stacks per hart
|
||||||
csrr t0, mhartid # read current hart id
|
csrr t0, mhartid # read current hart id
|
||||||
slli t0, t0, 10 # shift left the hart id by 1024
|
slli t0, t0, 10 # shift left the hart id by 1024
|
||||||
|
@ -54,4 +62,4 @@ _start:
|
||||||
|
|
||||||
park:
|
park:
|
||||||
wfi
|
wfi
|
||||||
j park
|
j park
|
||||||
|
|
|
@ -36,7 +36,7 @@ int tick_isr(void)
|
||||||
#ifdef RISCV_S_MODE
|
#ifdef RISCV_S_MODE
|
||||||
sbi_set_timer(get_ticks() + tick_cycles);
|
sbi_set_timer(get_ticks() + tick_cycles);
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -62,7 +62,7 @@ int rt_hw_tick_init(void)
|
||||||
#else
|
#else
|
||||||
clear_csr(mie, MIP_MTIP);
|
clear_csr(mie, MIP_MTIP);
|
||||||
clear_csr(mip, 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);
|
set_csr(mie, MIP_MTIP);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue