Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv: 把内核编译target改为riscv64gc & 获取time csr的频率 & 修正浮点保存与恢复的汇编的问题 #699

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ Cargo.lock
.cache
compile_commands.json
/logs/
.vscode
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
"./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.check.overrideCommand": [
"make",
Expand Down
5 changes: 3 additions & 2 deletions build-scripts/kernel_build/src/cfiles/arch/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ impl CFilesArch for RiscV64CFilesArch {
// // c.flag("-march=rv64imafdc");
// c.no_default_flags(true);
c.flag("-mcmodel=medany");
c.flag("-mabi=lp64");
c.flag("-march=rv64imac");

c.flag("-mabi=lp64d");
c.flag("-march=rv64gc");
}
}

Expand Down
2 changes: 2 additions & 0 deletions build-scripts/kernel_build/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![feature(cfg_target_abi)]

#[macro_use]
extern crate lazy_static;
extern crate cc;
Expand Down
2 changes: 1 addition & 1 deletion docs/kernel/configuration/arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

为了能支持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",
```

Expand Down
4 changes: 2 additions & 2 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include ./env.mk
ifeq ($(ARCH), x86_64)
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
else ifeq ($(ARCH), riscv64)
export TARGET_JSON=arch/riscv64/riscv64imac-unknown-none-elf.json
export TARGET_JSON=riscv64gc-unknown-none-elf
endif

export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
Expand Down Expand Up @@ -38,7 +38,7 @@ check: ECHO
ifeq ($(ARCH), x86_64)
@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
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

test:
Expand Down
2 changes: 1 addition & 1 deletion kernel/env.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export GLOBAL_CFLAGS := -fno-builtin -fno-stack-protector -D $(CFLAGS_DEFINE_ARC
ifeq ($(ARCH), x86_64)
GLOBAL_CFLAGS += -mcmodel=large -m64
else ifeq ($(ARCH), riscv64)
GLOBAL_CFLAGS += -mcmodel=medany -march=rv64imac -mabi=lp64
GLOBAL_CFLAGS += -mcmodel=medany -march=rv64gc -mabi=lp64d
endif

ifeq ($(DEBUG), DEBUG)
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ kernel: $(kernel_subdirs) kernel_rust

__link_riscv64_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
@rm kernel
$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"
Expand Down
1 change: 0 additions & 1 deletion kernel/src/arch/riscv64/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use sbi_rt::HartMask;

use crate::{
init::boot_params,
kdebug,
mm::percpu::{PerCpu, PerCpuVar},
smp::cpu::{ProcessorId, SmpCpuManager},
};
Expand Down
1 change: 1 addition & 0 deletions kernel/src/arch/riscv64/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod of;
pub mod sbi;
40 changes: 40 additions & 0 deletions kernel/src/arch/riscv64/driver/of.rs
Original file line number Diff line number Diff line change
@@ -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(());
}
}
8 changes: 6 additions & 2 deletions kernel/src/arch/riscv64/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct ArchBootParams {
/// 启动时的fdt物理地址
pub fdt_paddr: PhysAddr,
pub fdt_vaddr: Option<VirtAddr>,
pub fdt_size: usize,

pub boot_hartid: ProcessorId,
}
Expand All @@ -26,6 +27,7 @@ impl ArchBootParams {
pub const DEFAULT: Self = ArchBootParams {
fdt_paddr: PhysAddr::new(0),
fdt_vaddr: None,
fdt_size: 0,
boot_hartid: ProcessorId::new(0),
};

Expand Down Expand Up @@ -103,8 +105,12 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
let hartid = unsafe { BOOT_HARTID };
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();
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);

drop(arch_boot_params_guard);
Expand All @@ -116,8 +122,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
);
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);

unsafe { parse_dtb() };
Expand Down
30 changes: 23 additions & 7 deletions kernel/src/arch/riscv64/interrupt/handle.rs
Original file line number Diff line number Diff line change
@@ -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 system_error::SystemError;

use crate::{kdebug, kerror};
use crate::{arch::syscall::syscall_handler, kdebug, kerror};

use super::TrapFrame;

Expand Down Expand Up @@ -136,11 +139,16 @@ fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemE
}

/// 处理环境调用异常 #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();
fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
if trap_frame.is_from_user() {
let syscall_num = trap_frame.a7;
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
Expand All @@ -154,8 +162,16 @@ fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemErro
}

/// 处理页加载错误异常 #13
fn do_trap_load_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
kerror!("riscv64_do_irq: do_trap_load_page_fault");
fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
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 {
spin_loop();
}
Expand Down
19 changes: 16 additions & 3 deletions kernel/src/arch/riscv64/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use system_error::SystemError;

use crate::{
arch::MMArch,
driver::open_firmware::fdt::open_firmware_fdt_driver,
kdebug,
libs::spinlock::SpinLock,
mm::{
Expand All @@ -13,7 +14,7 @@ use crate::{
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
},
kernel_mapper::KernelMapper,
page::{PageEntry, PageFlags},
page::{PageEntry, PageFlags, PAGE_1G_SHIFT},
ucontext::UserMapper,
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
},
Expand Down Expand Up @@ -130,16 +131,28 @@ impl MemoryManagementArch for RiscV64MMArch {

const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);

/// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址
const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
/// 在距离sv39的顶端还有64M的位置,设置为FIXMAP的起始地址
const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_fc00_0000);
/// 设置1MB的fixmap空间
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)]
unsafe fn init() {
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) {
riscv::asm::sfence_vma(0, address.data());
}
Expand Down
Loading
Loading