mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
riscv: 把内核编译target改为riscv64gc & 获取time csr的频率 & 修正浮点保存与恢复的汇编的问题 (#699)
* 1. 把内核编译target改为riscv64gc 2. fix: 修正浮点保存与恢复的汇编的问题 * riscv: 获取time csr的频率
This commit is contained in:
parent
f0c87a897f
commit
23ef2b33d1
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,4 +20,3 @@ Cargo.lock
|
|||||||
.cache
|
.cache
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
/logs/
|
/logs/
|
||||||
.vscode
|
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -152,7 +152,7 @@
|
|||||||
"./tools/Cargo.toml",
|
"./tools/Cargo.toml",
|
||||||
|
|
||||||
],
|
],
|
||||||
// "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
|
// "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
|
||||||
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
"rust-analyzer.check.overrideCommand": [
|
"rust-analyzer.check.overrideCommand": [
|
||||||
"make",
|
"make",
|
||||||
|
@ -31,8 +31,9 @@ impl CFilesArch for RiscV64CFilesArch {
|
|||||||
// // c.flag("-march=rv64imafdc");
|
// // c.flag("-march=rv64imafdc");
|
||||||
// c.no_default_flags(true);
|
// c.no_default_flags(true);
|
||||||
c.flag("-mcmodel=medany");
|
c.flag("-mcmodel=medany");
|
||||||
c.flag("-mabi=lp64");
|
|
||||||
c.flag("-march=rv64imac");
|
c.flag("-mabi=lp64d");
|
||||||
|
c.flag("-march=rv64gc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(cfg_target_abi)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate cc;
|
extern crate cc;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
为了能支持vscode的调试功能,我们需要修改`.vscode/settings.json`文件的以下行:
|
为了能支持vscode的调试功能,我们需要修改`.vscode/settings.json`文件的以下行:
|
||||||
```
|
```
|
||||||
"rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
|
"rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
|
||||||
// "rust-analyzer.cargo.target": "x86_64-unknown-none",
|
// "rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ include ./env.mk
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
|
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
export TARGET_JSON=arch/riscv64/riscv64imac-unknown-none-elf.json
|
export TARGET_JSON=riscv64gc-unknown-none-elf
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
|
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
|
||||||
@ -38,7 +38,7 @@ check: ECHO
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
@ -36,7 +36,7 @@ export GLOBAL_CFLAGS := -fno-builtin -fno-stack-protector -D $(CFLAGS_DEFINE_ARC
|
|||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
GLOBAL_CFLAGS += -mcmodel=large -m64
|
GLOBAL_CFLAGS += -mcmodel=large -m64
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
GLOBAL_CFLAGS += -mcmodel=medany -march=rv64imac -mabi=lp64
|
GLOBAL_CFLAGS += -mcmodel=medany -march=rv64gc -mabi=lp64d
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DEBUG), DEBUG)
|
ifeq ($(DEBUG), DEBUG)
|
||||||
|
@ -65,7 +65,7 @@ kernel: $(kernel_subdirs) kernel_rust
|
|||||||
|
|
||||||
__link_riscv64_kernel:
|
__link_riscv64_kernel:
|
||||||
@echo "Linking kernel..."
|
@echo "Linking kernel..."
|
||||||
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64imac-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
||||||
$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
||||||
@rm kernel
|
@rm kernel
|
||||||
$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
|
$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
|
||||||
|
@ -3,7 +3,6 @@ use sbi_rt::HartMask;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
init::boot_params,
|
init::boot_params,
|
||||||
kdebug,
|
|
||||||
mm::percpu::{PerCpu, PerCpuVar},
|
mm::percpu::{PerCpu, PerCpuVar},
|
||||||
smp::cpu::{ProcessorId, SmpCpuManager},
|
smp::cpu::{ProcessorId, SmpCpuManager},
|
||||||
};
|
};
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
pub mod of;
|
||||||
pub mod sbi;
|
pub mod sbi;
|
||||||
|
40
kernel/src/arch/riscv64/driver/of.rs
Normal file
40
kernel/src/arch/riscv64/driver/of.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use system_error::SystemError;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
driver::open_firmware::fdt::OpenFirmwareFdtDriver,
|
||||||
|
init::boot_params,
|
||||||
|
libs::align::page_align_up,
|
||||||
|
mm::{mmio_buddy::mmio_pool, MemoryManagementArch, PhysAddr},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl OpenFirmwareFdtDriver {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub unsafe fn map_fdt(&self) -> Result<(), SystemError> {
|
||||||
|
let bp_guard = boot_params().read();
|
||||||
|
let fdt_size = bp_guard.arch.fdt_size;
|
||||||
|
let fdt_paddr = bp_guard.arch.fdt_paddr;
|
||||||
|
|
||||||
|
let offset = fdt_paddr.data() & crate::arch::MMArch::PAGE_OFFSET_MASK;
|
||||||
|
let map_size = page_align_up(fdt_size + offset);
|
||||||
|
let map_paddr = PhysAddr::new(fdt_paddr.data() & crate::arch::MMArch::PAGE_MASK);
|
||||||
|
// kdebug!(
|
||||||
|
// "map_fdt paddr: {:?}, map_pa: {:?},fdt_size: {}, size: {:?}",
|
||||||
|
// fdt_paddr,
|
||||||
|
// map_paddr,
|
||||||
|
// fdt_size,
|
||||||
|
// map_size
|
||||||
|
// );
|
||||||
|
let mmio_guard = mmio_pool().create_mmio(map_size)?;
|
||||||
|
|
||||||
|
// drop the boot params guard in order to avoid deadlock
|
||||||
|
drop(bp_guard);
|
||||||
|
mmio_guard.map_phys(map_paddr, map_size)?;
|
||||||
|
let mut bp_guard = boot_params().write();
|
||||||
|
let vaddr = mmio_guard.vaddr() + offset;
|
||||||
|
|
||||||
|
self.set_fdt_map_guard(Some(mmio_guard));
|
||||||
|
bp_guard.arch.fdt_vaddr.replace(vaddr);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ pub struct ArchBootParams {
|
|||||||
/// 启动时的fdt物理地址
|
/// 启动时的fdt物理地址
|
||||||
pub fdt_paddr: PhysAddr,
|
pub fdt_paddr: PhysAddr,
|
||||||
pub fdt_vaddr: Option<VirtAddr>,
|
pub fdt_vaddr: Option<VirtAddr>,
|
||||||
|
pub fdt_size: usize,
|
||||||
|
|
||||||
pub boot_hartid: ProcessorId,
|
pub boot_hartid: ProcessorId,
|
||||||
}
|
}
|
||||||
@ -26,6 +27,7 @@ impl ArchBootParams {
|
|||||||
pub const DEFAULT: Self = ArchBootParams {
|
pub const DEFAULT: Self = ArchBootParams {
|
||||||
fdt_paddr: PhysAddr::new(0),
|
fdt_paddr: PhysAddr::new(0),
|
||||||
fdt_vaddr: None,
|
fdt_vaddr: None,
|
||||||
|
fdt_size: 0,
|
||||||
boot_hartid: ProcessorId::new(0),
|
boot_hartid: ProcessorId::new(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,8 +105,12 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
|||||||
let hartid = unsafe { BOOT_HARTID };
|
let hartid = unsafe { BOOT_HARTID };
|
||||||
let fdt_paddr = unsafe { BOOT_FDT_PADDR };
|
let fdt_paddr = unsafe { BOOT_FDT_PADDR };
|
||||||
|
|
||||||
|
let fdt =
|
||||||
|
unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
|
||||||
|
|
||||||
let mut arch_boot_params_guard = boot_params().write();
|
let mut arch_boot_params_guard = boot_params().write();
|
||||||
arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
|
arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
|
||||||
|
arch_boot_params_guard.arch.fdt_size = fdt.total_size();
|
||||||
arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
|
arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
|
||||||
|
|
||||||
drop(arch_boot_params_guard);
|
drop(arch_boot_params_guard);
|
||||||
@ -116,8 +122,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
|||||||
);
|
);
|
||||||
mm_early_init();
|
mm_early_init();
|
||||||
|
|
||||||
let fdt =
|
|
||||||
unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
|
|
||||||
print_node(fdt.find_node("/").unwrap(), 0);
|
print_node(fdt.find_node("/").unwrap(), 0);
|
||||||
|
|
||||||
unsafe { parse_dtb() };
|
unsafe { parse_dtb() };
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
//! 处理中断和异常
|
||||||
|
//!
|
||||||
|
//! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c
|
||||||
use core::hint::spin_loop;
|
use core::hint::spin_loop;
|
||||||
|
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{kdebug, kerror};
|
use crate::{arch::syscall::syscall_handler, kdebug, kerror};
|
||||||
|
|
||||||
use super::TrapFrame;
|
use super::TrapFrame;
|
||||||
|
|
||||||
@ -136,11 +139,16 @@ fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemE
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 处理环境调用异常 #8
|
/// 处理环境调用异常 #8
|
||||||
fn do_trap_user_env_call(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
kerror!("riscv64_do_irq: do_trap_user_env_call");
|
if trap_frame.is_from_user() {
|
||||||
loop {
|
let syscall_num = trap_frame.a7;
|
||||||
spin_loop();
|
trap_frame.epc += 4;
|
||||||
|
trap_frame.origin_a0 = trap_frame.a0;
|
||||||
|
syscall_handler(syscall_num, trap_frame);
|
||||||
|
} else {
|
||||||
|
panic!("do_trap_user_env_call: not from user mode")
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9-11 reserved
|
// 9-11 reserved
|
||||||
@ -154,8 +162,16 @@ fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemErro
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 处理页加载错误异常 #13
|
/// 处理页加载错误异常 #13
|
||||||
fn do_trap_load_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
kerror!("riscv64_do_irq: do_trap_load_page_fault");
|
let vaddr = trap_frame.badaddr;
|
||||||
|
let cause = trap_frame.cause;
|
||||||
|
let epc = trap_frame.epc;
|
||||||
|
kerror!(
|
||||||
|
"riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
|
||||||
|
vaddr,
|
||||||
|
cause
|
||||||
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
spin_loop();
|
spin_loop();
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use system_error::SystemError;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::MMArch,
|
arch::MMArch,
|
||||||
|
driver::open_firmware::fdt::open_firmware_fdt_driver,
|
||||||
kdebug,
|
kdebug,
|
||||||
libs::spinlock::SpinLock,
|
libs::spinlock::SpinLock,
|
||||||
mm::{
|
mm::{
|
||||||
@ -13,7 +14,7 @@ use crate::{
|
|||||||
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
|
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
|
||||||
},
|
},
|
||||||
kernel_mapper::KernelMapper,
|
kernel_mapper::KernelMapper,
|
||||||
page::{PageEntry, PageFlags},
|
page::{PageEntry, PageFlags, PAGE_1G_SHIFT},
|
||||||
ucontext::UserMapper,
|
ucontext::UserMapper,
|
||||||
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
||||||
},
|
},
|
||||||
@ -130,16 +131,28 @@ impl MemoryManagementArch for RiscV64MMArch {
|
|||||||
|
|
||||||
const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);
|
const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);
|
||||||
|
|
||||||
/// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址
|
/// 在距离sv39的顶端还有64M的位置,设置为FIXMAP的起始地址
|
||||||
const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
|
const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_fc00_0000);
|
||||||
/// 设置1MB的fixmap空间
|
/// 设置1MB的fixmap空间
|
||||||
const FIXMAP_SIZE: usize = 256 * 4096;
|
const FIXMAP_SIZE: usize = 256 * 4096;
|
||||||
|
|
||||||
|
/// 在距离sv39的顶端还有2G的位置,设置为MMIO空间的起始地址
|
||||||
|
const MMIO_BASE: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
|
||||||
|
/// 设置1g的MMIO空间
|
||||||
|
const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
unsafe fn init() {
|
unsafe fn init() {
|
||||||
riscv_mm_init().expect("init kernel memory management architecture failed");
|
riscv_mm_init().expect("init kernel memory management architecture failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn arch_post_init() {
|
||||||
|
// 映射fdt
|
||||||
|
open_firmware_fdt_driver()
|
||||||
|
.map_fdt()
|
||||||
|
.expect("openfirmware map fdt failed");
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn invalidate_page(address: VirtAddr) {
|
unsafe fn invalidate_page(address: VirtAddr) {
|
||||||
riscv::asm::sfence_vma(0, address.data());
|
riscv::asm::sfence_vma(0, address.data());
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,10 @@ use crate::{
|
|||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
process::{
|
process::{
|
||||||
fork::{CloneFlags, KernelCloneArgs},
|
fork::{CloneFlags, KernelCloneArgs},
|
||||||
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
|
switch_finish_hook, KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager,
|
||||||
|
PROCESS_SWITCH_RESULT,
|
||||||
},
|
},
|
||||||
smp::cpu::ProcessorId,
|
smp::cpu::ProcessorId,
|
||||||
syscall::Syscall,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -213,9 +213,9 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
|
|||||||
ld s10, {off_s10}(a1)
|
ld s10, {off_s10}(a1)
|
||||||
ld s11, {off_s11}(a1)
|
ld s11, {off_s11}(a1)
|
||||||
|
|
||||||
// 将ra设置为标签1,并跳转到{switch_finish_hook}
|
// 将ra设置为标签1,并跳转到before_switch_finish_hook
|
||||||
la ra, 1f
|
la ra, 1f
|
||||||
j {switch_finish_hook}
|
j {before_switch_finish_hook}
|
||||||
|
|
||||||
1:
|
1:
|
||||||
ld sp, {off_sp}(a1)
|
ld sp, {off_sp}(a1)
|
||||||
@ -238,10 +238,15 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
|
|||||||
off_s9 = const(offset_of!(ArchPCBInfo, s9)),
|
off_s9 = const(offset_of!(ArchPCBInfo, s9)),
|
||||||
off_s10 = const(offset_of!(ArchPCBInfo, s10)),
|
off_s10 = const(offset_of!(ArchPCBInfo, s10)),
|
||||||
off_s11 = const(offset_of!(ArchPCBInfo, s11)),
|
off_s11 = const(offset_of!(ArchPCBInfo, s11)),
|
||||||
switch_finish_hook = sym crate::process::switch_finish_hook,
|
before_switch_finish_hook = sym before_switch_finish_hook,
|
||||||
options(noreturn));
|
options(noreturn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 在切换上下文完成后的钩子函数(必须在这里加一个跳转函数,否则会出现relocation truncated to fit: R_RISCV_JAL错误)
|
||||||
|
unsafe extern "C" fn before_switch_finish_hook() {
|
||||||
|
switch_finish_hook();
|
||||||
|
}
|
||||||
|
|
||||||
impl ProcessControlBlock {
|
impl ProcessControlBlock {
|
||||||
/// 获取当前进程的pcb
|
/// 获取当前进程的pcb
|
||||||
pub fn arch_current_pcb() -> Arc<Self> {
|
pub fn arch_current_pcb() -> Arc<Self> {
|
||||||
@ -375,73 +380,50 @@ impl FpDExtState {
|
|||||||
asm!("frcsr {0}", lateout(reg) self.fcsr);
|
asm!("frcsr {0}", lateout(reg) self.fcsr);
|
||||||
asm!(concat!(
|
asm!(concat!(
|
||||||
"
|
"
|
||||||
fsd f0, {0}
|
// 为原来的a0寄存器的值在堆栈上分配空间
|
||||||
fsd f1, {1}
|
addi sp, sp, -8
|
||||||
fsd f2, {2}
|
sd a0, 0(sp)
|
||||||
fsd f3, {3}
|
mv a0, {0}
|
||||||
fsd f4, {4}
|
|
||||||
fsd f5, {5}
|
fsd f0, 0(a0)
|
||||||
fsd f6, {6}
|
fsd f1, 8(a0)
|
||||||
fsd f7, {7}
|
fsd f2, 16(a0)
|
||||||
fsd f8, {8}
|
fsd f3, 24(a0)
|
||||||
fsd f9, {9}
|
fsd f4, 32(a0)
|
||||||
fsd f10, {10}
|
fsd f5, 40(a0)
|
||||||
fsd f11, {11}
|
fsd f6, 48(a0)
|
||||||
fsd f12, {12}
|
fsd f7, 56(a0)
|
||||||
fsd f13, {13}
|
fsd f8, 64(a0)
|
||||||
fsd f14, {14}
|
fsd f9, 72(a0)
|
||||||
fsd f15, {15}
|
fsd f10, 80(a0)
|
||||||
fsd f16, {16}
|
fsd f11, 88(a0)
|
||||||
fsd f17, {17}
|
fsd f12, 96(a0)
|
||||||
fsd f18, {18}
|
fsd f13, 104(a0)
|
||||||
fsd f19, {19}
|
fsd f14, 112(a0)
|
||||||
fsd f20, {20}
|
fsd f15, 120(a0)
|
||||||
fsd f21, {21}
|
fsd f16, 128(a0)
|
||||||
fsd f22, {22}
|
fsd f17, 136(a0)
|
||||||
fsd f23, {23}
|
fsd f18, 144(a0)
|
||||||
fsd f24, {24}
|
fsd f19, 152(a0)
|
||||||
fsd f25, {25}
|
fsd f20, 160(a0)
|
||||||
fsd f26, {26}
|
fsd f21, 168(a0)
|
||||||
fsd f27, {27}
|
fsd f22, 176(a0)
|
||||||
fsd f28, {28}
|
fsd f23, 184(a0)
|
||||||
fsd f29, {29}
|
fsd f24, 192(a0)
|
||||||
fsd f30, {30}
|
fsd f25, 200(a0)
|
||||||
fsd f31, {31}
|
fsd f26, 208(a0)
|
||||||
|
fsd f27, 216(a0)
|
||||||
|
fsd f28, 224(a0)
|
||||||
|
fsd f29, 232(a0)
|
||||||
|
fsd f30, 240(a0)
|
||||||
|
fsd f31, 248(a0)
|
||||||
|
|
||||||
|
// 恢复a0寄存器的值
|
||||||
|
ld a0, 0(sp)
|
||||||
|
addi sp, sp, 8
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
lateout(reg) self.f[0],
|
in (reg) &self.f as *const _,
|
||||||
lateout(reg) self.f[1],
|
|
||||||
lateout(reg) self.f[2],
|
|
||||||
lateout(reg) self.f[3],
|
|
||||||
lateout(reg) self.f[4],
|
|
||||||
lateout(reg) self.f[5],
|
|
||||||
lateout(reg) self.f[6],
|
|
||||||
lateout(reg) self.f[7],
|
|
||||||
lateout(reg) self.f[8],
|
|
||||||
lateout(reg) self.f[9],
|
|
||||||
lateout(reg) self.f[10],
|
|
||||||
lateout(reg) self.f[11],
|
|
||||||
lateout(reg) self.f[12],
|
|
||||||
lateout(reg) self.f[13],
|
|
||||||
lateout(reg) self.f[14],
|
|
||||||
lateout(reg) self.f[15],
|
|
||||||
lateout(reg) self.f[16],
|
|
||||||
lateout(reg) self.f[17],
|
|
||||||
lateout(reg) self.f[18],
|
|
||||||
lateout(reg) self.f[19],
|
|
||||||
lateout(reg) self.f[20],
|
|
||||||
lateout(reg) self.f[21],
|
|
||||||
lateout(reg) self.f[22],
|
|
||||||
lateout(reg) self.f[23],
|
|
||||||
lateout(reg) self.f[24],
|
|
||||||
lateout(reg) self.f[25],
|
|
||||||
lateout(reg) self.f[26],
|
|
||||||
lateout(reg) self.f[27],
|
|
||||||
lateout(reg) self.f[28],
|
|
||||||
lateout(reg) self.f[29],
|
|
||||||
lateout(reg) self.f[30],
|
|
||||||
lateout(reg) self.f[31],
|
|
||||||
|
|
||||||
);
|
);
|
||||||
riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off);
|
riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off);
|
||||||
}
|
}
|
||||||
@ -457,72 +439,50 @@ impl FpDExtState {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
asm!(concat!(
|
asm!(concat!(
|
||||||
"
|
"
|
||||||
fld f0, {0}
|
// 为原来的a0寄存器的值在堆栈上分配空间
|
||||||
fld f1, {1}
|
addi sp, sp, -8
|
||||||
fld f2, {2}
|
sd a0, 0(sp)
|
||||||
fld f3, {3}
|
mv a0, {0}
|
||||||
fld f4, {4}
|
|
||||||
fld f5, {5}
|
fld f0, 0(a0)
|
||||||
fld f6, {6}
|
fld f1, 8(a0)
|
||||||
fld f7, {7}
|
fld f2, 16(a0)
|
||||||
fld f8, {8}
|
fld f3, 24(a0)
|
||||||
fld f9, {9}
|
fld f4, 32(a0)
|
||||||
fld f10, {10}
|
fld f5, 40(a0)
|
||||||
fld f11, {11}
|
fld f6, 48(a0)
|
||||||
fld f12, {12}
|
fld f7, 56(a0)
|
||||||
fld f13, {13}
|
fld f8, 64(a0)
|
||||||
fld f14, {14}
|
fld f9, 72(a0)
|
||||||
fld f15, {15}
|
fld f10, 80(a0)
|
||||||
fld f16, {16}
|
fld f11, 88(a0)
|
||||||
fld f17, {17}
|
fld f12, 96(a0)
|
||||||
fld f18, {18}
|
fld f13, 104(a0)
|
||||||
fld f19, {19}
|
fld f14, 112(a0)
|
||||||
fld f20, {20}
|
fld f15, 120(a0)
|
||||||
fld f21, {21}
|
fld f16, 128(a0)
|
||||||
fld f22, {22}
|
fld f17, 136(a0)
|
||||||
fld f23, {23}
|
fld f18, 144(a0)
|
||||||
fld f24, {24}
|
fld f19, 152(a0)
|
||||||
fld f25, {25}
|
fld f20, 160(a0)
|
||||||
fld f26, {26}
|
fld f21, 168(a0)
|
||||||
fld f27, {27}
|
fld f22, 176(a0)
|
||||||
fld f28, {28}
|
fld f23, 184(a0)
|
||||||
fld f29, {29}
|
fld f24, 192(a0)
|
||||||
fld f30, {30}
|
fld f25, 200(a0)
|
||||||
fld f31, {31}
|
fld f26, 208(a0)
|
||||||
|
fld f27, 216(a0)
|
||||||
|
fld f28, 224(a0)
|
||||||
|
fld f29, 232(a0)
|
||||||
|
fld f30, 240(a0)
|
||||||
|
fld f31, 248(a0)
|
||||||
|
|
||||||
|
// 恢复a0寄存器的值
|
||||||
|
ld a0, 0(sp)
|
||||||
|
addi sp, sp, 8
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
in(reg) self.f[0],
|
in (reg) &self.f as *const _,
|
||||||
in(reg) self.f[1],
|
|
||||||
in(reg) self.f[2],
|
|
||||||
in(reg) self.f[3],
|
|
||||||
in(reg) self.f[4],
|
|
||||||
in(reg) self.f[5],
|
|
||||||
in(reg) self.f[6],
|
|
||||||
in(reg) self.f[7],
|
|
||||||
in(reg) self.f[8],
|
|
||||||
in(reg) self.f[9],
|
|
||||||
in(reg) self.f[10],
|
|
||||||
in(reg) self.f[11],
|
|
||||||
in(reg) self.f[12],
|
|
||||||
in(reg) self.f[13],
|
|
||||||
in(reg) self.f[14],
|
|
||||||
in(reg) self.f[15],
|
|
||||||
in(reg) self.f[16],
|
|
||||||
in(reg) self.f[17],
|
|
||||||
in(reg) self.f[18],
|
|
||||||
in(reg) self.f[19],
|
|
||||||
in(reg) self.f[20],
|
|
||||||
in(reg) self.f[21],
|
|
||||||
in(reg) self.f[22],
|
|
||||||
in(reg) self.f[23],
|
|
||||||
in(reg) self.f[24],
|
|
||||||
in(reg) self.f[25],
|
|
||||||
in(reg) self.f[26],
|
|
||||||
in(reg) self.f[27],
|
|
||||||
in(reg) self.f[28],
|
|
||||||
in(reg) self.f[29],
|
|
||||||
in(reg) self.f[30],
|
|
||||||
in(reg) self.f[31],
|
|
||||||
);
|
);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
asm!("fscsr {0}", in(reg) fcsr);
|
asm!("fscsr {0}", in(reg) fcsr);
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"arch": "riscv64",
|
|
||||||
"code-model": "medium",
|
|
||||||
"cpu": "generic-rv64",
|
|
||||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
|
||||||
"eh-frame-header": false,
|
|
||||||
"emit-debug-gdb-scripts": false,
|
|
||||||
"features": "+m,+a,+c",
|
|
||||||
"is-builtin": false,
|
|
||||||
"linker": "rust-lld",
|
|
||||||
"linker-flavor": "ld.lld",
|
|
||||||
"llvm-target": "riscv64",
|
|
||||||
"max-atomic-width": 64,
|
|
||||||
"panic-strategy": "abort",
|
|
||||||
"relocation-model": "pic",
|
|
||||||
"position-independent-executables": true,
|
|
||||||
"target-pointer-width": "64"
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
pub mod nr;
|
pub mod nr;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::exception::InterruptArch;
|
use crate::{exception::InterruptArch, process::ProcessManager, syscall::Syscall};
|
||||||
|
|
||||||
use super::{interrupt::TrapFrame, CurrentIrqArch};
|
use super::{interrupt::TrapFrame, CurrentIrqArch};
|
||||||
|
|
||||||
@ -11,10 +11,32 @@ pub fn arch_syscall_init() -> Result<(), SystemError> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
macro_rules! syscall_return {
|
||||||
pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
($val:expr, $regs:expr, $show:expr) => {{
|
||||||
|
let ret = $val;
|
||||||
|
$regs.a0 = ret;
|
||||||
|
|
||||||
|
if $show {
|
||||||
|
let pid = ProcessManager::current_pcb().pid();
|
||||||
|
crate::kdebug!("syscall return:pid={:?},ret= {:?}\n", pid, ret as isize);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
CurrentIrqArch::interrupt_disable();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn syscall_handler(syscall_num: usize, frame: &mut TrapFrame) -> () {
|
||||||
unsafe {
|
unsafe {
|
||||||
CurrentIrqArch::interrupt_enable();
|
CurrentIrqArch::interrupt_enable();
|
||||||
}
|
}
|
||||||
unimplemented!("syscall_handler")
|
|
||||||
|
let args = [frame.a0, frame.a1, frame.a2, frame.a3, frame.a4, frame.a5];
|
||||||
|
syscall_return!(
|
||||||
|
Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize),
|
||||||
|
frame,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,66 @@
|
|||||||
use crate::time::{clocksource::HZ, TimeArch};
|
use crate::{
|
||||||
|
driver::open_firmware::fdt::open_firmware_fdt_driver,
|
||||||
|
kinfo,
|
||||||
|
time::{clocksource::HZ, TimeArch},
|
||||||
|
};
|
||||||
pub struct RiscV64TimeArch;
|
pub struct RiscV64TimeArch;
|
||||||
|
|
||||||
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
||||||
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
||||||
|
|
||||||
|
static mut TIME_FREQ: usize = 0;
|
||||||
|
|
||||||
|
/// 获取CPU的time寄存器频率
|
||||||
|
///
|
||||||
|
/// todo: 支持从acpi中获取
|
||||||
|
fn init_time_freq() {
|
||||||
|
let fdt = open_firmware_fdt_driver().fdt_ref();
|
||||||
|
if fdt.is_err() {
|
||||||
|
panic!("init_time_freq: failed to get fdt");
|
||||||
|
}
|
||||||
|
let fdt = fdt.unwrap();
|
||||||
|
let cpu_node = fdt.find_node("/cpus");
|
||||||
|
if cpu_node.is_none() {
|
||||||
|
panic!("init_time_freq: failed to find /cpus node");
|
||||||
|
}
|
||||||
|
|
||||||
|
let cpu_node = cpu_node.unwrap();
|
||||||
|
let time_freq = cpu_node
|
||||||
|
.property("timebase-frequency")
|
||||||
|
.map(|prop| prop.as_usize())
|
||||||
|
.flatten();
|
||||||
|
if time_freq.is_none() {
|
||||||
|
panic!("init_time_freq: failed to get timebase-frequency");
|
||||||
|
}
|
||||||
|
|
||||||
|
let time_freq: usize = time_freq.unwrap();
|
||||||
|
kinfo!("init_time_freq: timebase-frequency: {}", time_freq);
|
||||||
|
unsafe {
|
||||||
|
TIME_FREQ = time_freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn time_init() {
|
||||||
|
// 初始化cpu time register频率
|
||||||
|
init_time_freq();
|
||||||
|
}
|
||||||
|
|
||||||
impl TimeArch for RiscV64TimeArch {
|
impl TimeArch for RiscV64TimeArch {
|
||||||
fn get_cycles() -> usize {
|
fn get_cycles() -> usize {
|
||||||
riscv::register::cycle::read()
|
riscv::register::time::read()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cal_expire_cycles(ns: usize) -> usize {
|
fn cal_expire_cycles(ns: usize) -> usize {
|
||||||
todo!()
|
Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 将CPU的时钟周期数转换为纳秒
|
/// 将CPU的时钟周期数转换为纳秒
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn cycles2ns(cycles: usize) -> usize {
|
fn cycles2ns(cycles: usize) -> usize {
|
||||||
todo!()
|
if unsafe { TIME_FREQ == 0 } {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cycles * 1000000000 / unsafe { TIME_FREQ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::mm::kernel_mapper::KernelMapper;
|
use crate::mm::kernel_mapper::KernelMapper;
|
||||||
use crate::mm::page::{PageEntry, PageFlags};
|
use crate::mm::page::{PageEntry, PageFlags, PAGE_1G_SHIFT};
|
||||||
use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
|
use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
|
||||||
use crate::{kdebug, kinfo, kwarn};
|
use crate::{kdebug, kinfo, kwarn};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
@ -122,6 +122,9 @@ impl MemoryManagementArch for X86_64MMArch {
|
|||||||
/// 设置FIXMAP区域大小为1M
|
/// 设置FIXMAP区域大小为1M
|
||||||
const FIXMAP_SIZE: usize = 256 * 4096;
|
const FIXMAP_SIZE: usize = 256 * 4096;
|
||||||
|
|
||||||
|
const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
|
||||||
|
const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
|
||||||
|
|
||||||
/// @brief 获取物理内存区域
|
/// @brief 获取物理内存区域
|
||||||
unsafe fn init() {
|
unsafe fn init() {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -5,6 +5,10 @@ use super::driver::tsc::TSCManager;
|
|||||||
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
||||||
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
||||||
|
|
||||||
|
pub fn time_init() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
pub struct X86_64TimeArch;
|
pub struct X86_64TimeArch;
|
||||||
|
|
||||||
impl TimeArch for X86_64TimeArch {
|
impl TimeArch for X86_64TimeArch {
|
||||||
|
@ -9,12 +9,14 @@ use system_error::SystemError;
|
|||||||
use crate::{
|
use crate::{
|
||||||
init::boot_params,
|
init::boot_params,
|
||||||
libs::rwlock::RwLock,
|
libs::rwlock::RwLock,
|
||||||
mm::{memblock::mem_block_manager, PhysAddr},
|
mm::{memblock::mem_block_manager, mmio_buddy::MMIOSpaceGuard, PhysAddr},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static OPEN_FIRMWARE_FDT_DRIVER: OpenFirmwareFdtDriver = OpenFirmwareFdtDriver::new();
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
|
pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
|
||||||
&OpenFirmwareFdtDriver
|
&OPEN_FIRMWARE_FDT_DRIVER
|
||||||
}
|
}
|
||||||
|
|
||||||
static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
|
static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
|
||||||
@ -40,22 +42,48 @@ impl FdtGlobalData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OpenFirmwareFdtDriver;
|
#[allow(dead_code)]
|
||||||
|
pub struct OpenFirmwareFdtDriver {
|
||||||
|
inner: RwLock<InnerOpenFirmwareFdtDriver>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct InnerOpenFirmwareFdtDriver {
|
||||||
|
/// FDT自身映射的MMIO空间
|
||||||
|
fdt_map_guard: Option<MMIOSpaceGuard>,
|
||||||
|
}
|
||||||
|
|
||||||
impl OpenFirmwareFdtDriver {
|
impl OpenFirmwareFdtDriver {
|
||||||
|
const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: RwLock::new(InnerOpenFirmwareFdtDriver {
|
||||||
|
fdt_map_guard: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
|
pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
|
||||||
|
let fdt = self.fdt_ref()?;
|
||||||
|
self.early_init_scan_nodes(&fdt);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn set_fdt_map_guard(&self, guard: Option<MMIOSpaceGuard>) {
|
||||||
|
self.inner.write().fdt_map_guard = guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取FDT的引用
|
||||||
|
pub fn fdt_ref(&self) -> Result<Fdt<'static>, SystemError> {
|
||||||
let fdt_vaddr = boot_params().read().fdt().unwrap();
|
let fdt_vaddr = boot_params().read().fdt().unwrap();
|
||||||
let fdt = unsafe {
|
let fdt: Fdt<'_> = unsafe {
|
||||||
fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
|
fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
|
||||||
kerror!("failed to parse fdt, err={:?}", e);
|
kerror!("failed to parse fdt, err={:?}", e);
|
||||||
SystemError::EINVAL
|
SystemError::EINVAL
|
||||||
})
|
})
|
||||||
}?;
|
}?;
|
||||||
|
Ok(fdt)
|
||||||
self.early_init_scan_nodes(&fdt);
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn early_init_scan_nodes(&self, fdt: &Fdt) {
|
fn early_init_scan_nodes(&self, fdt: &Fdt) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::{
|
||||||
init::{early_setup_arch, setup_arch, setup_arch_post},
|
init::{early_setup_arch, setup_arch, setup_arch_post},
|
||||||
|
time::time_init,
|
||||||
CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
|
CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
|
||||||
},
|
},
|
||||||
driver::{base::init::driver_init, serial::serial_early_init, video::VideoRefreshManager},
|
driver::{base::init::driver_init, serial::serial_early_init, video::VideoRefreshManager},
|
||||||
@ -70,6 +71,7 @@ fn do_start_kernel() {
|
|||||||
softirq_init().expect("softirq init failed");
|
softirq_init().expect("softirq init failed");
|
||||||
Syscall::init().expect("syscall init failed");
|
Syscall::init().expect("syscall init failed");
|
||||||
timekeeping_init();
|
timekeeping_init();
|
||||||
|
time_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
kthread_init();
|
kthread_init();
|
||||||
clocksource_boot_finish();
|
clocksource_boot_finish();
|
||||||
|
@ -58,6 +58,7 @@ pub unsafe fn mm_init() {
|
|||||||
Ordering::SeqCst,
|
Ordering::SeqCst,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
MMArch::arch_post_init();
|
||||||
kinfo!("mm init done.");
|
kinfo!("mm init done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
||||||
use crate::mm::kernel_mapper::KernelMapper;
|
use crate::mm::kernel_mapper::KernelMapper;
|
||||||
|
use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
|
||||||
use crate::process::ProcessManager;
|
use crate::process::ProcessManager;
|
||||||
use crate::{
|
use crate::{
|
||||||
include::bindings::bindings::{PAGE_1G_SHIFT, PAGE_4K_SHIFT, PAGE_4K_SIZE},
|
include::bindings::bindings::PAGE_4K_SIZE,
|
||||||
kdebug,
|
kdebug,
|
||||||
mm::{MMArch, MemoryManagementArch},
|
mm::{MMArch, MemoryManagementArch},
|
||||||
};
|
};
|
||||||
@ -10,22 +11,19 @@ use crate::{kerror, kinfo, kwarn};
|
|||||||
use alloc::{collections::LinkedList, vec::Vec};
|
use alloc::{collections::LinkedList, vec::Vec};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use super::page::PageFlags;
|
use super::page::PageFlags;
|
||||||
use super::{PhysAddr, VirtAddr};
|
use super::{PhysAddr, VirtAddr};
|
||||||
|
|
||||||
// 最大的伙伴块的幂
|
// 最大的伙伴块的幂
|
||||||
const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT;
|
const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT as u32;
|
||||||
// 最小的伙伴块的幂
|
// 最小的伙伴块的幂
|
||||||
const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT;
|
const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT as u32;
|
||||||
// 内存池数组的范围
|
// 内存池数组的范围
|
||||||
const MMIO_BUDDY_REGION_COUNT: u32 = MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1;
|
const MMIO_BUDDY_REGION_COUNT: u32 = MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1;
|
||||||
|
|
||||||
const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
|
|
||||||
const MMIO_TOP: VirtAddr = VirtAddr::new(0xffffa20000000000);
|
|
||||||
|
|
||||||
const PAGE_1G_SIZE: usize = 1 << 30;
|
const PAGE_1G_SIZE: usize = 1 << 30;
|
||||||
|
|
||||||
static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
|
static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
|
||||||
@ -65,26 +63,35 @@ impl MmioBuddyMemPool {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let pool = MmioBuddyMemPool {
|
let pool = MmioBuddyMemPool {
|
||||||
pool_start_addr: MMIO_BASE,
|
pool_start_addr: MMArch::MMIO_BASE,
|
||||||
pool_size: MMIO_TOP - MMIO_BASE,
|
pool_size: MMArch::MMIO_SIZE,
|
||||||
free_regions,
|
free_regions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert!(pool.pool_start_addr.data() % PAGE_1G_SIZE == 0);
|
||||||
kdebug!("MMIO buddy pool init: created");
|
kdebug!("MMIO buddy pool init: created");
|
||||||
|
|
||||||
let cnt_1g_blocks = (MMIO_TOP - MMIO_BASE) >> 30;
|
let mut vaddr_base = MMArch::MMIO_BASE;
|
||||||
let mut vaddr_base = MMIO_BASE;
|
let mut remain_size = MMArch::MMIO_SIZE;
|
||||||
kdebug!("total 1G blocks: {cnt_1g_blocks}");
|
kdebug!(
|
||||||
for _i in 0..cnt_1g_blocks {
|
"BASE: {:?}, TOP: {:?}, size: {:?}",
|
||||||
compiler_fence(Ordering::SeqCst);
|
MMArch::MMIO_BASE,
|
||||||
match pool.give_back_block(vaddr_base, PAGE_1G_SHIFT) {
|
MMArch::MMIO_TOP,
|
||||||
Ok(_) => {
|
MMArch::MMIO_SIZE
|
||||||
vaddr_base += PAGE_1G_SIZE;
|
);
|
||||||
}
|
|
||||||
Err(_) => {
|
for shift in (PAGE_4K_SHIFT..=PAGE_1G_SHIFT).rev() {
|
||||||
|
if remain_size & (1 << shift) != 0 {
|
||||||
|
let ok = pool.give_back_block(vaddr_base, shift as u32).is_ok();
|
||||||
|
if ok {
|
||||||
|
vaddr_base += 1 << shift;
|
||||||
|
remain_size -= 1 << shift;
|
||||||
|
} else {
|
||||||
panic!("MMIO buddy pool init failed");
|
panic!("MMIO buddy pool init failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kdebug!("MMIO buddy pool init success");
|
kdebug!("MMIO buddy pool init success");
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
@ -297,9 +304,9 @@ impl MmioBuddyMemPool {
|
|||||||
/// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
|
/// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
|
||||||
/// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
|
/// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
|
||||||
fn mmio_buddy_query_addr_region(&self, exp: u32) -> Result<MmioBuddyAddrRegion, MmioResult> {
|
fn mmio_buddy_query_addr_region(&self, exp: u32) -> Result<MmioBuddyAddrRegion, MmioResult> {
|
||||||
let list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
|
let mut list_guard: SpinLockGuard<MmioFreeRegionList> =
|
||||||
&mut self.free_regions[exp2index(exp)].lock();
|
self.free_regions[exp2index(exp)].lock();
|
||||||
match self.query_addr_region(exp, list_guard) {
|
match self.query_addr_region(exp, &mut list_guard) {
|
||||||
Ok(ret) => return Ok(ret),
|
Ok(ret) => return Ok(ret),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
kdebug!("mmio_buddy_query_addr_region failed");
|
kdebug!("mmio_buddy_query_addr_region failed");
|
||||||
@ -487,9 +494,9 @@ impl MmioBuddyMemPool {
|
|||||||
let mut new_size = size;
|
let mut new_size = size;
|
||||||
// 对齐要申请的空间大小
|
// 对齐要申请的空间大小
|
||||||
// 如果要申请的空间大小小于4k,则分配4k
|
// 如果要申请的空间大小小于4k,则分配4k
|
||||||
if size_exp < PAGE_4K_SHIFT {
|
if size_exp < PAGE_4K_SHIFT as u32 {
|
||||||
new_size = PAGE_4K_SIZE as usize;
|
new_size = PAGE_4K_SIZE as usize;
|
||||||
size_exp = PAGE_4K_SHIFT;
|
size_exp = PAGE_4K_SHIFT as u32;
|
||||||
} else if (new_size & (!(1 << size_exp))) != 0 {
|
} else if (new_size & (!(1 << size_exp))) != 0 {
|
||||||
// 向左对齐空间大小
|
// 向左对齐空间大小
|
||||||
size_exp += 1;
|
size_exp += 1;
|
||||||
@ -630,7 +637,8 @@ impl MMIOSpaceGuard {
|
|||||||
"MMIO space vaddr must be aligned with size"
|
"MMIO space vaddr must be aligned with size"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
vaddr.data() >= MMIO_BASE.data() && vaddr.data() + size <= MMIO_TOP.data(),
|
vaddr.data() >= MMArch::MMIO_BASE.data()
|
||||||
|
&& vaddr.data() + size <= MMArch::MMIO_TOP.data(),
|
||||||
"MMIO space must be in MMIO region"
|
"MMIO space must be in MMIO region"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -492,10 +492,20 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
|
|||||||
const FIXMAP_END_VADDR: VirtAddr =
|
const FIXMAP_END_VADDR: VirtAddr =
|
||||||
VirtAddr::new(Self::FIXMAP_START_VADDR.data() + Self::FIXMAP_SIZE);
|
VirtAddr::new(Self::FIXMAP_START_VADDR.data() + Self::FIXMAP_SIZE);
|
||||||
|
|
||||||
|
/// MMIO虚拟空间的基地址
|
||||||
|
const MMIO_BASE: VirtAddr;
|
||||||
|
/// MMIO虚拟空间的大小
|
||||||
|
const MMIO_SIZE: usize;
|
||||||
|
/// MMIO虚拟空间的顶端地址(不包含)
|
||||||
|
const MMIO_TOP: VirtAddr = VirtAddr::new(Self::MMIO_BASE.data() + Self::MMIO_SIZE);
|
||||||
|
|
||||||
/// @brief 用于初始化内存管理模块与架构相关的信息。
|
/// @brief 用于初始化内存管理模块与架构相关的信息。
|
||||||
/// 该函数应调用其他模块的接口,把可用内存区域添加到memblock,提供给BumpAllocator使用
|
/// 该函数应调用其他模块的接口,把可用内存区域添加到memblock,提供给BumpAllocator使用
|
||||||
unsafe fn init();
|
unsafe fn init();
|
||||||
|
|
||||||
|
/// 内存管理初始化完成后,调用该函数
|
||||||
|
unsafe fn arch_post_init() {}
|
||||||
|
|
||||||
/// @brief 读取指定虚拟地址的值,并假设它是类型T的指针
|
/// @brief 读取指定虚拟地址的值,并假设它是类型T的指针
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn read<T>(address: VirtAddr) -> T {
|
unsafe fn read<T>(address: VirtAddr) -> T {
|
||||||
|
@ -21,6 +21,11 @@ use super::{
|
|||||||
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const PAGE_4K_SHIFT: usize = 12;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const PAGE_2M_SHIFT: usize = 21;
|
||||||
|
pub const PAGE_1G_SHIFT: usize = 30;
|
||||||
|
|
||||||
/// 全局物理页信息管理器
|
/// 全局物理页信息管理器
|
||||||
pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
|
pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
|
||||||
|
|
||||||
|
@ -493,7 +493,8 @@ pub unsafe extern "sysv64" fn switch_finish_hook() {
|
|||||||
ProcessManager::switch_finish_hook();
|
ProcessManager::switch_finish_hook();
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
pub unsafe extern "C" fn switch_finish_hook() {
|
#[inline(always)]
|
||||||
|
pub unsafe fn switch_finish_hook() {
|
||||||
ProcessManager::switch_finish_hook();
|
ProcessManager::switch_finish_hook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
/*
|
//! 这个文件实现的是调度过程中涉及到的时钟
|
||||||
这个文件实现的是调度过程中设计到的时钟
|
//!
|
||||||
*/
|
use crate::{arch::CurrentTimeArch, time::TimeArch};
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
use crate::{
|
|
||||||
arch::{driver::tsc::TSCManager, CurrentTimeArch},
|
|
||||||
time::TimeArch,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct SchedClock;
|
pub struct SchedClock;
|
||||||
|
|
||||||
@ -14,15 +9,17 @@ impl SchedClock {
|
|||||||
pub fn sched_clock_cpu(_cpu: usize) -> u64 {
|
pub fn sched_clock_cpu(_cpu: usize) -> u64 {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
{
|
{
|
||||||
if TSCManager::cpu_khz() == 0 {
|
if crate::arch::driver::tsc::TSCManager::cpu_khz() == 0 {
|
||||||
// TCS no init
|
// TSC not calibrated yet
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
todo!()
|
{
|
||||||
|
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user