mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +00:00
在riscv上实现异常处理,能够进入异常处理程序 (#564)
This commit is contained in:
parent
c3dc6f2ff9
commit
5c4224e5a8
@ -42,7 +42,6 @@ linkme = "=0.2"
|
|||||||
num = { version = "=0.4.0", default-features = false }
|
num = { version = "=0.4.0", default-features = false }
|
||||||
num-derive = "=0.3"
|
num-derive = "=0.3"
|
||||||
num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
|
num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
|
||||||
|
|
||||||
smoltcp = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/smoltcp.git", rev = "9027825", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
|
smoltcp = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/smoltcp.git", rev = "9027825", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
|
||||||
system_error = { path = "crates/system_error" }
|
system_error = { path = "crates/system_error" }
|
||||||
unified-init = { path = "crates/unified-init" }
|
unified-init = { path = "crates/unified-init" }
|
||||||
@ -62,7 +61,7 @@ x86_64 = "=0.14.10"
|
|||||||
|
|
||||||
# target为riscv64时,使用下面的依赖
|
# target为riscv64时,使用下面的依赖
|
||||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||||
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "5c01a8320e", features = [ "s-mode" ] }
|
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "79d27d0f3a", features = [ "s-mode" ] }
|
||||||
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
||||||
|
|
||||||
|
|
||||||
|
20
kernel/src/arch/riscv64/asm/csr.rs
Normal file
20
kernel/src/arch/riscv64/asm/csr.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
pub const CSR_SSTATUS: usize = 0x100;
|
||||||
|
pub const CSR_SSCRATCH: usize = 0x140;
|
||||||
|
pub const CSR_SEPC: usize = 0x141;
|
||||||
|
pub const CSR_SCAUSE: usize = 0x142;
|
||||||
|
pub const CSR_STVAL: usize = 0x143;
|
||||||
|
|
||||||
|
// === Status register flags ===
|
||||||
|
|
||||||
|
/// Previously Supervisor
|
||||||
|
pub const SR_SPP: usize = 0x00000100;
|
||||||
|
/// Supervisor User Memory Access
|
||||||
|
pub const SR_SUM: usize = 0x00040000;
|
||||||
|
|
||||||
|
/// Floating-Point Status
|
||||||
|
pub const SR_FS: usize = 0x00006000;
|
||||||
|
/// Vector status
|
||||||
|
pub const SR_VS: usize = 0x00000600;
|
||||||
|
|
||||||
|
/// Vector and Floating-Point Unit
|
||||||
|
pub const SR_FS_VS: usize = SR_FS | SR_VS;
|
@ -1,31 +1,8 @@
|
|||||||
#include "common/asm.h"
|
#include "common/asm.h"
|
||||||
|
#include "asm/csr.h"
|
||||||
|
|
||||||
.section .bootstrap
|
.section .bootstrap
|
||||||
|
|
||||||
#define CSR_SSTATUS 0x100
|
|
||||||
#define CSR_SIE 0x104
|
|
||||||
#define CSR_STVEC 0x105
|
|
||||||
#define CSR_SIP 0x144
|
|
||||||
|
|
||||||
# define CSR_TVEC CSR_STVEC
|
|
||||||
|
|
||||||
# define CSR_STATUS CSR_SSTATUS
|
|
||||||
#define CSR_IE CSR_SIE
|
|
||||||
#define CSR_IP CSR_SIP
|
|
||||||
|
|
||||||
#define SR_FS 0x00006000
|
|
||||||
#define SR_VS 0x00000600
|
|
||||||
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
|
|
||||||
|
|
||||||
#define SATP_MODE_39 0x8000000000000000ULL
|
|
||||||
#define SATP_MODE_48 0x9000000000000000ULL
|
|
||||||
#define SATP_MODE_57 0xa000000000000000ULL
|
|
||||||
|
|
||||||
#define PAGE_OFFSET 0xffffffc000000000
|
|
||||||
#define KERNEL_LINK_OFFSET 0x1000000
|
|
||||||
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
|
|
||||||
|
|
||||||
|
|
||||||
// 内核入口(从DragonStub跳转到这里)
|
// 内核入口(从DragonStub跳转到这里)
|
||||||
// 参数:
|
// 参数:
|
||||||
// a0: hartid (核心ID)
|
// a0: hartid (核心ID)
|
||||||
@ -86,9 +63,11 @@ ENTRY(_start)
|
|||||||
__init_set_pgtable_loop_end:
|
__init_set_pgtable_loop_end:
|
||||||
call __initial_reloacate_enable_mmu
|
call __initial_reloacate_enable_mmu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.option push
|
.option push
|
||||||
.option norelax
|
.option norelax
|
||||||
|
// 设置栈指针
|
||||||
la a0, BSP_IDLE_STACK_SPACE
|
la a0, BSP_IDLE_STACK_SPACE
|
||||||
mv sp, a0
|
mv sp, a0
|
||||||
li t0, 32752 // 预留16字节防止越界
|
li t0, 32752 // 预留16字节防止越界
|
||||||
@ -101,6 +80,7 @@ __init_set_pgtable_loop_end:
|
|||||||
li t0, SR_FS_VS
|
li t0, SR_FS_VS
|
||||||
csrc CSR_STATUS, t0
|
csrc CSR_STATUS, t0
|
||||||
|
|
||||||
|
|
||||||
/* Call the kernel */
|
/* Call the kernel */
|
||||||
la a0, __initial_hartid_ptr
|
la a0, __initial_hartid_ptr
|
||||||
ld a0, 0(a0)
|
ld a0, 0(a0)
|
||||||
@ -128,7 +108,7 @@ __initial_reloacate_enable_mmu:
|
|||||||
|
|
||||||
/* Point stvec to virtual address of intruction after satp write */
|
/* Point stvec to virtual address of intruction after satp write */
|
||||||
/* Set trap vector to spin forever to help debug */
|
/* Set trap vector to spin forever to help debug */
|
||||||
la a2, 1f
|
la a2, 3f
|
||||||
add a2, a2, t1
|
add a2, a2, t1
|
||||||
csrw CSR_TVEC, a2
|
csrw CSR_TVEC, a2
|
||||||
// enable MMU
|
// enable MMU
|
||||||
@ -142,7 +122,7 @@ __initial_reloacate_enable_mmu:
|
|||||||
sfence.vma
|
sfence.vma
|
||||||
csrw satp, a2
|
csrw satp, a2
|
||||||
|
|
||||||
1:
|
3:
|
||||||
la a0, __initial_Lsecondary_park
|
la a0, __initial_Lsecondary_park
|
||||||
add a0, a0, t1
|
add a0, a0, t1
|
||||||
csrw CSR_TVEC, a0
|
csrw CSR_TVEC, a0
|
||||||
@ -337,6 +317,7 @@ __initial_clear_pgtable_loop:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
__initial_Lsecondary_park:
|
__initial_Lsecondary_park:
|
||||||
/* We lack SMP support or have too many harts, so park this hart */
|
/* We lack SMP support or have too many harts, so park this hart */
|
||||||
|
@ -1 +1,2 @@
|
|||||||
pub mod bitops;
|
pub mod bitops;
|
||||||
|
pub(super) mod csr;
|
||||||
|
@ -7,10 +7,13 @@ use crate::{
|
|||||||
smp::cpu::{ProcessorId, SmpCpuManager},
|
smp::cpu::{ProcessorId, SmpCpuManager},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// 栈对齐
|
||||||
|
pub(super) const STACK_ALIGN: usize = 16;
|
||||||
|
|
||||||
/// 获取当前cpu的id
|
/// 获取当前cpu的id
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn current_cpu_id() -> ProcessorId {
|
pub fn current_cpu_id() -> ProcessorId {
|
||||||
let ptr: *const LocalContext = riscv::register::sscratch::read() as *const LocalContext;
|
let ptr: *const LocalContext = riscv::register::tp::read() as *const LocalContext;
|
||||||
|
|
||||||
if core::intrinsics::unlikely(ptr.is_null()) {
|
if core::intrinsics::unlikely(ptr.is_null()) {
|
||||||
return boot_params().read_irqsave().arch.boot_hartid;
|
return boot_params().read_irqsave().arch.boot_hartid;
|
||||||
@ -34,16 +37,29 @@ pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
|
|||||||
|
|
||||||
/// Per cpu的上下文数据
|
/// Per cpu的上下文数据
|
||||||
///
|
///
|
||||||
/// 每个CPU的sscratch寄存器指向这个结构体
|
/// 每个CPU的tp寄存器指向这个结构体
|
||||||
|
///
|
||||||
|
/// 注意:
|
||||||
|
///
|
||||||
|
/// - 从用户态进入内核态时,会从sscratch寄存器加载这个结构体的地址到tp寄存器,并把sscratch寄存器清零
|
||||||
|
/// - 从内核态进入用户态时,会将tp寄存器的值保存到sscratch寄存器
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct LocalContext {
|
pub(super) struct LocalContext {
|
||||||
/// 当前cpu的id
|
/// 当前cpu的id
|
||||||
current_cpu: ProcessorId,
|
pub current_cpu: ProcessorId,
|
||||||
|
// 当前进程的内核栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
|
||||||
|
pub kernel_sp: usize,
|
||||||
|
// 当前进程的用户栈指针(暂存,当进入中断处理程序的时候需要保存到pcb,进程切换的时候需要重新设置这个值)
|
||||||
|
pub user_sp: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalContext {
|
impl LocalContext {
|
||||||
fn new(cpu: ProcessorId) -> Self {
|
fn new(cpu: ProcessorId) -> Self {
|
||||||
Self { current_cpu: cpu }
|
Self {
|
||||||
|
current_cpu: cpu,
|
||||||
|
kernel_sp: 0,
|
||||||
|
user_sp: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn current_cpu(&self) -> ProcessorId {
|
pub fn current_cpu(&self) -> ProcessorId {
|
||||||
self.current_cpu
|
self.current_cpu
|
||||||
@ -53,16 +69,34 @@ impl LocalContext {
|
|||||||
self.current_cpu = cpu;
|
self.current_cpu = cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn kernel_sp(&self) -> usize {
|
||||||
|
self.kernel_sp
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_kernel_sp(&mut self, sp: usize) {
|
||||||
|
self.kernel_sp = sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_sp(&self) -> usize {
|
||||||
|
self.user_sp
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_user_sp(&mut self, sp: usize) {
|
||||||
|
self.user_sp = sp;
|
||||||
|
}
|
||||||
|
|
||||||
fn sync_to_cpu(&self) {
|
fn sync_to_cpu(&self) {
|
||||||
let ptr = self as *const Self as usize;
|
let ptr = self as *const Self as usize;
|
||||||
riscv::register::sscratch::write(ptr);
|
riscv::register::sscratch::write(0);
|
||||||
|
|
||||||
|
// 写入tp寄存器
|
||||||
|
riscv::register::tp::write(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 初始化本地上下文
|
/// 初始化本地上下文
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub(super) fn init_local_context() {
|
pub(super) fn init_local_context() {
|
||||||
kdebug!("init_local_context");
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
|
|
||||||
for i in 0..PerCpu::MAX_CPU_NUM {
|
for i in 0..PerCpu::MAX_CPU_NUM {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DragonOS/stdint.h>
|
#include "DragonOS/stdint.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <common/stddef.h>
|
#include <common/stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
// RISC-V 没有直接的开启/关闭中断的指令,你需要通过修改CSR寄存器来实现
|
// RISC-V 没有直接的开启/关闭中断的指令,你需要通过修改CSR寄存器来实现
|
||||||
// 你可能需要在你的中断处理程序中处理这些操作
|
// 你可能需要在你的中断处理程序中处理这些操作
|
||||||
@ -15,44 +15,38 @@
|
|||||||
// RISC-V 没有 pause 指令,你可能需要使用其他方法来实现处理器等待
|
// RISC-V 没有 pause 指令,你可能需要使用其他方法来实现处理器等待
|
||||||
|
|
||||||
// RISC-V 使用 fence 指令来实现内存屏障
|
// RISC-V 使用 fence 指令来实现内存屏障
|
||||||
#define io_mfence() __asm__ __volatile__("fence rw,rw\n\t" :: \
|
#define io_mfence() __asm__ __volatile__("fence rw,rw\n\t" ::: "memory")
|
||||||
: "memory")
|
#define io_sfence() __asm__ __volatile__("fence w,w\n\t" ::: "memory")
|
||||||
#define io_sfence() __asm__ __volatile__("fence w,w\n\t" :: \
|
#define io_lfence() __asm__ __volatile__("fence r,r\n\t" ::: "memory")
|
||||||
: "memory")
|
|
||||||
#define io_lfence() __asm__ __volatile__("fence r,r\n\t" :: \
|
|
||||||
: "memory")
|
|
||||||
|
|
||||||
// 开启中断
|
// 开启中断
|
||||||
#define sti() __asm__ __volatile__("csrsi mstatus, 8\n\t" :: \
|
#define sti() __asm__ __volatile__("csrsi mstatus, 8\n\t" ::: "memory")
|
||||||
: "memory")
|
|
||||||
|
|
||||||
// 关闭中断
|
// 关闭中断
|
||||||
#define cli() __asm__ __volatile__("csrci mstatus, 8\n\t" :: \
|
#define cli() __asm__ __volatile__("csrci mstatus, 8\n\t" ::: "memory")
|
||||||
: "memory")
|
|
||||||
|
|
||||||
|
|
||||||
// 从io口读入8个bit
|
// 从io口读入8个bit
|
||||||
unsigned char io_in8(unsigned short port)
|
unsigned char io_in8(unsigned short port) {
|
||||||
{
|
while (1)
|
||||||
while(1);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从io口读入32个bit
|
// 从io口读入32个bit
|
||||||
unsigned int io_in32(unsigned short port)
|
unsigned int io_in32(unsigned short port) {
|
||||||
{
|
while (1)
|
||||||
while(1);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出8个bit到输出端口
|
// 输出8个bit到输出端口
|
||||||
void io_out8(unsigned short port, unsigned char value)
|
void io_out8(unsigned short port, unsigned char value) {
|
||||||
{
|
while (1)
|
||||||
while(1);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出32个bit到输出端口
|
// 输出32个bit到输出端口
|
||||||
void io_out32(unsigned short port, unsigned int value)
|
void io_out32(unsigned short port, unsigned int value) {
|
||||||
{
|
while (1)
|
||||||
while(1);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,6 +57,7 @@ void io_out32(unsigned short port, unsigned int value)
|
|||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool verify_area(uint64_t addr_start, uint64_t length){
|
bool verify_area(uint64_t addr_start, uint64_t length) {
|
||||||
while(1);
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
26
kernel/src/arch/riscv64/include/asm/csr.h
Normal file
26
kernel/src/arch/riscv64/include/asm/csr.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CSR_SSTATUS 0x100
|
||||||
|
#define CSR_SIE 0x104
|
||||||
|
#define CSR_STVEC 0x105
|
||||||
|
#define CSR_SIP 0x144
|
||||||
|
#define CSR_SSCRATCH 0x140
|
||||||
|
|
||||||
|
#define CSR_TVEC CSR_STVEC
|
||||||
|
#define CSR_SCRATCH CSR_SSCRATCH
|
||||||
|
|
||||||
|
#define CSR_STATUS CSR_SSTATUS
|
||||||
|
#define CSR_IE CSR_SIE
|
||||||
|
#define CSR_IP CSR_SIP
|
||||||
|
|
||||||
|
#define SR_FS 0x00006000
|
||||||
|
#define SR_VS 0x00000600
|
||||||
|
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
|
||||||
|
|
||||||
|
#define SATP_MODE_39 0x8000000000000000ULL
|
||||||
|
#define SATP_MODE_48 0x9000000000000000ULL
|
||||||
|
#define SATP_MODE_57 0xa000000000000000ULL
|
||||||
|
|
||||||
|
#define PAGE_OFFSET 0xffffffc000000000
|
||||||
|
#define KERNEL_LINK_OFFSET 0x1000000
|
||||||
|
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
|
@ -3,10 +3,7 @@ use system_error::SystemError;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
|
arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
|
||||||
driver::{
|
driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
|
||||||
firmware::efi::init::efi_init, irqchip::riscv_intc::riscv_intc_init,
|
|
||||||
open_firmware::fdt::open_firmware_fdt_driver,
|
|
||||||
},
|
|
||||||
init::{boot_params, init::start_kernel},
|
init::{boot_params, init::start_kernel},
|
||||||
kdebug, kinfo,
|
kdebug, kinfo,
|
||||||
mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
|
mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
|
||||||
@ -14,7 +11,7 @@ use crate::{
|
|||||||
smp::cpu::ProcessorId,
|
smp::cpu::ProcessorId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{cpu::init_local_context, driver::sbi::console_putstr};
|
use super::{cpu::init_local_context, interrupt::entry::handle_exception};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArchBootParams {
|
pub struct ArchBootParams {
|
||||||
@ -52,10 +49,22 @@ unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
|
|||||||
BOOT_HARTID = hartid as u32;
|
BOOT_HARTID = hartid as u32;
|
||||||
BOOT_FDT_PADDR = fdt_paddr;
|
BOOT_FDT_PADDR = fdt_paddr;
|
||||||
}
|
}
|
||||||
|
setup_trap_vector();
|
||||||
start_kernel();
|
start_kernel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 设置中断、异常处理函数
|
||||||
|
fn setup_trap_vector() {
|
||||||
|
let ptr = handle_exception as *const () as usize;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
riscv::register::stvec::write(ptr, riscv::register::stvec::TrapMode::Direct);
|
||||||
|
// Set sup0 scratch register to 0, indicating to exception vector that
|
||||||
|
// we are presently executing in kernel.
|
||||||
|
riscv::register::sscratch::write(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
|
fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
|
||||||
(0..n_spaces).for_each(|_| print!(" "));
|
(0..n_spaces).for_each(|_| print!(" "));
|
||||||
|
327
kernel/src/arch/riscv64/interrupt/entry.rs
Normal file
327
kernel/src/arch/riscv64/interrupt/entry.rs
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
use crate::arch::{
|
||||||
|
asm::csr::{
|
||||||
|
CSR_SCAUSE, CSR_SEPC, CSR_SSCRATCH, CSR_SSTATUS, CSR_STVAL, SR_FS_VS, SR_SPP, SR_SUM,
|
||||||
|
},
|
||||||
|
cpu::LocalContext,
|
||||||
|
interrupt::TrapFrame,
|
||||||
|
};
|
||||||
|
use core::arch::asm;
|
||||||
|
use kdepends::memoffset::offset_of;
|
||||||
|
|
||||||
|
/// 保存x6-x31寄存器
|
||||||
|
macro_rules! save_from_x6_to_x31 {
|
||||||
|
() => {
|
||||||
|
concat!(
|
||||||
|
"
|
||||||
|
sd x6, {off_t1}(sp)
|
||||||
|
sd x7, {off_t2}(sp)
|
||||||
|
sd x8, {off_s0}(sp)
|
||||||
|
sd x9, {off_s1}(sp)
|
||||||
|
sd x10, {off_a0}(sp)
|
||||||
|
sd x11, {off_a1}(sp)
|
||||||
|
sd x12, {off_a2}(sp)
|
||||||
|
sd x13, {off_a3}(sp)
|
||||||
|
sd x14, {off_a4}(sp)
|
||||||
|
sd x15, {off_a5}(sp)
|
||||||
|
sd x16, {off_a6}(sp)
|
||||||
|
sd x17, {off_a7}(sp)
|
||||||
|
sd x18, {off_s2}(sp)
|
||||||
|
sd x19, {off_s3}(sp)
|
||||||
|
sd x20, {off_s4}(sp)
|
||||||
|
sd x21, {off_s5}(sp)
|
||||||
|
sd x22, {off_s6}(sp)
|
||||||
|
sd x23, {off_s7}(sp)
|
||||||
|
sd x24, {off_s8}(sp)
|
||||||
|
sd x25, {off_s9}(sp)
|
||||||
|
sd x26, {off_s10}(sp)
|
||||||
|
sd x27, {off_s11}(sp)
|
||||||
|
sd x28, {off_t3}(sp)
|
||||||
|
sd x29, {off_t4}(sp)
|
||||||
|
sd x30, {off_t5}(sp)
|
||||||
|
sd x31, {off_t6}(sp)
|
||||||
|
|
||||||
|
"
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! restore_from_x6_to_x31 {
|
||||||
|
() => {
|
||||||
|
concat!("
|
||||||
|
|
||||||
|
ld x6, {off_t1}(sp)
|
||||||
|
ld x7, {off_t2}(sp)
|
||||||
|
ld x8, {off_s0}(sp)
|
||||||
|
ld x9, {off_s1}(sp)
|
||||||
|
ld x10, {off_a0}(sp)
|
||||||
|
ld x11, {off_a1}(sp)
|
||||||
|
ld x12, {off_a2}(sp)
|
||||||
|
ld x13, {off_a3}(sp)
|
||||||
|
ld x14, {off_a4}(sp)
|
||||||
|
ld x15, {off_a5}(sp)
|
||||||
|
ld x16, {off_a6}(sp)
|
||||||
|
ld x17, {off_a7}(sp)
|
||||||
|
ld x18, {off_s2}(sp)
|
||||||
|
ld x19, {off_s3}(sp)
|
||||||
|
ld x20, {off_s4}(sp)
|
||||||
|
ld x21, {off_s5}(sp)
|
||||||
|
ld x22, {off_s6}(sp)
|
||||||
|
ld x23, {off_s7}(sp)
|
||||||
|
ld x24, {off_s8}(sp)
|
||||||
|
ld x25, {off_s9}(sp)
|
||||||
|
ld x26, {off_s10}(sp)
|
||||||
|
ld x27, {off_s11}(sp)
|
||||||
|
ld x28, {off_t3}(sp)
|
||||||
|
ld x29, {off_t4}(sp)
|
||||||
|
ld x30, {off_t5}(sp)
|
||||||
|
ld x31, {off_t6}(sp)
|
||||||
|
")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Riscv64中断处理入口
|
||||||
|
#[naked]
|
||||||
|
#[no_mangle]
|
||||||
|
#[repr(align(4))]
|
||||||
|
pub unsafe extern "C" fn handle_exception() -> ! {
|
||||||
|
asm!(
|
||||||
|
concat!("
|
||||||
|
/*
|
||||||
|
* If coming from userspace, preserve the user thread pointer and load
|
||||||
|
* the kernel thread pointer. If we came from the kernel, the scratch
|
||||||
|
* register will contain 0, and we should continue on the current TP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
csrrw tp, {csr_scratch}, tp
|
||||||
|
bnez tp, _save_context
|
||||||
|
|
||||||
|
/* 从内核态进入中断 */
|
||||||
|
j {_restore_kernel_tpsp}
|
||||||
|
"),
|
||||||
|
csr_scratch = const CSR_SSCRATCH,
|
||||||
|
_restore_kernel_tpsp = sym _restore_kernel_tpsp,
|
||||||
|
options(noreturn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[naked]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn _restore_kernel_tpsp() -> ! {
|
||||||
|
asm!(
|
||||||
|
concat!("
|
||||||
|
// 这次是从内核态进入中断
|
||||||
|
// 从sscratch寄存器加载当前cpu的上下文
|
||||||
|
csrr tp, {csr_scratch}
|
||||||
|
|
||||||
|
// 把当前的sp寄存器的值保存到当前cpu的上下文的kernel_sp字段
|
||||||
|
sd sp, {lc_off_kernel_sp}(tp)
|
||||||
|
|
||||||
|
j {_save_context}
|
||||||
|
"),
|
||||||
|
csr_scratch = const CSR_SSCRATCH,
|
||||||
|
lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
|
||||||
|
_save_context = sym _save_context,
|
||||||
|
|
||||||
|
options(noreturn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[naked]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn _save_context() -> ! {
|
||||||
|
asm!(
|
||||||
|
concat!("
|
||||||
|
|
||||||
|
|
||||||
|
// 保存当前cpu的上下文
|
||||||
|
|
||||||
|
// 保存用户sp
|
||||||
|
sd sp, {lc_off_user_sp}(tp)
|
||||||
|
// 加载内核sp
|
||||||
|
ld sp, {lc_off_kernel_sp}(tp)
|
||||||
|
|
||||||
|
addi sp, sp, -{trap_frame_size_on_stack}
|
||||||
|
sd x1, {off_ra}(sp)
|
||||||
|
sd x3, {off_gp}(sp)
|
||||||
|
sd x5, {off_t0}(sp)
|
||||||
|
",
|
||||||
|
save_from_x6_to_x31!(),
|
||||||
|
"
|
||||||
|
/*
|
||||||
|
* Disable user-mode memory access as it should only be set in the
|
||||||
|
* actual user copy routines.
|
||||||
|
*
|
||||||
|
* Disable the FPU/Vector to detect illegal usage of floating point
|
||||||
|
* or vector in kernel space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
li t0, {sr_sum_and_fsvs}
|
||||||
|
|
||||||
|
ld s0, {lc_off_user_sp}(tp)
|
||||||
|
csrrc s1, {csr_status}, t0
|
||||||
|
csrr s2, {csr_epc}
|
||||||
|
csrr s3, {csr_tval}
|
||||||
|
csrr s4, {csr_cause}
|
||||||
|
csrr s5, {csr_scratch}
|
||||||
|
sd s0, {off_sp}(sp)
|
||||||
|
sd s1, {off_status}(sp)
|
||||||
|
sd s2, {off_epc}(sp)
|
||||||
|
sd s3, {off_badaddr}(sp)
|
||||||
|
sd s4, {off_cause}(sp)
|
||||||
|
sd s5, {off_tp}(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the scratch register to 0, so that if a recursive exception
|
||||||
|
* occurs, the exception vector knows it came from the kernel
|
||||||
|
*/
|
||||||
|
|
||||||
|
csrw {csr_scratch}, x0
|
||||||
|
|
||||||
|
/* Load the global pointer */
|
||||||
|
// linux 加载了global pointer,但是我们暂时没有用到
|
||||||
|
|
||||||
|
// .option push
|
||||||
|
// .option norelax
|
||||||
|
// la gp, __global_pointer$
|
||||||
|
// .option pop
|
||||||
|
|
||||||
|
mv a0, sp
|
||||||
|
la ra, ret_from_exception
|
||||||
|
|
||||||
|
tail riscv64_do_irq
|
||||||
|
"
|
||||||
|
),
|
||||||
|
|
||||||
|
lc_off_user_sp = const offset_of!(LocalContext, user_sp),
|
||||||
|
lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
|
||||||
|
trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
|
||||||
|
off_ra = const offset_of!(TrapFrame, ra),
|
||||||
|
off_gp = const offset_of!(TrapFrame, gp),
|
||||||
|
off_t0 = const offset_of!(TrapFrame, t0),
|
||||||
|
off_t1 = const offset_of!(TrapFrame, t1),
|
||||||
|
off_t2 = const offset_of!(TrapFrame, t2),
|
||||||
|
off_s0 = const offset_of!(TrapFrame, s0),
|
||||||
|
off_s1 = const offset_of!(TrapFrame, s1),
|
||||||
|
off_a0 = const offset_of!(TrapFrame, a0),
|
||||||
|
off_a1 = const offset_of!(TrapFrame, a1),
|
||||||
|
off_a2 = const offset_of!(TrapFrame, a2),
|
||||||
|
off_a3 = const offset_of!(TrapFrame, a3),
|
||||||
|
off_a4 = const offset_of!(TrapFrame, a4),
|
||||||
|
off_a5 = const offset_of!(TrapFrame, a5),
|
||||||
|
off_a6 = const offset_of!(TrapFrame, a6),
|
||||||
|
off_a7 = const offset_of!(TrapFrame, a7),
|
||||||
|
off_s2 = const offset_of!(TrapFrame, s2),
|
||||||
|
off_s3 = const offset_of!(TrapFrame, s3),
|
||||||
|
off_s4 = const offset_of!(TrapFrame, s4),
|
||||||
|
off_s5 = const offset_of!(TrapFrame, s5),
|
||||||
|
off_s6 = const offset_of!(TrapFrame, s6),
|
||||||
|
off_s7 = const offset_of!(TrapFrame, s7),
|
||||||
|
off_s8 = const offset_of!(TrapFrame, s8),
|
||||||
|
off_s9 = const offset_of!(TrapFrame, s9),
|
||||||
|
off_s10 = const offset_of!(TrapFrame, s10),
|
||||||
|
off_s11 = const offset_of!(TrapFrame, s11),
|
||||||
|
off_t3 = const offset_of!(TrapFrame, t3),
|
||||||
|
off_t4 = const offset_of!(TrapFrame, t4),
|
||||||
|
off_t5 = const offset_of!(TrapFrame, t5),
|
||||||
|
off_t6 = const offset_of!(TrapFrame, t6),
|
||||||
|
off_sp = const offset_of!(TrapFrame, sp),
|
||||||
|
off_status = const offset_of!(TrapFrame, status),
|
||||||
|
off_badaddr = const offset_of!(TrapFrame, badaddr),
|
||||||
|
off_cause = const offset_of!(TrapFrame, cause),
|
||||||
|
off_tp = const offset_of!(TrapFrame, tp),
|
||||||
|
off_epc = const offset_of!(TrapFrame, epc),
|
||||||
|
sr_sum_and_fsvs = const (SR_FS_VS | SR_SUM),
|
||||||
|
csr_status = const CSR_SSTATUS,
|
||||||
|
csr_epc = const CSR_SEPC,
|
||||||
|
csr_tval = const CSR_STVAL,
|
||||||
|
csr_cause = const CSR_SCAUSE,
|
||||||
|
csr_scratch = const CSR_SSCRATCH,
|
||||||
|
options(noreturn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[naked]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn ret_from_exception() -> ! {
|
||||||
|
asm!(
|
||||||
|
concat!("
|
||||||
|
ld s0, {off_status}(sp)
|
||||||
|
andi s0, s0, {sr_spp}
|
||||||
|
|
||||||
|
bnez s0, 3f
|
||||||
|
|
||||||
|
// Save unwound kernel stack pointer in thread_info
|
||||||
|
addi s0, sp, {trap_frame_size_on_stack}
|
||||||
|
sd s0, {lc_off_kernel_sp}(tp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save TP into the scratch register , so we can find the kernel data
|
||||||
|
* structures again.
|
||||||
|
*/
|
||||||
|
csrw {csr_scratch}, tp
|
||||||
|
3:
|
||||||
|
|
||||||
|
ld a0, {off_status}(sp)
|
||||||
|
|
||||||
|
ld a2, {off_epc}(sp)
|
||||||
|
sc.d x0, a2, {off_epc}(sp)
|
||||||
|
|
||||||
|
csrw {csr_status}, a0
|
||||||
|
csrw {csr_epc}, a2
|
||||||
|
|
||||||
|
ld x1, {off_ra}(sp)
|
||||||
|
ld x3, {off_gp}(sp)
|
||||||
|
ld x4, {off_tp}(sp)
|
||||||
|
ld x5, {off_t0}(sp)
|
||||||
|
|
||||||
|
",
|
||||||
|
restore_from_x6_to_x31!(),
|
||||||
|
"
|
||||||
|
ld x2, {off_sp}(sp)
|
||||||
|
|
||||||
|
sret
|
||||||
|
"
|
||||||
|
),
|
||||||
|
off_status = const offset_of!(TrapFrame, status),
|
||||||
|
sr_spp = const SR_SPP,
|
||||||
|
trap_frame_size_on_stack = const TrapFrame::SIZE_ON_STACK,
|
||||||
|
lc_off_kernel_sp = const offset_of!(LocalContext, kernel_sp),
|
||||||
|
csr_scratch = const CSR_SSCRATCH,
|
||||||
|
csr_status = const CSR_SSTATUS,
|
||||||
|
csr_epc = const CSR_SEPC,
|
||||||
|
off_ra = const offset_of!(TrapFrame, ra),
|
||||||
|
off_gp = const offset_of!(TrapFrame, gp),
|
||||||
|
off_t0 = const offset_of!(TrapFrame, t0),
|
||||||
|
off_t1 = const offset_of!(TrapFrame, t1),
|
||||||
|
off_t2 = const offset_of!(TrapFrame, t2),
|
||||||
|
off_s0 = const offset_of!(TrapFrame, s0),
|
||||||
|
off_s1 = const offset_of!(TrapFrame, s1),
|
||||||
|
off_a0 = const offset_of!(TrapFrame, a0),
|
||||||
|
off_a1 = const offset_of!(TrapFrame, a1),
|
||||||
|
off_a2 = const offset_of!(TrapFrame, a2),
|
||||||
|
off_a3 = const offset_of!(TrapFrame, a3),
|
||||||
|
off_a4 = const offset_of!(TrapFrame, a4),
|
||||||
|
off_a5 = const offset_of!(TrapFrame, a5),
|
||||||
|
off_a6 = const offset_of!(TrapFrame, a6),
|
||||||
|
off_a7 = const offset_of!(TrapFrame, a7),
|
||||||
|
off_s2 = const offset_of!(TrapFrame, s2),
|
||||||
|
off_s3 = const offset_of!(TrapFrame, s3),
|
||||||
|
off_s4 = const offset_of!(TrapFrame, s4),
|
||||||
|
off_s5 = const offset_of!(TrapFrame, s5),
|
||||||
|
off_s6 = const offset_of!(TrapFrame, s6),
|
||||||
|
off_s7 = const offset_of!(TrapFrame, s7),
|
||||||
|
off_s8 = const offset_of!(TrapFrame, s8),
|
||||||
|
off_s9 = const offset_of!(TrapFrame, s9),
|
||||||
|
off_s10 = const offset_of!(TrapFrame, s10),
|
||||||
|
off_s11 = const offset_of!(TrapFrame, s11),
|
||||||
|
off_t3 = const offset_of!(TrapFrame, t3),
|
||||||
|
off_t4 = const offset_of!(TrapFrame, t4),
|
||||||
|
off_t5 = const offset_of!(TrapFrame, t5),
|
||||||
|
off_t6 = const offset_of!(TrapFrame, t6),
|
||||||
|
off_sp = const offset_of!(TrapFrame, sp),
|
||||||
|
off_tp = const offset_of!(TrapFrame, tp),
|
||||||
|
off_epc = const offset_of!(TrapFrame, epc),
|
||||||
|
|
||||||
|
options(noreturn),
|
||||||
|
)
|
||||||
|
}
|
172
kernel/src/arch/riscv64/interrupt/handle.rs
Normal file
172
kernel/src/arch/riscv64/interrupt/handle.rs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
use core::hint::spin_loop;
|
||||||
|
|
||||||
|
use system_error::SystemError;
|
||||||
|
|
||||||
|
use crate::{kdebug, kerror};
|
||||||
|
|
||||||
|
use super::TrapFrame;
|
||||||
|
|
||||||
|
type ExceptionHandler = fn(&mut TrapFrame) -> Result<(), SystemError>;
|
||||||
|
|
||||||
|
static EXCEPTION_HANDLERS: [ExceptionHandler; 16] = [
|
||||||
|
do_trap_insn_misaligned, // 0
|
||||||
|
do_trap_insn_access_fault, // 1
|
||||||
|
do_trap_insn_illegal, // 2
|
||||||
|
do_trap_break, // 3
|
||||||
|
do_trap_load_misaligned, // 4
|
||||||
|
do_trap_load_access_fault, // 5
|
||||||
|
do_trap_store_misaligned, // 6
|
||||||
|
do_trap_store_access_fault, // 7
|
||||||
|
do_trap_user_env_call, // 8
|
||||||
|
default_handler, // 9
|
||||||
|
default_handler, // 10
|
||||||
|
default_handler, // 11
|
||||||
|
do_trap_insn_page_fault, // 12
|
||||||
|
do_trap_load_page_fault, // 13
|
||||||
|
default_handler, // 14
|
||||||
|
do_trap_store_page_fault, // 15
|
||||||
|
];
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn riscv64_do_irq(trap_frame: &mut TrapFrame) {
|
||||||
|
if trap_frame.cause.is_interrupt() {
|
||||||
|
riscv64_do_interrupt(trap_frame);
|
||||||
|
} else if trap_frame.cause.is_exception() {
|
||||||
|
riscv64_do_exception(trap_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理中断
|
||||||
|
fn riscv64_do_interrupt(_trap_frame: &mut TrapFrame) {
|
||||||
|
kdebug!("todo: riscv64_do_irq: interrupt");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理异常
|
||||||
|
fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
|
||||||
|
kdebug!(
|
||||||
|
"riscv64_do_exception: from_user: {}",
|
||||||
|
trap_frame.from_user()
|
||||||
|
);
|
||||||
|
let code = trap_frame.cause.code();
|
||||||
|
|
||||||
|
if code < EXCEPTION_HANDLERS.len() {
|
||||||
|
let handler = EXCEPTION_HANDLERS[code];
|
||||||
|
handler(trap_frame).ok();
|
||||||
|
} else {
|
||||||
|
kerror!("riscv64_do_irq: exception code out of range");
|
||||||
|
loop {
|
||||||
|
// kernel die
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_handler(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: handler not found");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理指令地址不对齐异常 #0
|
||||||
|
fn do_trap_insn_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_insn_misaligned");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理指令访问异常 #1
|
||||||
|
fn do_trap_insn_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_insn_access_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理非法指令异常 #2
|
||||||
|
fn do_trap_insn_illegal(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_insn_illegal");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理断点异常 #3
|
||||||
|
fn do_trap_break(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_break");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理加载地址不对齐异常 #4
|
||||||
|
fn do_trap_load_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_load_misaligned");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理加载访问异常 #5
|
||||||
|
fn do_trap_load_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_load_access_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理存储地址不对齐异常 #6
|
||||||
|
fn do_trap_store_misaligned(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_store_misaligned");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理存储访问异常 #7
|
||||||
|
fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_store_access_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理环境调用异常 #8
|
||||||
|
fn do_trap_user_env_call(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_user_env_call");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9-11 reserved
|
||||||
|
|
||||||
|
/// 处理指令页错误异常 #12
|
||||||
|
fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_insn_page_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理页加载错误异常 #13
|
||||||
|
fn do_trap_load_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_load_page_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 14 reserved
|
||||||
|
|
||||||
|
/// 处理页存储错误异常 #15
|
||||||
|
fn do_trap_store_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
|
kerror!("riscv64_do_irq: do_trap_store_page_fault");
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,16 @@
|
|||||||
|
use riscv::register::{scause::Scause, sstatus::Sstatus};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::irqchip::riscv_intc::riscv_intc_init,
|
driver::irqchip::riscv_intc::riscv_intc_init,
|
||||||
exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
|
exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
|
||||||
|
libs::align::align_up,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::cpu::STACK_ALIGN;
|
||||||
|
|
||||||
|
pub(super) mod entry;
|
||||||
|
mod handle;
|
||||||
pub mod ipi;
|
pub mod ipi;
|
||||||
|
|
||||||
pub struct RiscV64InterruptArch;
|
pub struct RiscV64InterruptArch;
|
||||||
@ -55,12 +61,54 @@ impl InterruptArch for RiscV64InterruptArch {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct TrapFrame {
|
pub struct TrapFrame {
|
||||||
// todo
|
epc: usize,
|
||||||
|
ra: usize,
|
||||||
|
sp: usize,
|
||||||
|
gp: usize,
|
||||||
|
tp: usize,
|
||||||
|
t0: usize,
|
||||||
|
t1: usize,
|
||||||
|
t2: usize,
|
||||||
|
s0: usize,
|
||||||
|
s1: usize,
|
||||||
|
a0: usize,
|
||||||
|
a1: usize,
|
||||||
|
a2: usize,
|
||||||
|
a3: usize,
|
||||||
|
a4: usize,
|
||||||
|
a5: usize,
|
||||||
|
a6: usize,
|
||||||
|
a7: usize,
|
||||||
|
s2: usize,
|
||||||
|
s3: usize,
|
||||||
|
s4: usize,
|
||||||
|
s5: usize,
|
||||||
|
s6: usize,
|
||||||
|
s7: usize,
|
||||||
|
s8: usize,
|
||||||
|
s9: usize,
|
||||||
|
s10: usize,
|
||||||
|
s11: usize,
|
||||||
|
t3: usize,
|
||||||
|
t4: usize,
|
||||||
|
t5: usize,
|
||||||
|
t6: usize,
|
||||||
|
// 以下是中断发生时自动保存的寄存器
|
||||||
|
status: Sstatus,
|
||||||
|
badaddr: usize,
|
||||||
|
cause: Scause,
|
||||||
|
/// a0 value before the syscall
|
||||||
|
origin_a0: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrapFrame {
|
impl TrapFrame {
|
||||||
|
/// 中断栈帧结构体的大小
|
||||||
|
pub const SIZE: usize = core::mem::size_of::<TrapFrame>();
|
||||||
|
|
||||||
|
/// 中断栈帧在栈上的大小
|
||||||
|
pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN);
|
||||||
/// 判断当前中断是否来自用户模式
|
/// 判断当前中断是否来自用户模式
|
||||||
pub fn from_user(&self) -> bool {
|
pub fn from_user(&self) -> bool {
|
||||||
unimplemented!("TrapFrame::from_user")
|
self.status.spp() == riscv::register::sstatus::SPP::User
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ use crate::{
|
|||||||
process::ProcessManager,
|
process::ProcessManager,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 信号处理的栈的栈指针的最小对齐数量
|
|
||||||
pub const STACK_ALIGN: u64 = 16;
|
|
||||||
/// 信号最大值
|
/// 信号最大值
|
||||||
pub const MAX_SIG_NUM: usize = 64;
|
pub const MAX_SIG_NUM: usize = 64;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -5,6 +5,7 @@ use crate::smp::SMPArch;
|
|||||||
pub struct RiscV64SMPArch;
|
pub struct RiscV64SMPArch;
|
||||||
|
|
||||||
impl SMPArch for RiscV64SMPArch {
|
impl SMPArch for RiscV64SMPArch {
|
||||||
|
#[inline(never)]
|
||||||
fn prepare_cpus() -> Result<(), SystemError> {
|
fn prepare_cpus() -> Result<(), SystemError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DragonOS/stdint.h>
|
#include "DragonOS/stdint.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef unsigned char u_char;
|
typedef unsigned char u_char;
|
||||||
|
@ -62,9 +62,8 @@ fn do_start_kernel() {
|
|||||||
|
|
||||||
early_smp_init().expect("early smp init failed");
|
early_smp_init().expect("early smp init failed");
|
||||||
irq_init().expect("irq init failed");
|
irq_init().expect("irq init failed");
|
||||||
CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");
|
|
||||||
|
|
||||||
setup_arch().expect("setup_arch failed");
|
setup_arch().expect("setup_arch failed");
|
||||||
|
CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");
|
||||||
|
|
||||||
process_init();
|
process_init();
|
||||||
sched_init();
|
sched_init();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![feature(arbitrary_self_types)]
|
#![feature(arbitrary_self_types)]
|
||||||
#![feature(asm_const)]
|
#![feature(asm_const)]
|
||||||
|
#![feature(concat_idents)]
|
||||||
#![feature(const_for)]
|
#![feature(const_for)]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
@ -11,16 +12,16 @@
|
|||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(c_void_variant)]
|
#![feature(c_void_variant)]
|
||||||
#![feature(extract_if)]
|
#![feature(extract_if)]
|
||||||
|
#![feature(fn_align)]
|
||||||
#![feature(inline_const)]
|
#![feature(inline_const)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
|
#![feature(new_uninit)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![feature(ptr_internals)]
|
#![feature(ptr_internals)]
|
||||||
|
#![feature(ptr_to_from_bits)]
|
||||||
#![feature(trait_upcasting)]
|
#![feature(trait_upcasting)]
|
||||||
#![feature(slice_ptr_get)]
|
#![feature(slice_ptr_get)]
|
||||||
#![feature(vec_into_raw_parts)]
|
#![feature(vec_into_raw_parts)]
|
||||||
#![feature(new_uninit)]
|
|
||||||
#![feature(ptr_to_from_bits)]
|
|
||||||
#![feature(concat_idents)]
|
|
||||||
#![cfg_attr(target_os = "none", no_std)]
|
#![cfg_attr(target_os = "none", no_std)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -126,16 +126,26 @@ unsafe impl<const NUM: usize> SafeForZero for [u8; NUM] {}
|
|||||||
/// 参数 `addr`:要对齐的地址。
|
/// 参数 `addr`:要对齐的地址。
|
||||||
///
|
///
|
||||||
/// 返回值:对齐后的地址。
|
/// 返回值:对齐后的地址。
|
||||||
pub fn page_align_up(addr: usize) -> usize {
|
pub const fn page_align_up(addr: usize) -> usize {
|
||||||
let page_size = MMArch::PAGE_SIZE;
|
let page_size = MMArch::PAGE_SIZE;
|
||||||
return (addr + page_size - 1) & (!(page_size - 1));
|
return (addr + page_size - 1) & (!(page_size - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_align_down(addr: usize) -> usize {
|
pub const fn page_align_down(addr: usize) -> usize {
|
||||||
let page_size = MMArch::PAGE_SIZE;
|
let page_size = MMArch::PAGE_SIZE;
|
||||||
return addr & (!(page_size - 1));
|
return addr & (!(page_size - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn align_up(addr: usize, align: usize) -> usize {
|
||||||
|
assert!(align != 0 && align.is_power_of_two());
|
||||||
|
return (addr + align - 1) & (!(align - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn align_down(addr: usize, align: usize) -> usize {
|
||||||
|
assert!(align != 0 && align.is_power_of_two());
|
||||||
|
return addr & (!(align - 1));
|
||||||
|
}
|
||||||
|
|
||||||
/// ## 检查是否对齐
|
/// ## 检查是否对齐
|
||||||
///
|
///
|
||||||
/// 检查给定的值是否对齐到给定的对齐要求。
|
/// 检查给定的值是否对齐到给定的对齐要求。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user