From b2b922fe853fd9dda66df9ca44beadd0b62fb823 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 10:52:55 -0700 Subject: [PATCH 01/26] fix typo --- src/aarch64/trap.rs | 2 +- src/lib.rs | 9 +++++---- src/riscv64/interrupt.rs | 2 +- src/riscv64/timer.rs | 2 +- src/x86_64/interrupt.rs | 4 ++-- src/x86_64/mod.rs | 2 +- src/x86_64/multiboot.rs | 2 +- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/aarch64/trap.rs b/src/aarch64/trap.rs index 4a114a5..0bf82a5 100644 --- a/src/aarch64/trap.rs +++ b/src/aarch64/trap.rs @@ -4,7 +4,7 @@ use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, VBAR_EL1}; use tock_registers::interfaces::Readable; use crate::{ - currrent_arch::{gic::handle_irq, timer::set_next_timer}, + current_arch::{gic::handle_irq, timer::set_next_timer}, instruction::Instruction, TrapType, }; diff --git a/src/lib.rs b/src/lib.rs index bf6ab72..0bd03b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,6 +158,7 @@ use core::mem::size_of; use addr::PhysPage; use alloc::vec::Vec; +use cfg_if::cfg_if; use consts::STACK_SIZE; use fdt::Fdt; use once::LazyInit; @@ -168,12 +169,12 @@ pub use percpu; #[cfg_attr(target_arch = "aarch64", path = "aarch64/mod.rs")] #[cfg_attr(target_arch = "x86_64", path = "x86_64/mod.rs")] #[cfg_attr(target_arch = "loongarch64", path = "loongarch64/mod.rs")] -mod currrent_arch; +mod current_arch; /// Trap Frame -pub use currrent_arch::TrapFrame; +pub use current_arch::TrapFrame; -pub use currrent_arch::*; +pub use current_arch::*; pub use polyhal_macro::{arch_entry, arch_interrupt}; @@ -253,7 +254,7 @@ pub fn init(page_alloc: &'static dyn PageAlloc) { PAGE_ALLOC.init_by(page_alloc); // Init current architecture - currrent_arch::arch_init(); + current_arch::arch_init(); } /// Store the number of cpu, this will fill up by startup function. diff --git a/src/riscv64/interrupt.rs b/src/riscv64/interrupt.rs index 2ecee7a..6e6bb95 100644 --- a/src/riscv64/interrupt.rs +++ b/src/riscv64/interrupt.rs @@ -83,7 +83,7 @@ static USER_RSP: usize = 0; // 设置中断 pub(crate) fn init_interrupt() { - crate::currrent_arch::page_table::sigtrx::init(); + crate::current_arch::page_table::sigtrx::init(); // 输出内核信息 unsafe { diff --git a/src/riscv64/timer.rs b/src/riscv64/timer.rs index 89aa91b..8d4ec72 100644 --- a/src/riscv64/timer.rs +++ b/src/riscv64/timer.rs @@ -1,4 +1,4 @@ -use crate::currrent_arch::boards::CLOCK_FREQ; +use crate::current_arch::boards::CLOCK_FREQ; use crate::time::Time; use riscv::register::{sie, time}; diff --git a/src/x86_64/interrupt.rs b/src/x86_64/interrupt.rs index 74dd4f7..0f84492 100644 --- a/src/x86_64/interrupt.rs +++ b/src/x86_64/interrupt.rs @@ -9,9 +9,9 @@ use x86_64::VirtAddr; use x86::{controlregs::cr2, irq::*}; use crate::consts::TRAPFRAME_SIZE; -use crate::currrent_arch::gdt::set_tss_kernel_sp; +use crate::current_arch::gdt::set_tss_kernel_sp; use crate::SYSCALL_VECTOR; -use crate::{currrent_arch::gdt::GdtStruct, TrapFrame, TrapType}; +use crate::{current_arch::gdt::GdtStruct, TrapFrame, TrapType}; use super::apic::vectors::APIC_TIMER_VECTOR; use super::context::FxsaveArea; diff --git a/src/x86_64/mod.rs b/src/x86_64/mod.rs index 5350177..12e3471 100644 --- a/src/x86_64/mod.rs +++ b/src/x86_64/mod.rs @@ -33,7 +33,7 @@ use x86_64::{ }; use crate::{ - currrent_arch::multiboot::use_multiboot, multicore::MultiCore, once::LazyInit, CPU_NUM, + current_arch::multiboot::use_multiboot, multicore::MultiCore, once::LazyInit, CPU_NUM, DTB_BIN, MEM_AREA, }; diff --git a/src/x86_64/multiboot.rs b/src/x86_64/multiboot.rs index 2f3bd8e..ccc3c37 100644 --- a/src/x86_64/multiboot.rs +++ b/src/x86_64/multiboot.rs @@ -1,4 +1,4 @@ -use crate::currrent_arch::rust_tmp_main; +use crate::current_arch::rust_tmp_main; use crate::pagetable::PageTable; use crate::{BOOT_STACK, STACK_SIZE}; use core::arch::global_asm; From 113a4e9c5061207be474d591cb36d41f9cb592ce Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 13:05:48 -0700 Subject: [PATCH 02/26] refactor first --- Cargo.toml | 1 + src/{ => bare/arch}/aarch64/barrier.rs | 0 src/{ => bare/arch}/aarch64/boot.rs | 0 src/{ => bare/arch}/aarch64/consts.rs | 0 src/{ => bare/arch}/aarch64/context.rs | 0 src/{ => bare/arch}/aarch64/gic.rs | 0 src/{ => bare/arch}/aarch64/kcontext.rs | 0 src/{ => bare/arch}/aarch64/mod.rs | 0 src/{ => bare/arch}/aarch64/page_table.rs | 0 src/{ => bare/arch}/aarch64/pl011.rs | 0 src/{ => bare/arch}/aarch64/psci.rs | 0 src/{ => bare/arch}/aarch64/timer.rs | 0 src/{ => bare/arch}/aarch64/trap.S | 0 src/{ => bare/arch}/aarch64/trap.rs | 0 src/{ => bare/arch}/loongarch64/barrier.rs | 0 src/{ => bare/arch}/loongarch64/boot.rs | 0 src/{ => bare/arch}/loongarch64/console.rs | 0 src/{ => bare/arch}/loongarch64/consts.rs | 0 src/{ => bare/arch}/loongarch64/context.rs | 0 src/{ => bare/arch}/loongarch64/kcontext.rs | 0 src/{ => bare/arch}/loongarch64/mod.rs | 0 src/{ => bare/arch}/loongarch64/page_table.rs | 0 src/{ => bare/arch}/loongarch64/sigtrx.rs | 0 src/{ => bare/arch}/loongarch64/timer.rs | 0 src/{ => bare/arch}/loongarch64/trap.rs | 0 src/{ => bare/arch}/loongarch64/unaligned.rs | 0 src/{x86_64 => bare/arch/riscv64}/barrier.rs | 2 +- .../arch}/riscv64/boards/cv1811h-fdt.dtb | Bin .../arch}/riscv64/boards/cv1811h-fdt.dts | 0 src/{ => bare/arch}/riscv64/boards/cv1811h.rs | 0 .../riscv64/boards/jh7110-visionfive-v2.dtb | Bin .../riscv64/boards/jh7110-visionfive-v2.dts | 0 src/{ => bare/arch}/riscv64/boards/k210.rs | 0 src/{ => bare/arch}/riscv64/boards/mod.rs | 0 src/{ => bare/arch}/riscv64/boards/qemu.rs | 0 src/{ => bare/arch}/riscv64/consts.rs | 0 src/{ => bare/arch}/riscv64/context.rs | 0 src/{ => bare/arch}/riscv64/entry.rs | 2 +- src/{ => bare/arch}/riscv64/interrupt.rs | 4 +- src/{ => bare/arch}/riscv64/kcontext.rs | 0 src/{ => bare/arch}/riscv64/mod.rs | 15 +- src/{ => bare/arch}/riscv64/page_table/mod.rs | 6 +- .../arch}/riscv64/page_table/sigtrx.rs | 5 +- .../arch}/riscv64/page_table/sv39.rs | 10 +- src/{ => bare/arch}/riscv64/sbi.rs | 0 src/{ => bare/arch}/riscv64/timer.rs | 2 +- src/{ => bare/arch}/x86_64/apic.rs | 0 src/{riscv64 => bare/arch/x86_64}/barrier.rs | 0 src/{ => bare/arch}/x86_64/consts.rs | 0 src/{ => bare/arch}/x86_64/context.rs | 0 src/{ => bare/arch}/x86_64/gdt.rs | 0 src/{ => bare/arch}/x86_64/idt.rs | 0 src/{ => bare/arch}/x86_64/interrupt.rs | 0 src/{ => bare/arch}/x86_64/kcontext.rs | 0 src/{ => bare/arch}/x86_64/mod.rs | 0 src/{ => bare/arch}/x86_64/multiboot.S | 0 src/{ => bare/arch}/x86_64/multiboot.rs | 0 src/{ => bare/arch}/x86_64/page_table.rs | 0 src/{ => bare/arch}/x86_64/sigtrx.rs | 0 src/{ => bare/arch}/x86_64/time.rs | 0 src/{ => bare/arch}/x86_64/trap.S | 0 src/{ => bare/arch}/x86_64/uart.rs | 0 src/{ => bare}/debug.rs | 0 src/{ => bare}/instruction.rs | 0 src/{ => bare}/irq.rs | 0 src/{ => bare}/mem.rs | 0 src/bare/mod.rs | 267 +++++++++++++++++ src/{ => bare}/time.rs | 0 src/{ => common}/addr.rs | 2 +- src/{ => common}/api.rs | 2 +- src/common/consts.rs | 10 + src/common/mod.rs | 17 ++ src/{ => common}/multicore.rs | 0 src/{ => common}/pagetable.rs | 4 +- src/consts.rs | 21 -- src/lib.rs | 282 ++---------------- src/libos/mod.rs | 0 src/utils/mod.rs | 1 + src/{once/mod.rs => utils/once.rs} | 0 79 files changed, 340 insertions(+), 313 deletions(-) rename src/{ => bare/arch}/aarch64/barrier.rs (100%) rename src/{ => bare/arch}/aarch64/boot.rs (100%) rename src/{ => bare/arch}/aarch64/consts.rs (100%) rename src/{ => bare/arch}/aarch64/context.rs (100%) rename src/{ => bare/arch}/aarch64/gic.rs (100%) rename src/{ => bare/arch}/aarch64/kcontext.rs (100%) rename src/{ => bare/arch}/aarch64/mod.rs (100%) rename src/{ => bare/arch}/aarch64/page_table.rs (100%) rename src/{ => bare/arch}/aarch64/pl011.rs (100%) rename src/{ => bare/arch}/aarch64/psci.rs (100%) rename src/{ => bare/arch}/aarch64/timer.rs (100%) rename src/{ => bare/arch}/aarch64/trap.S (100%) rename src/{ => bare/arch}/aarch64/trap.rs (100%) rename src/{ => bare/arch}/loongarch64/barrier.rs (100%) rename src/{ => bare/arch}/loongarch64/boot.rs (100%) rename src/{ => bare/arch}/loongarch64/console.rs (100%) rename src/{ => bare/arch}/loongarch64/consts.rs (100%) rename src/{ => bare/arch}/loongarch64/context.rs (100%) rename src/{ => bare/arch}/loongarch64/kcontext.rs (100%) rename src/{ => bare/arch}/loongarch64/mod.rs (100%) rename src/{ => bare/arch}/loongarch64/page_table.rs (100%) rename src/{ => bare/arch}/loongarch64/sigtrx.rs (100%) rename src/{ => bare/arch}/loongarch64/timer.rs (100%) rename src/{ => bare/arch}/loongarch64/trap.rs (100%) rename src/{ => bare/arch}/loongarch64/unaligned.rs (100%) rename src/{x86_64 => bare/arch/riscv64}/barrier.rs (81%) rename src/{ => bare/arch}/riscv64/boards/cv1811h-fdt.dtb (100%) rename src/{ => bare/arch}/riscv64/boards/cv1811h-fdt.dts (100%) rename src/{ => bare/arch}/riscv64/boards/cv1811h.rs (100%) rename src/{ => bare/arch}/riscv64/boards/jh7110-visionfive-v2.dtb (100%) rename src/{ => bare/arch}/riscv64/boards/jh7110-visionfive-v2.dts (100%) rename src/{ => bare/arch}/riscv64/boards/k210.rs (100%) rename src/{ => bare/arch}/riscv64/boards/mod.rs (100%) rename src/{ => bare/arch}/riscv64/boards/qemu.rs (100%) rename src/{ => bare/arch}/riscv64/consts.rs (100%) rename src/{ => bare/arch}/riscv64/context.rs (100%) rename src/{ => bare/arch}/riscv64/entry.rs (99%) rename src/{ => bare/arch}/riscv64/interrupt.rs (98%) rename src/{ => bare/arch}/riscv64/kcontext.rs (100%) rename src/{ => bare/arch}/riscv64/mod.rs (92%) rename src/{ => bare/arch}/riscv64/page_table/mod.rs (89%) rename src/{ => bare/arch}/riscv64/page_table/sigtrx.rs (93%) rename src/{ => bare/arch}/riscv64/page_table/sv39.rs (96%) rename src/{ => bare/arch}/riscv64/sbi.rs (100%) rename src/{ => bare/arch}/riscv64/timer.rs (92%) rename src/{ => bare/arch}/x86_64/apic.rs (100%) rename src/{riscv64 => bare/arch/x86_64}/barrier.rs (100%) rename src/{ => bare/arch}/x86_64/consts.rs (100%) rename src/{ => bare/arch}/x86_64/context.rs (100%) rename src/{ => bare/arch}/x86_64/gdt.rs (100%) rename src/{ => bare/arch}/x86_64/idt.rs (100%) rename src/{ => bare/arch}/x86_64/interrupt.rs (100%) rename src/{ => bare/arch}/x86_64/kcontext.rs (100%) rename src/{ => bare/arch}/x86_64/mod.rs (100%) rename src/{ => bare/arch}/x86_64/multiboot.S (100%) rename src/{ => bare/arch}/x86_64/multiboot.rs (100%) rename src/{ => bare/arch}/x86_64/page_table.rs (100%) rename src/{ => bare/arch}/x86_64/sigtrx.rs (100%) rename src/{ => bare/arch}/x86_64/time.rs (100%) rename src/{ => bare/arch}/x86_64/trap.S (100%) rename src/{ => bare/arch}/x86_64/uart.rs (100%) rename src/{ => bare}/debug.rs (100%) rename src/{ => bare}/instruction.rs (100%) rename src/{ => bare}/irq.rs (100%) rename src/{ => bare}/mem.rs (100%) create mode 100644 src/bare/mod.rs rename src/{ => bare}/time.rs (100%) rename src/{ => common}/addr.rs (99%) rename src/{ => common}/api.rs (93%) create mode 100644 src/common/consts.rs create mode 100644 src/common/mod.rs rename src/{ => common}/multicore.rs (100%) rename src/{ => common}/pagetable.rs (99%) delete mode 100644 src/consts.rs create mode 100644 src/libos/mod.rs create mode 100644 src/utils/mod.rs rename src/{once/mod.rs => utils/once.rs} (100%) diff --git a/Cargo.toml b/Cargo.toml index 4d50f5c..c505232 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ repository = "https://github.com/Byte-OS/polyhal" [features] kcontext = [] multicore = [] +libos = [] default = ["multicore"] diff --git a/src/aarch64/barrier.rs b/src/bare/arch/aarch64/barrier.rs similarity index 100% rename from src/aarch64/barrier.rs rename to src/bare/arch/aarch64/barrier.rs diff --git a/src/aarch64/boot.rs b/src/bare/arch/aarch64/boot.rs similarity index 100% rename from src/aarch64/boot.rs rename to src/bare/arch/aarch64/boot.rs diff --git a/src/aarch64/consts.rs b/src/bare/arch/aarch64/consts.rs similarity index 100% rename from src/aarch64/consts.rs rename to src/bare/arch/aarch64/consts.rs diff --git a/src/aarch64/context.rs b/src/bare/arch/aarch64/context.rs similarity index 100% rename from src/aarch64/context.rs rename to src/bare/arch/aarch64/context.rs diff --git a/src/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs similarity index 100% rename from src/aarch64/gic.rs rename to src/bare/arch/aarch64/gic.rs diff --git a/src/aarch64/kcontext.rs b/src/bare/arch/aarch64/kcontext.rs similarity index 100% rename from src/aarch64/kcontext.rs rename to src/bare/arch/aarch64/kcontext.rs diff --git a/src/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs similarity index 100% rename from src/aarch64/mod.rs rename to src/bare/arch/aarch64/mod.rs diff --git a/src/aarch64/page_table.rs b/src/bare/arch/aarch64/page_table.rs similarity index 100% rename from src/aarch64/page_table.rs rename to src/bare/arch/aarch64/page_table.rs diff --git a/src/aarch64/pl011.rs b/src/bare/arch/aarch64/pl011.rs similarity index 100% rename from src/aarch64/pl011.rs rename to src/bare/arch/aarch64/pl011.rs diff --git a/src/aarch64/psci.rs b/src/bare/arch/aarch64/psci.rs similarity index 100% rename from src/aarch64/psci.rs rename to src/bare/arch/aarch64/psci.rs diff --git a/src/aarch64/timer.rs b/src/bare/arch/aarch64/timer.rs similarity index 100% rename from src/aarch64/timer.rs rename to src/bare/arch/aarch64/timer.rs diff --git a/src/aarch64/trap.S b/src/bare/arch/aarch64/trap.S similarity index 100% rename from src/aarch64/trap.S rename to src/bare/arch/aarch64/trap.S diff --git a/src/aarch64/trap.rs b/src/bare/arch/aarch64/trap.rs similarity index 100% rename from src/aarch64/trap.rs rename to src/bare/arch/aarch64/trap.rs diff --git a/src/loongarch64/barrier.rs b/src/bare/arch/loongarch64/barrier.rs similarity index 100% rename from src/loongarch64/barrier.rs rename to src/bare/arch/loongarch64/barrier.rs diff --git a/src/loongarch64/boot.rs b/src/bare/arch/loongarch64/boot.rs similarity index 100% rename from src/loongarch64/boot.rs rename to src/bare/arch/loongarch64/boot.rs diff --git a/src/loongarch64/console.rs b/src/bare/arch/loongarch64/console.rs similarity index 100% rename from src/loongarch64/console.rs rename to src/bare/arch/loongarch64/console.rs diff --git a/src/loongarch64/consts.rs b/src/bare/arch/loongarch64/consts.rs similarity index 100% rename from src/loongarch64/consts.rs rename to src/bare/arch/loongarch64/consts.rs diff --git a/src/loongarch64/context.rs b/src/bare/arch/loongarch64/context.rs similarity index 100% rename from src/loongarch64/context.rs rename to src/bare/arch/loongarch64/context.rs diff --git a/src/loongarch64/kcontext.rs b/src/bare/arch/loongarch64/kcontext.rs similarity index 100% rename from src/loongarch64/kcontext.rs rename to src/bare/arch/loongarch64/kcontext.rs diff --git a/src/loongarch64/mod.rs b/src/bare/arch/loongarch64/mod.rs similarity index 100% rename from src/loongarch64/mod.rs rename to src/bare/arch/loongarch64/mod.rs diff --git a/src/loongarch64/page_table.rs b/src/bare/arch/loongarch64/page_table.rs similarity index 100% rename from src/loongarch64/page_table.rs rename to src/bare/arch/loongarch64/page_table.rs diff --git a/src/loongarch64/sigtrx.rs b/src/bare/arch/loongarch64/sigtrx.rs similarity index 100% rename from src/loongarch64/sigtrx.rs rename to src/bare/arch/loongarch64/sigtrx.rs diff --git a/src/loongarch64/timer.rs b/src/bare/arch/loongarch64/timer.rs similarity index 100% rename from src/loongarch64/timer.rs rename to src/bare/arch/loongarch64/timer.rs diff --git a/src/loongarch64/trap.rs b/src/bare/arch/loongarch64/trap.rs similarity index 100% rename from src/loongarch64/trap.rs rename to src/bare/arch/loongarch64/trap.rs diff --git a/src/loongarch64/unaligned.rs b/src/bare/arch/loongarch64/unaligned.rs similarity index 100% rename from src/loongarch64/unaligned.rs rename to src/bare/arch/loongarch64/unaligned.rs diff --git a/src/x86_64/barrier.rs b/src/bare/arch/riscv64/barrier.rs similarity index 81% rename from src/x86_64/barrier.rs rename to src/bare/arch/riscv64/barrier.rs index 6a42705..bcc15ba 100644 --- a/src/x86_64/barrier.rs +++ b/src/bare/arch/riscv64/barrier.rs @@ -1,4 +1,4 @@ -use crate::mem::Barrier; +use crate::Barrier; impl Barrier { #[inline] diff --git a/src/riscv64/boards/cv1811h-fdt.dtb b/src/bare/arch/riscv64/boards/cv1811h-fdt.dtb similarity index 100% rename from src/riscv64/boards/cv1811h-fdt.dtb rename to src/bare/arch/riscv64/boards/cv1811h-fdt.dtb diff --git a/src/riscv64/boards/cv1811h-fdt.dts b/src/bare/arch/riscv64/boards/cv1811h-fdt.dts similarity index 100% rename from src/riscv64/boards/cv1811h-fdt.dts rename to src/bare/arch/riscv64/boards/cv1811h-fdt.dts diff --git a/src/riscv64/boards/cv1811h.rs b/src/bare/arch/riscv64/boards/cv1811h.rs similarity index 100% rename from src/riscv64/boards/cv1811h.rs rename to src/bare/arch/riscv64/boards/cv1811h.rs diff --git a/src/riscv64/boards/jh7110-visionfive-v2.dtb b/src/bare/arch/riscv64/boards/jh7110-visionfive-v2.dtb similarity index 100% rename from src/riscv64/boards/jh7110-visionfive-v2.dtb rename to src/bare/arch/riscv64/boards/jh7110-visionfive-v2.dtb diff --git a/src/riscv64/boards/jh7110-visionfive-v2.dts b/src/bare/arch/riscv64/boards/jh7110-visionfive-v2.dts similarity index 100% rename from src/riscv64/boards/jh7110-visionfive-v2.dts rename to src/bare/arch/riscv64/boards/jh7110-visionfive-v2.dts diff --git a/src/riscv64/boards/k210.rs b/src/bare/arch/riscv64/boards/k210.rs similarity index 100% rename from src/riscv64/boards/k210.rs rename to src/bare/arch/riscv64/boards/k210.rs diff --git a/src/riscv64/boards/mod.rs b/src/bare/arch/riscv64/boards/mod.rs similarity index 100% rename from src/riscv64/boards/mod.rs rename to src/bare/arch/riscv64/boards/mod.rs diff --git a/src/riscv64/boards/qemu.rs b/src/bare/arch/riscv64/boards/qemu.rs similarity index 100% rename from src/riscv64/boards/qemu.rs rename to src/bare/arch/riscv64/boards/qemu.rs diff --git a/src/riscv64/consts.rs b/src/bare/arch/riscv64/consts.rs similarity index 100% rename from src/riscv64/consts.rs rename to src/bare/arch/riscv64/consts.rs diff --git a/src/riscv64/context.rs b/src/bare/arch/riscv64/context.rs similarity index 100% rename from src/riscv64/context.rs rename to src/bare/arch/riscv64/context.rs diff --git a/src/riscv64/entry.rs b/src/bare/arch/riscv64/entry.rs similarity index 99% rename from src/riscv64/entry.rs rename to src/bare/arch/riscv64/entry.rs index 1bf79ce..4b47db6 100644 --- a/src/riscv64/entry.rs +++ b/src/bare/arch/riscv64/entry.rs @@ -1,6 +1,6 @@ use core::arch::riscv64::sfence_vma_all; -use crate::pagetable::{PageTable, PTE}; +use crate::{PageTable, PTE}; use crate::VIRT_ADDR_START; use super::page_table::PTEFlags; diff --git a/src/riscv64/interrupt.rs b/src/bare/arch/riscv64/interrupt.rs similarity index 98% rename from src/riscv64/interrupt.rs rename to src/bare/arch/riscv64/interrupt.rs index 6e6bb95..7183692 100644 --- a/src/riscv64/interrupt.rs +++ b/src/bare/arch/riscv64/interrupt.rs @@ -141,7 +141,7 @@ fn kernel_callback(context: &mut TrapFrame) -> TrapType { panic!("未知中断: {:#x?}", context); } }; - unsafe { crate::api::_interrupt_for_arch(context, trap_type) }; + unsafe { crate::_interrupt_for_arch(context, trap_type) }; trap_type } @@ -169,7 +169,7 @@ pub unsafe extern "C" fn kernelvec() { LOAD_GENERAL_REGS sret ", - cx_size = const crate::consts::TRAPFRAME_SIZE, + cx_size = const crate::TRAPFRAME_SIZE, options(noreturn) ) } diff --git a/src/riscv64/kcontext.rs b/src/bare/arch/riscv64/kcontext.rs similarity index 100% rename from src/riscv64/kcontext.rs rename to src/bare/arch/riscv64/kcontext.rs diff --git a/src/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs similarity index 92% rename from src/riscv64/mod.rs rename to src/bare/arch/riscv64/mod.rs index 93b7d48..81d3317 100644 --- a/src/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -20,6 +20,7 @@ use fdt::Fdt; pub use interrupt::{ disable_irq, enable_external_irq, enable_irq, run_user_task, run_user_task_forever, }; +pub use boards::*; use sbi::*; pub use sbi::shutdown; @@ -29,7 +30,8 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext} use riscv::register::sstatus; -use crate::{api::frame_alloc, multicore::MultiCore, once::LazyInit, CPU_NUM, DTB_BIN, MEM_AREA}; +use crate::{frame_alloc, MultiCore, utils::once::LazyInit}; +use super::{CPU_NUM, DTB_BIN, MEM_AREA}; #[percpu::def_percpu] static CPU_ID: usize = 0; @@ -37,7 +39,7 @@ static CPU_ID: usize = 0; static DTB_PTR: LazyInit = LazyInit::new(); pub(crate) fn rust_main(hartid: usize, device_tree: usize) { - crate::clear_bss(); + super::clear_bss(); // Init allocator percpu::init(4); percpu::set_local_thread_pointer(hartid); @@ -60,7 +62,7 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { DTB_PTR.init_by(device_tree); - unsafe { crate::api::_main_for_arch(hartid) }; + unsafe { crate::_main_for_arch(hartid) }; shutdown(); } @@ -78,7 +80,7 @@ pub(crate) extern "C" fn rust_secondary_main(hartid: usize) { } info!("secondary hart {} started", hartid); - unsafe { crate::api::_main_for_arch(hartid) }; + unsafe { crate::_main_for_arch(hartid) }; shutdown(); } @@ -132,10 +134,7 @@ impl MultiCore { /// Boot all application cores. pub fn boot_all() { use self::entry::secondary_start; - use crate::{ - addr::VirtPage, - pagetable::{MappingFlags, MappingSize, PageTable}, - }; + use crate::{VirtPage, MappingFlags, MappingSize, PageTable}; let page_table = PageTable::current(); diff --git a/src/riscv64/page_table/mod.rs b/src/bare/arch/riscv64/page_table/mod.rs similarity index 89% rename from src/riscv64/page_table/mod.rs rename to src/bare/arch/riscv64/page_table/mod.rs index 9f07067..aa1d389 100644 --- a/src/riscv64/page_table/mod.rs +++ b/src/bare/arch/riscv64/page_table/mod.rs @@ -1,12 +1,12 @@ pub mod sigtrx; -mod sv39; +pub mod sv39; use core::arch::riscv64::sfence_vma; pub use sv39::*; -use crate::addr::VirtAddr; -use crate::pagetable::TLB; +use crate::VirtAddr; +use crate::TLB; /// TLB operations impl TLB { diff --git a/src/riscv64/page_table/sigtrx.rs b/src/bare/arch/riscv64/page_table/sigtrx.rs similarity index 93% rename from src/riscv64/page_table/sigtrx.rs rename to src/bare/arch/riscv64/page_table/sigtrx.rs index acd352e..42bce9b 100644 --- a/src/riscv64/page_table/sigtrx.rs +++ b/src/bare/arch/riscv64/page_table/sigtrx.rs @@ -1,7 +1,4 @@ -use crate::{ - pagetable::{PageTable, PTE}, - VIRT_ADDR_START, -}; +use crate::{PageTable, PTE, VIRT_ADDR_START}; use super::PTEFlags; diff --git a/src/riscv64/page_table/sv39.rs b/src/bare/arch/riscv64/page_table/sv39.rs similarity index 96% rename from src/riscv64/page_table/sv39.rs rename to src/bare/arch/riscv64/page_table/sv39.rs index e8ab7a6..73f27fd 100644 --- a/src/riscv64/page_table/sv39.rs +++ b/src/bare/arch/riscv64/page_table/sv39.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; use riscv::register::satp; -use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::kernel_page_table; -use crate::pagetable::MappingFlags; -use crate::pagetable::{PageTable, PTE, TLB}; +use crate::MappingFlags; +use crate::{PageTable, PTE, TLB}; use super::sigtrx::get_trx_mapping; @@ -198,9 +198,9 @@ impl PageTable { self.release(); let kernel_arr = Self::get_pte_list(kernel_page_table().0); let arr = Self::get_pte_list(self.0); - arr[0x100..].copy_from_slice(&kernel_arr[0x100..]); + arr[0x100..].copy_from_slice(&kernel_arr[0x100..]); // 0xffff ffc000000000 // TODO: using map kernel in the boot instead of map here manually - arr[0x104] = PTE::from_addr(get_trx_mapping(), PTEFlags::V); + arr[0x104] = PTE::from_addr(get_trx_mapping(), PTEFlags::V); // 0xffff ffc100000000 arr[0..0x100].fill(PTE(0)); } diff --git a/src/riscv64/sbi.rs b/src/bare/arch/riscv64/sbi.rs similarity index 100% rename from src/riscv64/sbi.rs rename to src/bare/arch/riscv64/sbi.rs diff --git a/src/riscv64/timer.rs b/src/bare/arch/riscv64/timer.rs similarity index 92% rename from src/riscv64/timer.rs rename to src/bare/arch/riscv64/timer.rs index 8d4ec72..42dda20 100644 --- a/src/riscv64/timer.rs +++ b/src/bare/arch/riscv64/timer.rs @@ -1,4 +1,4 @@ -use crate::current_arch::boards::CLOCK_FREQ; +use crate::CLOCK_FREQ; use crate::time::Time; use riscv::register::{sie, time}; diff --git a/src/x86_64/apic.rs b/src/bare/arch/x86_64/apic.rs similarity index 100% rename from src/x86_64/apic.rs rename to src/bare/arch/x86_64/apic.rs diff --git a/src/riscv64/barrier.rs b/src/bare/arch/x86_64/barrier.rs similarity index 100% rename from src/riscv64/barrier.rs rename to src/bare/arch/x86_64/barrier.rs diff --git a/src/x86_64/consts.rs b/src/bare/arch/x86_64/consts.rs similarity index 100% rename from src/x86_64/consts.rs rename to src/bare/arch/x86_64/consts.rs diff --git a/src/x86_64/context.rs b/src/bare/arch/x86_64/context.rs similarity index 100% rename from src/x86_64/context.rs rename to src/bare/arch/x86_64/context.rs diff --git a/src/x86_64/gdt.rs b/src/bare/arch/x86_64/gdt.rs similarity index 100% rename from src/x86_64/gdt.rs rename to src/bare/arch/x86_64/gdt.rs diff --git a/src/x86_64/idt.rs b/src/bare/arch/x86_64/idt.rs similarity index 100% rename from src/x86_64/idt.rs rename to src/bare/arch/x86_64/idt.rs diff --git a/src/x86_64/interrupt.rs b/src/bare/arch/x86_64/interrupt.rs similarity index 100% rename from src/x86_64/interrupt.rs rename to src/bare/arch/x86_64/interrupt.rs diff --git a/src/x86_64/kcontext.rs b/src/bare/arch/x86_64/kcontext.rs similarity index 100% rename from src/x86_64/kcontext.rs rename to src/bare/arch/x86_64/kcontext.rs diff --git a/src/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs similarity index 100% rename from src/x86_64/mod.rs rename to src/bare/arch/x86_64/mod.rs diff --git a/src/x86_64/multiboot.S b/src/bare/arch/x86_64/multiboot.S similarity index 100% rename from src/x86_64/multiboot.S rename to src/bare/arch/x86_64/multiboot.S diff --git a/src/x86_64/multiboot.rs b/src/bare/arch/x86_64/multiboot.rs similarity index 100% rename from src/x86_64/multiboot.rs rename to src/bare/arch/x86_64/multiboot.rs diff --git a/src/x86_64/page_table.rs b/src/bare/arch/x86_64/page_table.rs similarity index 100% rename from src/x86_64/page_table.rs rename to src/bare/arch/x86_64/page_table.rs diff --git a/src/x86_64/sigtrx.rs b/src/bare/arch/x86_64/sigtrx.rs similarity index 100% rename from src/x86_64/sigtrx.rs rename to src/bare/arch/x86_64/sigtrx.rs diff --git a/src/x86_64/time.rs b/src/bare/arch/x86_64/time.rs similarity index 100% rename from src/x86_64/time.rs rename to src/bare/arch/x86_64/time.rs diff --git a/src/x86_64/trap.S b/src/bare/arch/x86_64/trap.S similarity index 100% rename from src/x86_64/trap.S rename to src/bare/arch/x86_64/trap.S diff --git a/src/x86_64/uart.rs b/src/bare/arch/x86_64/uart.rs similarity index 100% rename from src/x86_64/uart.rs rename to src/bare/arch/x86_64/uart.rs diff --git a/src/debug.rs b/src/bare/debug.rs similarity index 100% rename from src/debug.rs rename to src/bare/debug.rs diff --git a/src/instruction.rs b/src/bare/instruction.rs similarity index 100% rename from src/instruction.rs rename to src/bare/instruction.rs diff --git a/src/irq.rs b/src/bare/irq.rs similarity index 100% rename from src/irq.rs rename to src/bare/irq.rs diff --git a/src/mem.rs b/src/bare/mem.rs similarity index 100% rename from src/mem.rs rename to src/bare/mem.rs diff --git a/src/bare/mod.rs b/src/bare/mod.rs new file mode 100644 index 0000000..f94d2a7 --- /dev/null +++ b/src/bare/mod.rs @@ -0,0 +1,267 @@ +//! This is a crate to help you supporting multiple platforms. +//! +//! If you want to use this crate, you should implement the following trait in your code. +//! +//! ```rust +//! /// impl +//! pub struct PageAllocImpl; +//! +//! impl PageAlloc for PageAllocImpl { +//! fn alloc(&self) -> PhysPage { +//! frame_alloc() +//! } +//! +//! fn dealloc(&self, ppn: PhysPage) { +//! frame::frame_dealloc(ppn) +//! } +//! } +//! +//! /// kernel interrupt +//! #[polyhal::arch_interrupt] +//! fn kernel_interrupt(ctx: &mut TrapFrame, trap_type: TrapType) { +//! // println!("trap_type @ {:x?} {:#x?}", trap_type, ctx); +//! match trap_type { +//! Breakpoint => return, +//! UserEnvCall => { +//! // jump to next instruction anyway +//! ctx.syscall_ok(); +//! log::info!("Handle a syscall"); +//! } +//! StorePageFault(_paddr) | LoadPageFault(_paddr) | InstructionPageFault(_paddr) => { +//! log::info!("page fault"); +//! } +//! IllegalInstruction(_) => { +//! log::info!("illegal instruction"); +//! } +//! Time => { +//! log::info!("Timer"); +//! } +//! _ => { +//! log::warn!("unsuspended trap type: {:?}", trap_type); +//! } +//! } +//! } +//! +//! #[polyhal::arch_entry] +//! /// kernel main function, entry point. +//! fn main(hartid: usize) { +//! if hartid != 0 { +//! return; +//! } +//! +//! println!("[kernel] Hello, world!"); +//! allocator::init_allocator(); +//! logging::init(Some("trace")); +//! println!("init logging"); +//! +//! // Init page alloc for polyhal +//! polyhal::init(&PageAllocImpl); +//! +//! polyhal::init_interrupt(); +//! +//! get_mem_areas().into_iter().for_each(|(start, size)| { +//! println!("init memory region {:#x} - {:#x}", start, start + size); +//! frame::add_frame_range(start, start + size); +//! }); +//! panic!("end of rust_main!"); +//! } +//! +//! ``` +//! +//! The main(hardid: usize) is the entry point. +//! +//! You can find details in the example. +//! +//! In this crate you can find some interfaces to use. +//! These interfaces are classified into some structures. +//! +//! [PhysPage]: PhysicalPage And its associated functions. +//! +//! [PhysAddr](addr::PhysAddr): PhysicalAddr And its associated functions. +//! +//! [VirtPage](addr::VirtPage): VirtualPage And its associated functions. +//! +//! [VirtAddr](addr::VirtAddr): VirtualAddr And its associated functions. +//! +//! [IRQ](irq::IRQ): Interrupt ReQuest management, includes enable and disable. +//! +//! [Barrier](mem::Barrier): Memory barrier operations. +//! +//! [MultiCore](multicore::MultiCore): MultiCore operations. Now only [multicore::MultiCore::boot_all] is available. +//! +//! [PageTable]: PageTable and its associated functions. +//! +//! [MappingFlags](pagetable::MappingFlags): MappingFlags, This is an abstraction of pagetable flags. +//! +//! [TLB](pagetable::TLB): TLB operations. +//! +//! [PageTableWrapper](pagetable::PageTableWrapper): PageTableWrapper. It will dealloc all pagetable leaf when it was dropping. +//! +//! [Time](time::Time): Time and its associated functions. +//! +//! [Instruction](instruction::Instruction): Some platform instruction. +//! +//! There also provides a debugging console(recommanded only for debugging). +//! +//! [DebugConsole](debug::DebugConsole): A console for debugging. +//! +//! This crate provides a [TrapFrame], you can operate it through index with [TrapFrameArgs]. +//! +//! If you are using kernel task. You should to enable feature `kcontext`. +//! Then you can use kernel task context structure [KContext], and manipulate it with [KContextArgs]. +//! +//! You can switch kcontext through [context_switch_pt] or [context_switch] +//! +//! There are also some consts. +//! +//! [VIRT_ADDR_START]: This is a higher half kernel offset address. +//! [USER_VADDR_END]: End of the user address range. +//! [PAGE_SIZE]: The size of the page. +//! +//! You can get some device information using the functions below. +//! [get_mem_areas]: Get the avaliable memorys. +//! [get_fdt]: Get the Fdt structure(fdt is a rust dtb operation crate). +//! [get_cpu_num]: Get the number of cpus. +//! +//! TIPS: You should have finished [init] before using [get_mem_areas] and [get_fdt]. + + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + #[path = "arch/x86_64/mod.rs"] + mod current_arch; + } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + #[path = "arch/riscv64/mod.rs"] + pub mod current_arch; + } else if #[cfg(target_arch = "aarch64")] { + #[path = "arch/aarch64/mod.rs"] + pub mod current_arch; + pub use self::arch::timer_interrupt_vector; + } else if #[cfg(target_arch = "loongarch64")] { + #[path = "arch/loongarch64/mod.rs"] + pub mod current_arch; + } else { + compile_error!("Unsupported target_arch"); + } +} + +pub mod debug; +pub mod instruction; +pub mod irq; +pub mod mem; +pub mod time; +use core::mem::size_of; +pub use current_arch::*; +use alloc::vec::Vec; +pub use mem::Barrier; + +use cfg_if::cfg_if; +use fdt::Fdt; +use crate::utils::once::LazyInit; + +/// Trap Frame + +pub use polyhal_macro::{arch_entry, arch_interrupt}; + +pub const PAGE_SIZE: usize; +pub const USER_VADDR_END: usize = PageTable::USER_VADDR_END; + +/// Kernel Context Arg Type. +/// +/// Using this by Index and IndexMut trait bound on KContext. +#[derive(Debug)] +#[cfg(feature = "kcontext")] +pub enum KContextArgs { + /// Kernel Stack Pointer + KSP, + /// Kernel Thread Pointer + KTP, + /// Kernel Program Counter + KPC, +} + +/// Trap Frame Arg Type +/// +/// Using this by Index and IndexMut trait bound on TrapFrame +#[derive(Debug)] +pub enum TrapFrameArgs { + SEPC, + RA, + SP, + RET, + ARG0, + ARG1, + ARG2, + TLS, + SYSCALL, +} + +#[derive(Debug, Clone, Copy)] +pub enum TrapType { + Breakpoint, + UserEnvCall, + Time, + Unknown, + SupervisorExternal, + StorePageFault(usize), + LoadPageFault(usize), + InstructionPageFault(usize), + IllegalInstruction(usize), +} + +#[link_section = ".bss.stack"] +static mut BOOT_STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; + +pub(crate) fn clear_bss() { + extern "C" { + fn _sbss(); + fn _ebss(); + } + unsafe { + core::slice::from_raw_parts_mut( + _sbss as usize as *mut u128, + (_ebss as usize - _sbss as usize) / size_of::(), + ) + .fill(0); + } +} + +pub trait PageAlloc: Sync { + fn alloc(&self) -> PhysPage; + fn dealloc(&self, ppn: PhysPage); +} + +static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); + +/// Init arch with page allocator, like log crate +/// Please initialize the allocator before calling this function. +pub fn init(page_alloc: &'static dyn PageAlloc) { + PAGE_ALLOC.init_by(page_alloc); + + // Init current architecture + current_arch::arch_init(); +} + +/// Store the number of cpu, this will fill up by startup function. +pub(crate) static CPU_NUM: LazyInit = LazyInit::new(); + +/// Store the memory area, this will fill up by the arch_init() function in each architecture. +pub(crate) static MEM_AREA: LazyInit> = LazyInit::new(); + +/// Store the DTB_area, this will fill up by the arch_init() function in each architecture +static DTB_BIN: LazyInit> = LazyInit::new(); + +/// Get the memory area, this function should be called after initialization +pub fn get_mem_areas() -> Vec<(usize, usize)> { + MEM_AREA.clone() +} + +/// Get the fdt +pub fn get_fdt() -> Option> { + Fdt::new(&DTB_BIN).ok() +} + +/// Get the number of cpus +pub fn get_cpu_num() -> usize { + *CPU_NUM +} diff --git a/src/time.rs b/src/bare/time.rs similarity index 100% rename from src/time.rs rename to src/bare/time.rs diff --git a/src/addr.rs b/src/common/addr.rs similarity index 99% rename from src/addr.rs rename to src/common/addr.rs index fffe527..062d1f1 100644 --- a/src/addr.rs +++ b/src/common/addr.rs @@ -5,7 +5,7 @@ use core::{ ops::Add, }; -use crate::{pagetable::PageTable, VIRT_ADDR_START}; +use crate::{PageTable, VIRT_ADDR_START}; #[repr(C)] #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] diff --git a/src/api.rs b/src/common/api.rs similarity index 93% rename from src/api.rs rename to src/common/api.rs index 043be68..746f1fe 100644 --- a/src/api.rs +++ b/src/common/api.rs @@ -1,4 +1,4 @@ -use crate::addr::PhysPage; +use crate::PhysPage; use crate::{TrapFrame, TrapType, PAGE_ALLOC}; extern "Rust" { diff --git a/src/common/consts.rs b/src/common/consts.rs new file mode 100644 index 0000000..1cc003c --- /dev/null +++ b/src/common/consts.rs @@ -0,0 +1,10 @@ +use core::mem::size_of; + +use crate::TrapFrame; + +/// Boot Stack Size. +/// TODO: reduce the boot stack size. Map stack in boot step. +pub const STACK_SIZE: usize = 0x8_0000; + +/// The size of the trap frame(diffent in each architecture.). +pub const TRAPFRAME_SIZE: usize = size_of::(); \ No newline at end of file diff --git a/src/common/mod.rs b/src/common/mod.rs new file mode 100644 index 0000000..4deb096 --- /dev/null +++ b/src/common/mod.rs @@ -0,0 +1,17 @@ +pub mod addr; +pub(crate) mod pagetable; +pub mod api; +pub mod consts; +#[cfg(feature = "multicore")] +pub mod multicore; + +/// bit macro will generate the number through a shift value. +/// +/// Here is an example. +/// You can use bit!(0) instead of 1 << 0. +/// bit!(39) instead of 1 << 39. +macro_rules! bit { + ($x:expr) => { + 1 << $x + }; +} \ No newline at end of file diff --git a/src/multicore.rs b/src/common/multicore.rs similarity index 100% rename from src/multicore.rs rename to src/common/multicore.rs diff --git a/src/pagetable.rs b/src/common/pagetable.rs similarity index 99% rename from src/pagetable.rs rename to src/common/pagetable.rs index 1170b53..bc964d1 100644 --- a/src/pagetable.rs +++ b/src/common/pagetable.rs @@ -1,7 +1,7 @@ use core::ops::Deref; -use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; -use crate::api::{frame_alloc, frame_dealloc}; +use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::{frame_alloc, frame_dealloc}; bitflags::bitflags! { /// Mapping flags for page table. diff --git a/src/consts.rs b/src/consts.rs deleted file mode 100644 index 9b6940e..0000000 --- a/src/consts.rs +++ /dev/null @@ -1,21 +0,0 @@ -use core::mem::size_of; - -use crate::TrapFrame; - -/// Boot Stack Size. -/// TODO: reduce the boot stack size. Map stack in boot step. -pub const STACK_SIZE: usize = 0x8_0000; - -/// The size of the trap frame(diffent in each architecture.). -pub const TRAPFRAME_SIZE: usize = size_of::(); - -/// bit macro will generate the number through a shift value. -/// -/// Here is an example. -/// You can use bit!(0) instead of 1 << 0. -/// bit!(39) instead of 1 << 39. -macro_rules! bit { - ($x:expr) => { - 1 << $x - }; -} diff --git a/src/lib.rs b/src/lib.rs index 0bd03b0..8397fe0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,275 +8,31 @@ #![cfg_attr(target_arch = "riscv64", feature(riscv_ext_intrinsics))] #![cfg_attr(target_arch = "aarch64", feature(const_option))] -//! This is a crate to help you supporting multiple platforms. -//! -//! If you want to use this crate, you should implement the following trait in your code. -//! -//! ```rust -//! /// impl -//! pub struct PageAllocImpl; -//! -//! impl PageAlloc for PageAllocImpl { -//! fn alloc(&self) -> PhysPage { -//! frame_alloc() -//! } -//! -//! fn dealloc(&self, ppn: PhysPage) { -//! frame::frame_dealloc(ppn) -//! } -//! } -//! -//! /// kernel interrupt -//! #[polyhal::arch_interrupt] -//! fn kernel_interrupt(ctx: &mut TrapFrame, trap_type: TrapType) { -//! // println!("trap_type @ {:x?} {:#x?}", trap_type, ctx); -//! match trap_type { -//! Breakpoint => return, -//! UserEnvCall => { -//! // jump to next instruction anyway -//! ctx.syscall_ok(); -//! log::info!("Handle a syscall"); -//! } -//! StorePageFault(_paddr) | LoadPageFault(_paddr) | InstructionPageFault(_paddr) => { -//! log::info!("page fault"); -//! } -//! IllegalInstruction(_) => { -//! log::info!("illegal instruction"); -//! } -//! Time => { -//! log::info!("Timer"); -//! } -//! _ => { -//! log::warn!("unsuspended trap type: {:?}", trap_type); -//! } -//! } -//! } -//! -//! #[polyhal::arch_entry] -//! /// kernel main function, entry point. -//! fn main(hartid: usize) { -//! if hartid != 0 { -//! return; -//! } -//! -//! println!("[kernel] Hello, world!"); -//! allocator::init_allocator(); -//! logging::init(Some("trace")); -//! println!("init logging"); -//! -//! // Init page alloc for polyhal -//! polyhal::init(&PageAllocImpl); -//! -//! polyhal::init_interrupt(); -//! -//! get_mem_areas().into_iter().for_each(|(start, size)| { -//! println!("init memory region {:#x} - {:#x}", start, start + size); -//! frame::add_frame_range(start, start + size); -//! }); -//! panic!("end of rust_main!"); -//! } -//! -//! ``` -//! -//! The main(hardid: usize) is the entry point. -//! -//! You can find details in the example. -//! -//! In this crate you can find some interfaces to use. -//! These interfaces are classified into some structures. -//! -//! [PhysPage]: PhysicalPage And its associated functions. -//! -//! [PhysAddr](addr::PhysAddr): PhysicalAddr And its associated functions. -//! -//! [VirtPage](addr::VirtPage): VirtualPage And its associated functions. -//! -//! [VirtAddr](addr::VirtAddr): VirtualAddr And its associated functions. -//! -//! [IRQ](irq::IRQ): Interrupt ReQuest management, includes enable and disable. -//! -//! [Barrier](mem::Barrier): Memory barrier operations. -//! -//! [MultiCore](multicore::MultiCore): MultiCore operations. Now only [multicore::MultiCore::boot_all] is available. -//! -//! [PageTable]: PageTable and its associated functions. -//! -//! [MappingFlags](pagetable::MappingFlags): MappingFlags, This is an abstraction of pagetable flags. -//! -//! [TLB](pagetable::TLB): TLB operations. -//! -//! [PageTableWrapper](pagetable::PageTableWrapper): PageTableWrapper. It will dealloc all pagetable leaf when it was dropping. -//! -//! [Time](time::Time): Time and its associated functions. -//! -//! [Instruction](instruction::Instruction): Some platform instruction. -//! -//! There also provides a debugging console(recommanded only for debugging). -//! -//! [DebugConsole](debug::DebugConsole): A console for debugging. -//! -//! This crate provides a [TrapFrame], you can operate it through index with [TrapFrameArgs]. -//! -//! If you are using kernel task. You should to enable feature `kcontext`. -//! Then you can use kernel task context structure [KContext], and manipulate it with [KContextArgs]. -//! -//! You can switch kcontext through [context_switch_pt] or [context_switch] -//! -//! There are also some consts. -//! -//! [VIRT_ADDR_START]: This is a higher half kernel offset address. -//! [USER_VADDR_END]: End of the user address range. -//! [PAGE_SIZE]: The size of the page. -//! -//! You can get some device information using the functions below. -//! [get_mem_areas]: Get the avaliable memorys. -//! [get_fdt]: Get the Fdt structure(fdt is a rust dtb operation crate). -//! [get_cpu_num]: Get the number of cpus. -//! -//! TIPS: You should have finished [init] before using [get_mem_areas] and [get_fdt]. - extern crate alloc; #[macro_use] extern crate log; - -pub mod addr; -pub mod api; #[macro_use] -pub mod consts; -pub mod debug; -pub mod instruction; -pub mod irq; -pub mod mem; -#[cfg(feature = "multicore")] -pub mod multicore; -pub mod once; -pub mod pagetable; -pub mod time; -use core::mem::size_of; - -use addr::PhysPage; -use alloc::vec::Vec; - -use cfg_if::cfg_if; -use consts::STACK_SIZE; -use fdt::Fdt; -use once::LazyInit; -use pagetable::PageTable; -pub use percpu; - -#[cfg_attr(target_arch = "riscv64", path = "riscv64/mod.rs")] -#[cfg_attr(target_arch = "aarch64", path = "aarch64/mod.rs")] -#[cfg_attr(target_arch = "x86_64", path = "x86_64/mod.rs")] -#[cfg_attr(target_arch = "loongarch64", path = "loongarch64/mod.rs")] -mod current_arch; - -/// Trap Frame -pub use current_arch::TrapFrame; - -pub use current_arch::*; - -pub use polyhal_macro::{arch_entry, arch_interrupt}; - -pub const PAGE_SIZE: usize = PageTable::PAGE_SIZE; -pub const USER_VADDR_END: usize = PageTable::USER_VADDR_END; - -/// Kernel Context Arg Type. -/// -/// Using this by Index and IndexMut trait bound on KContext. -#[derive(Debug)] -#[cfg(feature = "kcontext")] -pub enum KContextArgs { - /// Kernel Stack Pointer - KSP, - /// Kernel Thread Pointer - KTP, - /// Kernel Program Counter - KPC, -} - -/// Trap Frame Arg Type -/// -/// Using this by Index and IndexMut trait bound on TrapFrame -#[derive(Debug)] -pub enum TrapFrameArgs { - SEPC, - RA, - SP, - RET, - ARG0, - ARG1, - ARG2, - TLS, - SYSCALL, -} - -#[derive(Debug, Clone, Copy)] -pub enum TrapType { - Breakpoint, - UserEnvCall, - Time, - Unknown, - SupervisorExternal, - StorePageFault(usize), - LoadPageFault(usize), - InstructionPageFault(usize), - IllegalInstruction(usize), -} - -#[link_section = ".bss.stack"] -static mut BOOT_STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; +extern crate cfg_if; -pub(crate) fn clear_bss() { - extern "C" { - fn _sbss(); - fn _ebss(); - } - unsafe { - core::slice::from_raw_parts_mut( - _sbss as usize as *mut u128, - (_ebss as usize - _sbss as usize) / size_of::(), - ) - .fill(0); +mod utils; +#[macro_use] +mod common; + +cfg_if! { + if #[cfg(feature = "libos")] { + #[path = "libos/mod.rs"] + mod imp; + } else { + #[path = "bare/mod.rs"] + mod imp; } } -pub trait PageAlloc: Sync { - fn alloc(&self) -> PhysPage; - fn dealloc(&self, ppn: PhysPage); -} - -static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); - -/// Init arch with page allocator, like log crate -/// Please initialize the allocator before calling this function. -pub fn init(page_alloc: &'static dyn PageAlloc) { - PAGE_ALLOC.init_by(page_alloc); - - // Init current architecture - current_arch::arch_init(); -} - -/// Store the number of cpu, this will fill up by startup function. -pub(crate) static CPU_NUM: LazyInit = LazyInit::new(); - -/// Store the memory area, this will fill up by the arch_init() function in each architecture. -pub(crate) static MEM_AREA: LazyInit> = LazyInit::new(); - -/// Store the DTB_area, this will fill up by the arch_init() function in each architecture -static DTB_BIN: LazyInit> = LazyInit::new(); - -/// Get the memory area, this function should be called after initialization -pub fn get_mem_areas() -> Vec<(usize, usize)> { - MEM_AREA.clone() -} - -/// Get the fdt -pub fn get_fdt() -> Option> { - Fdt::new(&DTB_BIN).ok() -} - -/// Get the number of cpus -pub fn get_cpu_num() -> usize { - *CPU_NUM -} +use common::pagetable::*; +use common::consts::*; +use common::addr::*; +use common::api::*; +use common::multicore::MultiCore; +use imp::*; +use imp::current_arch::*; diff --git a/src/libos/mod.rs b/src/libos/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..db723f6 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1 @@ +pub(crate) mod once; \ No newline at end of file diff --git a/src/once/mod.rs b/src/utils/once.rs similarity index 100% rename from src/once/mod.rs rename to src/utils/once.rs From c6bce24a3924860578b8fc296816f9a1775840c1 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 13:14:32 -0700 Subject: [PATCH 03/26] tmp commit --- src/bare/arch/riscv64/entry.rs | 2 +- src/bare/mod.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bare/arch/riscv64/entry.rs b/src/bare/arch/riscv64/entry.rs index 4b47db6..bacd00e 100644 --- a/src/bare/arch/riscv64/entry.rs +++ b/src/bare/arch/riscv64/entry.rs @@ -144,7 +144,7 @@ pub fn switch_to_kernel_page_table() { } pub fn kernel_page_table() -> PageTable { - PageTable(crate::addr::PhysAddr(unsafe { + PageTable(crate::PhysAddr(unsafe { PAGE_TABLE.as_ptr() as usize & !VIRT_ADDR_START })) } diff --git a/src/bare/mod.rs b/src/bare/mod.rs index f94d2a7..e119b29 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -162,9 +162,11 @@ use crate::utils::once::LazyInit; /// Trap Frame pub use polyhal_macro::{arch_entry, arch_interrupt}; +use crate::STACK_SIZE; +use crate::PhysPage; -pub const PAGE_SIZE: usize; -pub const USER_VADDR_END: usize = PageTable::USER_VADDR_END; +pub const PAGE_SIZE: usize = crate::PageTable::PAGE_SIZE; +pub const USER_VADDR_END: usize = crate::PageTable::USER_VADDR_END; /// Kernel Context Arg Type. /// @@ -210,7 +212,7 @@ pub enum TrapType { } #[link_section = ".bss.stack"] -static mut BOOT_STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; +pub static mut BOOT_STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; pub(crate) fn clear_bss() { extern "C" { @@ -231,7 +233,7 @@ pub trait PageAlloc: Sync { fn dealloc(&self, ppn: PhysPage); } -static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); +pub static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); /// Init arch with page allocator, like log crate /// Please initialize the allocator before calling this function. From 36bf1676a118f1c310e77fbc417a1f8ba00bdf72 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 13:28:33 -0700 Subject: [PATCH 04/26] tmp commit --- src/bare/arch/riscv64/mod.rs | 2 +- src/bare/mod.rs | 9 +++------ src/common/pagetable.rs | 9 ++++++++- src/lib.rs | 2 ++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index 81d3317..8185188 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -167,4 +167,4 @@ impl MultiCore { } }); } -} +} \ No newline at end of file diff --git a/src/bare/mod.rs b/src/bare/mod.rs index e119b29..416225e 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -151,17 +151,15 @@ pub mod irq; pub mod mem; pub mod time; use core::mem::size_of; -pub use current_arch::*; -use alloc::vec::Vec; pub use mem::Barrier; use cfg_if::cfg_if; -use fdt::Fdt; use crate::utils::once::LazyInit; +use fdt::Fdt; +use alloc::vec::Vec; /// Trap Frame -pub use polyhal_macro::{arch_entry, arch_interrupt}; use crate::STACK_SIZE; use crate::PhysPage; @@ -232,7 +230,6 @@ pub trait PageAlloc: Sync { fn alloc(&self) -> PhysPage; fn dealloc(&self, ppn: PhysPage); } - pub static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); /// Init arch with page allocator, like log crate @@ -266,4 +263,4 @@ pub fn get_fdt() -> Option> { /// Get the number of cpus pub fn get_cpu_num() -> usize { *CPU_NUM -} +} \ No newline at end of file diff --git a/src/common/pagetable.rs b/src/common/pagetable.rs index bc964d1..d575f61 100644 --- a/src/common/pagetable.rs +++ b/src/common/pagetable.rs @@ -2,8 +2,15 @@ use core::ops::Deref; use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::{frame_alloc, frame_dealloc}; +use bitflags::bitflags; -bitflags::bitflags! { +macro_rules! bit { + ($x:expr) => { + 1 << $x + }; +} + +bitflags! { /// Mapping flags for page table. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct MappingFlags: u64 { diff --git a/src/lib.rs b/src/lib.rs index 8397fe0..f51666d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,3 +36,5 @@ use common::api::*; use common::multicore::MultiCore; use imp::*; use imp::current_arch::*; + +pub use imp::{get_cpu_num, get_mem_areas, get_fdt, init}; \ No newline at end of file From b6f9a7c860fa69fe2f1171365c6fce7f05b88cbc Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 13:52:37 -0700 Subject: [PATCH 05/26] refactor --- Cargo.toml | 2 +- src/bare/mod.rs | 5 +---- src/common/mod.rs | 1 + src/common/page.rs | 6 ++++++ src/lib.rs | 16 ++++++++++++++-- 5 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 src/common/page.rs diff --git a/Cargo.toml b/Cargo.toml index c505232..8fa57f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ kcontext = [] multicore = [] libos = [] -default = ["multicore"] +default = ["multicore", "kcontext"] [dependencies] log = "0.4" diff --git a/src/bare/mod.rs b/src/bare/mod.rs index 416225e..33bc5eb 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -162,6 +162,7 @@ use alloc::vec::Vec; use crate::STACK_SIZE; use crate::PhysPage; +use crate::PageAlloc; pub const PAGE_SIZE: usize = crate::PageTable::PAGE_SIZE; pub const USER_VADDR_END: usize = crate::PageTable::USER_VADDR_END; @@ -226,10 +227,6 @@ pub(crate) fn clear_bss() { } } -pub trait PageAlloc: Sync { - fn alloc(&self) -> PhysPage; - fn dealloc(&self, ppn: PhysPage); -} pub static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); /// Init arch with page allocator, like log crate diff --git a/src/common/mod.rs b/src/common/mod.rs index 4deb096..9125dae 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,6 +4,7 @@ pub mod api; pub mod consts; #[cfg(feature = "multicore")] pub mod multicore; +pub mod page; /// bit macro will generate the number through a shift value. /// diff --git a/src/common/page.rs b/src/common/page.rs new file mode 100644 index 0000000..6cbe6ab --- /dev/null +++ b/src/common/page.rs @@ -0,0 +1,6 @@ +use crate::PhysPage; + +pub trait PageAlloc: Sync { + fn alloc(&self) -> PhysPage; + fn dealloc(&self, ppn: PhysPage); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index f51666d..3a16077 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,10 +31,22 @@ cfg_if! { use common::pagetable::*; use common::consts::*; -use common::addr::*; use common::api::*; use common::multicore::MultiCore; use imp::*; use imp::current_arch::*; -pub use imp::{get_cpu_num, get_mem_areas, get_fdt, init}; \ No newline at end of file +pub use common::addr::*; +pub use common::page::PageAlloc; +pub use imp::{get_cpu_num, get_mem_areas, get_fdt, init}; +pub use imp::time::*; +pub use imp::debug::DebugConsole; +pub use imp::current_arch::{run_user_task, run_user_task_forever, disable_irq, enable_irq, enable_external_irq, switch_to_kernel_page_table, kernel_page_table}; +pub use imp::current_arch::TrapFrame; +pub use imp::current_arch::VIRT_ADDR_START; +pub use imp::{TrapFrameArgs, TrapType, PAGE_ALLOC, PAGE_SIZE}; +#[cfg(feature = "kcontext")] +pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; +pub use polyhal_macro::{arch_entry, arch_interrupt}; +pub use imp::current_arch::shutdown; +pub use common::pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize}; \ No newline at end of file From 7bff41b2147343a33298c40caf419e17d79c6fc4 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 14:40:40 -0700 Subject: [PATCH 06/26] refactor with four arch --- .cargo/config.toml | 4 +-- src/bare/arch/aarch64/boot.rs | 2 +- src/bare/arch/aarch64/gic.rs | 2 +- src/bare/arch/aarch64/mod.rs | 12 ++++---- src/bare/arch/aarch64/page_table.rs | 4 +-- src/bare/arch/aarch64/pl011.rs | 2 +- src/bare/arch/aarch64/trap.rs | 2 +- src/bare/arch/loongarch64/mod.rs | 5 ++-- src/bare/arch/loongarch64/page_table.rs | 5 +--- src/bare/arch/loongarch64/sigtrx.rs | 4 +-- src/bare/arch/loongarch64/trap.rs | 4 +-- src/bare/arch/x86_64/apic.rs | 2 +- src/bare/arch/x86_64/interrupt.rs | 13 +++++---- src/bare/arch/x86_64/mod.rs | 8 ++++-- src/bare/arch/x86_64/multiboot.rs | 8 +++--- src/bare/arch/x86_64/page_table.rs | 9 +++--- src/bare/arch/x86_64/sigtrx.rs | 2 +- src/bare/mod.rs | 5 ++-- src/common/consts.rs | 2 +- src/lib.rs | 37 +++++++++++++++---------- 20 files changed, 69 insertions(+), 63 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index bac0add..a6b4d94 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # Just used for rust-analyzer. [build] -target = "riscv64gc-unknown-none-elf" +# target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' # target = 'x86_64-unknown-none' -# target = 'loongarch64-unknown-none' +target = 'loongarch64-unknown-none' diff --git a/src/bare/arch/aarch64/boot.rs b/src/bare/arch/aarch64/boot.rs index 36c71ff..3a93dd1 100644 --- a/src/bare/arch/aarch64/boot.rs +++ b/src/bare/arch/aarch64/boot.rs @@ -1,4 +1,4 @@ -use crate::{pagetable::TLB, PTEFlags}; +use crate::{TLB, PTEFlags}; use aarch64_cpu::{asm, asm::barrier, registers::*}; // use page_table_entry::aarch64::{MemAttr, A64PTE}; diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index d6c4cd9..b3ea0f3 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -2,7 +2,7 @@ use arm_gic::gic_v2::{GicCpuInterface, GicDistributor}; use arm_gic::{translate_irq, InterruptType}; use irq_safety::MutexIrqSafe; -use crate::addr::PhysAddr; +use crate::PhysAddr; /// The maximum number of IRQs. #[allow(dead_code)] diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index ec33f2c..cdcfbd0 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -28,10 +28,10 @@ pub use page_table::*; pub use psci::system_off as shutdown; pub use trap::{disable_irq, enable_external_irq, enable_irq, run_user_task}; -use crate::multicore::MultiCore; -use crate::once::LazyInit; -use crate::pagetable::PageTable; -use crate::{clear_bss, CPU_NUM, DTB_BIN, MEM_AREA}; +use crate::MultiCore; +use crate::utils::once::LazyInit; +use crate::PageTable; +use super::{clear_bss, CPU_NUM, MEM_AREA, DTB_BIN}; static DTB_PTR: LazyInit = LazyInit::new(); @@ -56,13 +56,13 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { aarch64_cpu::asm::barrier::isb(aarch64_cpu::asm::barrier::SY); // Enter to kernel entry point(`main` function). - unsafe { crate::api::_main_for_arch(hart_id) }; + unsafe { crate::_main_for_arch(hart_id) }; shutdown(); } pub fn kernel_page_table() -> PageTable { - PageTable(crate::addr::PhysAddr(TTBR0_EL1.get_baddr() as _)) + PageTable(crate::PhysAddr(TTBR0_EL1.get_baddr() as _)) } #[inline] diff --git a/src/bare/arch/aarch64/page_table.rs b/src/bare/arch/aarch64/page_table.rs index 015ea58..7b8e299 100644 --- a/src/bare/arch/aarch64/page_table.rs +++ b/src/bare/arch/aarch64/page_table.rs @@ -1,7 +1,7 @@ use aarch64_cpu::registers::{Writeable, TTBR0_EL1}; -use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; -use crate::pagetable::{MappingFlags, PageTable, PTE, TLB}; +use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::{MappingFlags, PageTable, PTE, TLB}; impl PTE { #[inline] diff --git a/src/bare/arch/aarch64/pl011.rs b/src/bare/arch/aarch64/pl011.rs index be2c7a3..fbac0b5 100644 --- a/src/bare/arch/aarch64/pl011.rs +++ b/src/bare/arch/aarch64/pl011.rs @@ -3,7 +3,7 @@ use arm_pl011::pl011::Pl011Uart; use irq_safety::MutexIrqSafe; -use crate::{addr::PhysAddr, debug::DebugConsole}; +use crate::{PhysAddr, debug::DebugConsole}; const UART_BASE: PhysAddr = PhysAddr(0x0900_0000); diff --git a/src/bare/arch/aarch64/trap.rs b/src/bare/arch/aarch64/trap.rs index 0bf82a5..4aa5244 100644 --- a/src/bare/arch/aarch64/trap.rs +++ b/src/bare/arch/aarch64/trap.rs @@ -88,7 +88,7 @@ fn handle_exception(tf: &mut TrapFrame, kind: TrapKind, source: TrapSource) -> T ); } }; - unsafe { crate::api::_interrupt_for_arch(tf, trap_type) }; + unsafe { crate::_interrupt_for_arch(tf, trap_type) }; trap_type } diff --git a/src/bare/arch/loongarch64/mod.rs b/src/bare/arch/loongarch64/mod.rs index d79cb2d..0e8f551 100644 --- a/src/bare/arch/loongarch64/mod.rs +++ b/src/bare/arch/loongarch64/mod.rs @@ -11,7 +11,8 @@ mod timer; mod trap; mod unaligned; -use crate::{clear_bss, multicore::MultiCore, CPU_NUM, DTB_BIN, MEM_AREA}; +use crate::MultiCore; +use super::{clear_bss, CPU_NUM, DTB_BIN, MEM_AREA}; use alloc::vec::Vec; pub use consts::*; pub use context::TrapFrame; @@ -33,7 +34,7 @@ pub fn rust_tmp_main(hart_id: usize) { CPU_NUM.init_by(2); - unsafe { crate::api::_main_for_arch(hart_id) }; + unsafe { crate::_main_for_arch(hart_id) }; shutdown(); } diff --git a/src/bare/arch/loongarch64/page_table.rs b/src/bare/arch/loongarch64/page_table.rs index a555522..504d677 100644 --- a/src/bare/arch/loongarch64/page_table.rs +++ b/src/bare/arch/loongarch64/page_table.rs @@ -1,9 +1,6 @@ use loongArch64::register::pgdl; -use crate::{ - addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}, - pagetable::{MappingFlags, PageTable, PTE, TLB}, -}; +use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage, MappingFlags, PageTable, PTE, TLB}; use super::sigtrx::get_trx_mapping; diff --git a/src/bare/arch/loongarch64/sigtrx.rs b/src/bare/arch/loongarch64/sigtrx.rs index b03fa18..ee5ac72 100644 --- a/src/bare/arch/loongarch64/sigtrx.rs +++ b/src/bare/arch/loongarch64/sigtrx.rs @@ -1,5 +1,5 @@ use crate::{ - pagetable::{MappingFlags, PageTable, PTE}, + {MappingFlags, PageTable, PTE}, PAGE_SIZE, VIRT_ADDR_START, }; @@ -26,7 +26,7 @@ static mut TRX_STEP: [[PTE; PageTable::PTE_NUM_IN_PAGE]; 2] = pub fn init() { unsafe { TRX_STEP[0][0] = PTE::from_addr( - crate::addr::PhysAddr(_sigreturn as usize & !VIRT_ADDR_START), + crate::PhysAddr(_sigreturn as usize & !VIRT_ADDR_START), MappingFlags::URX.into(), ); TRX_STEP[1][0] = PTE(TRX_STEP.as_ptr() as usize & !VIRT_ADDR_START); diff --git a/src/bare/arch/loongarch64/trap.rs b/src/bare/arch/loongarch64/trap.rs index 9c6bf53..3d8c6ba 100644 --- a/src/bare/arch/loongarch64/trap.rs +++ b/src/bare/arch/loongarch64/trap.rs @@ -227,7 +227,7 @@ pub unsafe extern "C" fn trap_vector_base() { LOAD_REGS ertn ", - trapframe_size = const crate::consts::TRAPFRAME_SIZE, + trapframe_size = const crate::TRAPFRAME_SIZE, user_vec = sym user_vec, trap_handler = sym loongarch64_trap_handler, options(noreturn) @@ -361,6 +361,6 @@ fn loongarch64_trap_handler(tf: &mut TrapFrame) -> TrapType { } }; // info!("return to addr: {:#x}", tf.era); - unsafe { crate::api::_interrupt_for_arch(tf, trap_type) }; + unsafe { crate::_interrupt_for_arch(tf, trap_type) }; trap_type } diff --git a/src/bare/arch/x86_64/apic.rs b/src/bare/arch/x86_64/apic.rs index 04cb4a4..7376d38 100644 --- a/src/bare/arch/x86_64/apic.rs +++ b/src/bare/arch/x86_64/apic.rs @@ -7,7 +7,7 @@ use x2apic::lapic::{xapic_base, LocalApic, LocalApicBuilder}; use x86_64::instructions::port::Port; use self::vectors::*; -use crate::VIRT_ADDR_START; +use crate::imp::current_arch::VIRT_ADDR_START; pub(super) mod vectors { pub const APIC_TIMER_VECTOR: u8 = 0xf0; diff --git a/src/bare/arch/x86_64/interrupt.rs b/src/bare/arch/x86_64/interrupt.rs index 0f84492..caad9b9 100644 --- a/src/bare/arch/x86_64/interrupt.rs +++ b/src/bare/arch/x86_64/interrupt.rs @@ -8,10 +8,11 @@ use x86_64::VirtAddr; use x86::{controlregs::cr2, irq::*}; -use crate::consts::TRAPFRAME_SIZE; -use crate::current_arch::gdt::set_tss_kernel_sp; -use crate::SYSCALL_VECTOR; -use crate::{current_arch::gdt::GdtStruct, TrapFrame, TrapType}; +use crate::TRAPFRAME_SIZE; +use crate::imp::current_arch::gdt::set_tss_kernel_sp; +use crate::imp::current_arch::SYSCALL_VECTOR; +use crate::imp::current_arch::gdt::GdtStruct; +use crate::{imp::current_arch::TrapFrame, TrapType}; use super::apic::vectors::APIC_TIMER_VECTOR; use super::context::FxsaveArea; @@ -107,7 +108,7 @@ fn kernel_callback(context: &mut TrapFrame) { ); } }; - unsafe { crate::api::_interrupt_for_arch(context, trap_type) }; + unsafe { crate::_interrupt_for_arch(context, trap_type) }; unsafe { super::apic::local_apic().end_of_interrupt() }; } @@ -389,7 +390,7 @@ pub fn run_user_task(context: &mut TrapFrame) -> Option<()> { match context.vector { SYSCALL_VECTOR => { - unsafe { crate::api::_interrupt_for_arch(context, TrapType::UserEnvCall) }; + unsafe { crate::_interrupt_for_arch(context, TrapType::UserEnvCall) }; Some(()) } _ => { diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index 12e3471..b4ccbad 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -32,10 +32,12 @@ use x86_64::{ }, }; -use crate::{ - current_arch::multiboot::use_multiboot, multicore::MultiCore, once::LazyInit, CPU_NUM, +use crate::imp::{ + current_arch::multiboot::use_multiboot, CPU_NUM, DTB_BIN, MEM_AREA, }; +use crate::MultiCore; +use crate::utils::once::LazyInit; #[percpu::def_percpu] static CPU_ID: usize = 1; @@ -93,7 +95,7 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) { MBOOT_PTR.init_by(mboot_ptr); - unsafe { crate::api::_main_for_arch(0) }; + unsafe { crate::_main_for_arch(0) }; shutdown() } diff --git a/src/bare/arch/x86_64/multiboot.rs b/src/bare/arch/x86_64/multiboot.rs index ccc3c37..5fcc155 100644 --- a/src/bare/arch/x86_64/multiboot.rs +++ b/src/bare/arch/x86_64/multiboot.rs @@ -1,5 +1,5 @@ -use crate::current_arch::rust_tmp_main; -use crate::pagetable::PageTable; +use crate::imp::current_arch::rust_tmp_main; +use crate::PageTable; use crate::{BOOT_STACK, STACK_SIZE}; use core::arch::global_asm; use core::{mem, slice}; @@ -7,7 +7,7 @@ use multiboot::information::{MemoryManagement, Multiboot, PAddr}; use x86_64::registers::control::{Cr0Flags, Cr4Flags}; use x86_64::registers::model_specific::EferFlags; -use crate::VIRT_ADDR_START; +use crate::imp::current_arch::VIRT_ADDR_START; /// Flags set in the 'flags' member of the multiboot header. /// @@ -78,7 +78,7 @@ pub fn kernel_page_table() -> PageTable { extern "C" { fn _kernel_page_table(); } - PageTable(crate::addr::PhysAddr( + PageTable(crate::PhysAddr( _kernel_page_table as usize - VIRT_ADDR_START, )) } diff --git a/src/bare/arch/x86_64/page_table.rs b/src/bare/arch/x86_64/page_table.rs index 340ab48..47e6797 100644 --- a/src/bare/arch/x86_64/page_table.rs +++ b/src/bare/arch/x86_64/page_table.rs @@ -3,11 +3,10 @@ use bitflags::bitflags; use x86::tlb; use x86_64::registers::control::Cr3; -use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; -use crate::{ - pagetable::{MappingFlags, PageTable, PTE, TLB}, - VIRT_ADDR_START, -}; +use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::imp::current_arch::VIRT_ADDR_START; +use crate::{MappingFlags, PageTable, PTE, TLB}; + bitflags! { pub struct PTEFlags: u64 { diff --git a/src/bare/arch/x86_64/sigtrx.rs b/src/bare/arch/x86_64/sigtrx.rs index 2a432b3..77d82fd 100644 --- a/src/bare/arch/x86_64/sigtrx.rs +++ b/src/bare/arch/x86_64/sigtrx.rs @@ -1,6 +1,6 @@ use x86::bits64::paging::{PDEntry, PDFlags, PTEntry, PTFlags, PAGE_SIZE_ENTRIES, PD, PT}; -use crate::VIRT_ADDR_START; +use crate::imp::current_arch::VIRT_ADDR_START; /// 汇编入口函数 /// diff --git a/src/bare/mod.rs b/src/bare/mod.rs index 33bc5eb..ea63e0d 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -129,14 +129,13 @@ cfg_if! { if #[cfg(target_arch = "x86_64")] { #[path = "arch/x86_64/mod.rs"] - mod current_arch; + pub mod current_arch; } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { #[path = "arch/riscv64/mod.rs"] pub mod current_arch; } else if #[cfg(target_arch = "aarch64")] { #[path = "arch/aarch64/mod.rs"] pub mod current_arch; - pub use self::arch::timer_interrupt_vector; } else if #[cfg(target_arch = "loongarch64")] { #[path = "arch/loongarch64/mod.rs"] pub mod current_arch; @@ -227,7 +226,7 @@ pub(crate) fn clear_bss() { } } -pub static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); +pub(crate) static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); /// Init arch with page allocator, like log crate /// Please initialize the allocator before calling this function. diff --git a/src/common/consts.rs b/src/common/consts.rs index 1cc003c..6ca9a59 100644 --- a/src/common/consts.rs +++ b/src/common/consts.rs @@ -1,6 +1,6 @@ use core::mem::size_of; -use crate::TrapFrame; +use crate::imp::current_arch::TrapFrame; /// Boot Stack Size. /// TODO: reduce the boot stack size. Map stack in boot step. diff --git a/src/lib.rs b/src/lib.rs index 3a16077..349e9c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,20 +33,27 @@ use common::pagetable::*; use common::consts::*; use common::api::*; use common::multicore::MultiCore; -use imp::*; -use imp::current_arch::*; - -pub use common::addr::*; -pub use common::page::PageAlloc; -pub use imp::{get_cpu_num, get_mem_areas, get_fdt, init}; +pub use imp::*; +pub use imp::current_arch::*; +pub use imp::debug::*; pub use imp::time::*; -pub use imp::debug::DebugConsole; -pub use imp::current_arch::{run_user_task, run_user_task_forever, disable_irq, enable_irq, enable_external_irq, switch_to_kernel_page_table, kernel_page_table}; -pub use imp::current_arch::TrapFrame; -pub use imp::current_arch::VIRT_ADDR_START; -pub use imp::{TrapFrameArgs, TrapType, PAGE_ALLOC, PAGE_SIZE}; -#[cfg(feature = "kcontext")] -pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; + +pub use common::{ + addr::*, + page::PageAlloc, + pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} +}; +// pub use imp::{ +// get_mem_areas, init, +// TrapFrameArgs, TrapType, PAGE_SIZE, +// time::*, +// debug::DebugConsole, +// current_arch::{ +// run_user_task, shutdown, kernel_page_table, +// TrapFrame, VIRT_ADDR_START, +// }, +// }; pub use polyhal_macro::{arch_entry, arch_interrupt}; -pub use imp::current_arch::shutdown; -pub use common::pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize}; \ No newline at end of file + +#[cfg(feature = "kcontext")] +pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; \ No newline at end of file From cbac969fe6059c724bb332694cc7c3c2c4fd30da Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 16:29:16 -0700 Subject: [PATCH 07/26] refactor after add libos feature --- .cargo/config.toml | 4 +- Cargo.toml | 2 +- src/{common => bare}/addr.rs | 0 src/{common => bare}/api.rs | 0 src/bare/arch/aarch64/page_table.rs | 1 + src/bare/arch/loongarch64/page_table.rs | 1 + src/bare/arch/riscv64/page_table/sv39.rs | 1 + src/bare/arch/x86_64/page_table.rs | 1 + src/{common => bare}/consts.rs | 0 src/bare/mod.rs | 8 +++- src/{common => bare}/multicore.rs | 0 src/{common => bare}/page.rs | 0 src/{common => bare}/pagetable.rs | 7 +-- src/lib.rs | 60 ++++++++++++------------ src/{common/mod.rs => utils/macros.rs} | 9 +--- src/utils/mod.rs | 3 +- 16 files changed, 47 insertions(+), 50 deletions(-) rename src/{common => bare}/addr.rs (100%) rename src/{common => bare}/api.rs (100%) rename src/{common => bare}/consts.rs (100%) rename src/{common => bare}/multicore.rs (100%) rename src/{common => bare}/page.rs (100%) rename src/{common => bare}/pagetable.rs (99%) rename src/{common/mod.rs => utils/macros.rs} (63%) diff --git a/.cargo/config.toml b/.cargo/config.toml index a6b4d94..21e59ec 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,5 +2,5 @@ [build] # target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' -# target = 'x86_64-unknown-none' -target = 'loongarch64-unknown-none' +target = 'x86_64-unknown-none' +# target = 'loongarch64-unknown-none' diff --git a/Cargo.toml b/Cargo.toml index 8fa57f9..c505232 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ kcontext = [] multicore = [] libos = [] -default = ["multicore", "kcontext"] +default = ["multicore"] [dependencies] log = "0.4" diff --git a/src/common/addr.rs b/src/bare/addr.rs similarity index 100% rename from src/common/addr.rs rename to src/bare/addr.rs diff --git a/src/common/api.rs b/src/bare/api.rs similarity index 100% rename from src/common/api.rs rename to src/bare/api.rs diff --git a/src/bare/arch/aarch64/page_table.rs b/src/bare/arch/aarch64/page_table.rs index 7b8e299..31e5c12 100644 --- a/src/bare/arch/aarch64/page_table.rs +++ b/src/bare/arch/aarch64/page_table.rs @@ -2,6 +2,7 @@ use aarch64_cpu::registers::{Writeable, TTBR0_EL1}; use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::{MappingFlags, PageTable, PTE, TLB}; +use crate::bit; impl PTE { #[inline] diff --git a/src/bare/arch/loongarch64/page_table.rs b/src/bare/arch/loongarch64/page_table.rs index 504d677..364e53f 100644 --- a/src/bare/arch/loongarch64/page_table.rs +++ b/src/bare/arch/loongarch64/page_table.rs @@ -3,6 +3,7 @@ use loongArch64::register::pgdl; use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage, MappingFlags, PageTable, PTE, TLB}; use super::sigtrx::get_trx_mapping; +use crate::bit; impl PTE { #[inline] diff --git a/src/bare/arch/riscv64/page_table/sv39.rs b/src/bare/arch/riscv64/page_table/sv39.rs index 73f27fd..6086917 100644 --- a/src/bare/arch/riscv64/page_table/sv39.rs +++ b/src/bare/arch/riscv64/page_table/sv39.rs @@ -5,6 +5,7 @@ use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::kernel_page_table; use crate::MappingFlags; use crate::{PageTable, PTE, TLB}; +use crate::bit; use super::sigtrx::get_trx_mapping; diff --git a/src/bare/arch/x86_64/page_table.rs b/src/bare/arch/x86_64/page_table.rs index 47e6797..aedcc51 100644 --- a/src/bare/arch/x86_64/page_table.rs +++ b/src/bare/arch/x86_64/page_table.rs @@ -6,6 +6,7 @@ use x86_64::registers::control::Cr3; use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::imp::current_arch::VIRT_ADDR_START; use crate::{MappingFlags, PageTable, PTE, TLB}; +use crate::bit; bitflags! { diff --git a/src/common/consts.rs b/src/bare/consts.rs similarity index 100% rename from src/common/consts.rs rename to src/bare/consts.rs diff --git a/src/bare/mod.rs b/src/bare/mod.rs index ea63e0d..c932753 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -149,9 +149,15 @@ pub mod instruction; pub mod irq; pub mod mem; pub mod time; +pub mod pagetable; +pub mod addr; +pub mod api; +pub mod consts; +pub mod multicore; +pub mod page; + use core::mem::size_of; pub use mem::Barrier; - use cfg_if::cfg_if; use crate::utils::once::LazyInit; use fdt::Fdt; diff --git a/src/common/multicore.rs b/src/bare/multicore.rs similarity index 100% rename from src/common/multicore.rs rename to src/bare/multicore.rs diff --git a/src/common/page.rs b/src/bare/page.rs similarity index 100% rename from src/common/page.rs rename to src/bare/page.rs diff --git a/src/common/pagetable.rs b/src/bare/pagetable.rs similarity index 99% rename from src/common/pagetable.rs rename to src/bare/pagetable.rs index d575f61..2f1489e 100644 --- a/src/common/pagetable.rs +++ b/src/bare/pagetable.rs @@ -3,12 +3,7 @@ use core::ops::Deref; use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::{frame_alloc, frame_dealloc}; use bitflags::bitflags; - -macro_rules! bit { - ($x:expr) => { - 1 << $x - }; -} +use crate::bit; bitflags! { /// Mapping flags for page table. diff --git a/src/lib.rs b/src/lib.rs index 349e9c8..5f6ec13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,9 +15,8 @@ extern crate log; #[macro_use] extern crate cfg_if; -mod utils; #[macro_use] -mod common; +mod utils; cfg_if! { if #[cfg(feature = "libos")] { @@ -26,34 +25,33 @@ cfg_if! { } else { #[path = "bare/mod.rs"] mod imp; + use imp::api::*; + use imp::pagetable::*; + use imp::consts::*; + use imp::multicore::MultiCore; + use imp::*; + use imp::current_arch::*; + use imp::debug::*; + use imp::time::*; + + pub use imp::{ + addr::*, + page::PageAlloc, + pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} + }; + pub use imp::{ + get_mem_areas, init, + TrapFrameArgs, TrapType, PAGE_SIZE, + time::*, + debug::DebugConsole, + current_arch::{ + run_user_task, shutdown, kernel_page_table, + TrapFrame, VIRT_ADDR_START, + }, + }; + pub use polyhal_macro::{arch_entry, arch_interrupt}; + + #[cfg(feature = "kcontext")] + pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; } } - -use common::pagetable::*; -use common::consts::*; -use common::api::*; -use common::multicore::MultiCore; -pub use imp::*; -pub use imp::current_arch::*; -pub use imp::debug::*; -pub use imp::time::*; - -pub use common::{ - addr::*, - page::PageAlloc, - pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} -}; -// pub use imp::{ -// get_mem_areas, init, -// TrapFrameArgs, TrapType, PAGE_SIZE, -// time::*, -// debug::DebugConsole, -// current_arch::{ -// run_user_task, shutdown, kernel_page_table, -// TrapFrame, VIRT_ADDR_START, -// }, -// }; -pub use polyhal_macro::{arch_entry, arch_interrupt}; - -#[cfg(feature = "kcontext")] -pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; \ No newline at end of file diff --git a/src/common/mod.rs b/src/utils/macros.rs similarity index 63% rename from src/common/mod.rs rename to src/utils/macros.rs index 9125dae..fcd0b00 100644 --- a/src/common/mod.rs +++ b/src/utils/macros.rs @@ -1,16 +1,9 @@ -pub mod addr; -pub(crate) mod pagetable; -pub mod api; -pub mod consts; -#[cfg(feature = "multicore")] -pub mod multicore; -pub mod page; - /// bit macro will generate the number through a shift value. /// /// Here is an example. /// You can use bit!(0) instead of 1 << 0. /// bit!(39) instead of 1 << 39. +#[macro_export] macro_rules! bit { ($x:expr) => { 1 << $x diff --git a/src/utils/mod.rs b/src/utils/mod.rs index db723f6..d7b8210 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,2 @@ -pub(crate) mod once; \ No newline at end of file +pub(crate) mod once; +pub(crate) mod macros; \ No newline at end of file From d42e577058c9497d4f87512d8cd6d5f86c53c367 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 11 May 2024 21:19:16 -0700 Subject: [PATCH 08/26] libos tmp --- .cargo/config.toml | 2 +- Cargo.lock | 340 ++++++++++++++++++++++++++++++++++-- Cargo.toml | 12 +- src/bare/arch/x86_64/mod.rs | 2 +- src/bare/mod.rs | 3 +- src/{utils => bare}/once.rs | 0 src/lib.rs | 12 +- src/libos/addr.rs | 58 ++++++ src/libos/api.rs | 3 + src/libos/context.rs | 3 + src/libos/debug.rs | 30 ++++ src/libos/mem.rs | 62 +++++++ src/libos/mock_mem.rs | 121 +++++++++++++ src/libos/mod.rs | 23 +++ src/libos/page.rs | 6 + src/libos/vm.rs | 284 ++++++++++++++++++++++++++++++ src/utils/init_once.rs | 54 ++++++ src/utils/mod.rs | 4 +- 18 files changed, 1001 insertions(+), 18 deletions(-) rename src/{utils => bare}/once.rs (100%) create mode 100644 src/libos/addr.rs create mode 100644 src/libos/api.rs create mode 100644 src/libos/context.rs create mode 100644 src/libos/debug.rs create mode 100644 src/libos/mem.rs create mode 100644 src/libos/mock_mem.rs create mode 100644 src/libos/page.rs create mode 100644 src/libos/vm.rs create mode 100644 src/utils/init_once.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 21e59ec..b615045 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,5 +2,5 @@ [build] # target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' -target = 'x86_64-unknown-none' +# target = 'x86_64-unknown-none' # target = 'loongarch64-unknown-none' diff --git a/Cargo.lock b/Cargo.lock index f0aae7d..c4f87ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,16 @@ version = "9.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287" dependencies = [ - "tock-registers", + "tock-registers 0.8.1", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", ] [[package]] @@ -16,7 +25,7 @@ name = "arm_gic" version = "0.1.0" source = "git+https://github.com/Byte-OS/arm_gic#7a0693ebe4113cfeb2f5ee93920e6e7ea3afe99a" dependencies = [ - "tock-registers", + "tock-registers 0.8.1", ] [[package]] @@ -24,7 +33,7 @@ name = "arm_pl011" version = "0.1.0" source = "git+https://github.com/Byte-OS/arm_pl011.git#8a66e24c7e6ac2a01841cd29c5e1690323aa1d8d" dependencies = [ - "tock-registers", + "tock-registers 0.8.1", ] [[package]] @@ -33,6 +42,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + [[package]] name = "bit" version = "0.1.1" @@ -57,24 +72,73 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "bitmap-allocator" +version = "0.1.0" +source = "git+https://github.com/rcore-os/bitmap-allocator.git?rev=88e871a5#88e871a54f28a3d6795478f237466b3332e2fb1d" +dependencies = [ + "bit_field", +] + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cortex-a" +version = "7.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdecfbb28672ad3664e71ae05a398a52df430d86d660691501b28968cc4467e6" +dependencies = [ + "tock-registers 0.7.0", +] + [[package]] name = "critical-section" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + [[package]] name = "embedded-hal" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "fdt" version = "0.1.5" @@ -86,7 +150,42 @@ name = "irq_safety" version = "0.1.1" source = "git+https://github.com/theseus-os/irq_safety.git#11bfab9f410a898df1e42ad6213488612e20c926" dependencies = [ - "spin", + "spin 0.9.8", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock" +version = "0.1.0" +source = "git+https://github.com/DeathWish5/kernel-sync?rev=8486b8#8486b817a71ec5141836e00c817fefb94c9cfbb7" +dependencies = [ + "cfg-if", + "cortex-a", + "raw-cpuid 10.7.0", + "riscv 0.7.0", + "spin 0.9.8", + "tock-registers 0.7.0", + "x86_64", ] [[package]] @@ -115,6 +214,21 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "multiboot" version = "0.8.0" @@ -124,6 +238,40 @@ dependencies = [ "paste", ] +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "numeric-enum-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e4bdb6b46b592948e700ea1ef24a4296491f6a0ee722b258040abd15a3714" + [[package]] name = "paste" version = "1.0.14" @@ -137,7 +285,7 @@ source = "git+https://github.com/Byte-OS/percpu.git#a71e60e376ac28cdf1a46312e270 dependencies = [ "cfg-if", "percpu_macros", - "spin", + "spin 0.9.8", "x86", ] @@ -158,20 +306,26 @@ dependencies = [ "aarch64-cpu", "arm_gic", "arm_pl011", - "bitflags 2.5.0", + "bitflags 1.3.2", + "bitmap-allocator", "cfg-if", "fdt", "irq_safety", + "lazy_static", + "lock", "log", "loongArch64", "multiboot", + "nix", + "numeric-enum-macro", "percpu", "polyhal-macro", "raw-cpuid 11.0.1", - "riscv", + "riscv 0.11.1", "sbi-rt", - "spin", - "tock-registers", + "spin 0.9.8", + "tempfile", + "tock-registers 0.8.1", "x2apic", "x86", "x86_64", @@ -222,6 +376,46 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "riscv" +version = "0.7.0" +source = "git+https://github.com/rust-embedded/riscv?rev=cd31989ba1#cd31989ba11d5d64e1addd8aab98bfb00dd927d5" +dependencies = [ + "bare-metal", + "bit_field", + "embedded-hal 0.2.7", + "riscv-target", +] + [[package]] name = "riscv" version = "0.11.1" @@ -229,7 +423,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" dependencies = [ "critical-section", - "embedded-hal", + "embedded-hal 1.0.0", +] + +[[package]] +name = "riscv-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] @@ -262,6 +479,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -288,6 +511,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "tock-registers" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee8fba06c1f4d0b396ef61a54530bb6b28f0dc61c38bc8bc5a5a48161e6282e" + [[package]] name = "tock-registers" version = "0.8.1" @@ -300,12 +541,91 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "volatile" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "x2apic" version = "0.4.3" diff --git a/Cargo.toml b/Cargo.toml index c505232..4e7cdb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,15 +14,23 @@ kcontext = [] multicore = [] libos = [] -default = ["multicore"] +default = ["multicore", "libos"] [dependencies] log = "0.4" +nix = { version = "0.23"} +tempfile = { version = "3"} fdt = "0.1.5" -bitflags = "2.0.2" +bitflags = "1.3" cfg-if = "1.0.0" percpu = { git = "https://github.com/Byte-OS/percpu.git" } polyhal-macro = { path = "polyhal-macro" } +lazy_static = { version = "1.4.0", features = ["spin_no_std"] } +numeric-enum-macro = "0.2" +bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator.git", rev = "88e871a5"} +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "8486b8" } + + [target.'cfg(target_arch = "riscv64")'.dependencies] riscv = "0.11.0" diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index b4ccbad..a57fe15 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -37,7 +37,7 @@ use crate::imp::{ DTB_BIN, MEM_AREA, }; use crate::MultiCore; -use crate::utils::once::LazyInit; +use super::once::LazyInit; #[percpu::def_percpu] static CPU_ID: usize = 1; diff --git a/src/bare/mod.rs b/src/bare/mod.rs index c932753..14efc37 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -150,6 +150,7 @@ pub mod irq; pub mod mem; pub mod time; pub mod pagetable; +pub mod once; pub mod addr; pub mod api; pub mod consts; @@ -159,7 +160,7 @@ pub mod page; use core::mem::size_of; pub use mem::Barrier; use cfg_if::cfg_if; -use crate::utils::once::LazyInit; +use once::LazyInit; use fdt::Fdt; use alloc::vec::Vec; diff --git a/src/utils/once.rs b/src/bare/once.rs similarity index 100% rename from src/utils/once.rs rename to src/bare/once.rs diff --git a/src/lib.rs b/src/lib.rs index 5f6ec13..888ff22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![no_std] +#![cfg_attr(not(feature = "libos"), no_std)] #![no_main] #![feature(naked_functions)] #![feature(asm_const)] @@ -14,14 +14,24 @@ extern crate alloc; extern crate log; #[macro_use] extern crate cfg_if; +#[macro_use] +extern crate lazy_static; #[macro_use] mod utils; + cfg_if! { if #[cfg(feature = "libos")] { #[path = "libos/mod.rs"] mod imp; + + pub use polyhal_macro::{arch_entry, arch_interrupt}; + pub use imp::context::*; + pub use imp::debug::DebugConsole; + pub use imp::page::PageAlloc; + pub use imp::addr::*; + pub use imp::init; } else { #[path = "bare/mod.rs"] mod imp; diff --git a/src/libos/addr.rs b/src/libos/addr.rs new file mode 100644 index 0000000..69ce3a5 --- /dev/null +++ b/src/libos/addr.rs @@ -0,0 +1,58 @@ +use bitflags::bitflags; +use numeric_enum_macro::numeric_enum; + +/// Physical address. +pub type PhysAddr = usize; + +/// Virtual address. +pub type VirtAddr = usize; + +/// Device address. +pub type DevVAddr = usize; + +pub const PAGE_SIZE: usize = 0x1000; + + +pub const fn align_down(addr: usize) -> usize { + addr & !(PAGE_SIZE - 1) +} + +pub const fn align_up(addr: usize) -> usize { + (addr + PAGE_SIZE - 1) & !(PAGE_SIZE - 1) +} + +pub const fn is_aligned(addr: usize) -> bool { + page_offset(addr) == 0 +} + +pub const fn page_count(size: usize) -> usize { + align_up(size) / PAGE_SIZE +} + +pub const fn page_offset(addr: usize) -> usize { + addr & (PAGE_SIZE - 1) +} + +/// The error type which is returned from HAL functions. +/// TODO: more error types. +#[derive(Debug)] +pub struct HalError; + +/// The result type returned by HAL functions. +pub type HalResult = core::result::Result; + +bitflags! { + /// Generic memory flags. + pub struct MMUFlags: usize { + #[allow(clippy::identity_op)] + const CACHE_1 = 1 << 0; + const CACHE_2 = 1 << 1; + const READ = 1 << 2; + const WRITE = 1 << 3; + const EXECUTE = 1 << 4; + const USER = 1 << 5; + const HUGE_PAGE = 1 << 6; + const DEVICE = 1 << 7; + const RXW = Self::READ.bits | Self::WRITE.bits | Self::EXECUTE.bits; + } +} \ No newline at end of file diff --git a/src/libos/api.rs b/src/libos/api.rs new file mode 100644 index 0000000..5ba118d --- /dev/null +++ b/src/libos/api.rs @@ -0,0 +1,3 @@ +extern "Rust" { + pub(crate) fn _main_for_arch(hartid: usize); +} \ No newline at end of file diff --git a/src/libos/context.rs b/src/libos/context.rs new file mode 100644 index 0000000..a0628aa --- /dev/null +++ b/src/libos/context.rs @@ -0,0 +1,3 @@ +pub struct TrapFrame {} + +pub enum TrapType {} \ No newline at end of file diff --git a/src/libos/debug.rs b/src/libos/debug.rs new file mode 100644 index 0000000..9bfe79c --- /dev/null +++ b/src/libos/debug.rs @@ -0,0 +1,30 @@ +use core::fmt::Write; + +/// This is a console for debugging, +/// If you want to use this logging +/// You need to use like this: +/// +/// #### Put a char to output device(always uart) +/// ```rust +/// DebugConsole::putchar(b'3'); +/// ``` +/// +/// ### Get a char from input device(always uart) +/// ```rust +/// DebugConsole::getchar(); +/// ``` +pub struct DebugConsole; + +// Write string through DebugConsole +impl Write for DebugConsole { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + std::print!("{}", s); + Ok(()) + } +} + +impl DebugConsole { + pub fn putchar(c: u8) { + print!("{}", c as char); + } +} diff --git a/src/libos/mem.rs b/src/libos/mem.rs new file mode 100644 index 0000000..37fd7cf --- /dev/null +++ b/src/libos/mem.rs @@ -0,0 +1,62 @@ +//! Physical memory operations. + +use alloc::vec::Vec; +use core::ops::Range; + +use bitmap_allocator::BitAlloc; +use lock::Mutex; + +use super::mock_mem::MockMemory; +use crate::{PhysAddr, VirtAddr, PAGE_SIZE}; + +type FrameAlloc = bitmap_allocator::BitAlloc1M; + +/// Map physical memory from here. +pub(super) const PMEM_MAP_VADDR: VirtAddr = 0x8_0000_0000; +/// Physical memory size = 1GiB +pub(super) const PMEM_SIZE: usize = 0x4000_0000; + +lazy_static! { + pub(super) static ref FRAME_ALLOCATOR: Mutex = { + let mut allocator = FrameAlloc::DEFAULT; + allocator.insert(1..PMEM_SIZE / PAGE_SIZE); + Mutex::new(allocator) + }; + pub(super) static ref MOCK_PHYS_MEM: MockMemory = MockMemory::new(PMEM_SIZE); +} + +pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr { + MOCK_PHYS_MEM.phys_to_virt(paddr) +} + +pub fn free_pmem_regions() -> Vec> { + vec![PAGE_SIZE..PMEM_SIZE] +} + +pub fn pmem_read(paddr: PhysAddr, buf: &mut [u8]) { + trace!("pmem read: paddr={:#x}, len={:#x}", paddr, buf.len()); + assert!(paddr + buf.len() <= PMEM_SIZE); + let src = MOCK_PHYS_MEM.as_ptr(paddr); + unsafe { buf.as_mut_ptr().copy_from_nonoverlapping(src, buf.len()) }; +} + +fn pmem_write(paddr: PhysAddr, buf: &[u8]) { + trace!("pmem write: paddr={:#x}, len={:#x}", paddr, buf.len()); + assert!(paddr + buf.len() <= PMEM_SIZE); + let dst = MOCK_PHYS_MEM.as_mut_ptr::(paddr); + unsafe { dst.copy_from_nonoverlapping(buf.as_ptr(), buf.len()) }; +} + +fn pmem_zero(paddr: PhysAddr, len: usize) { + trace!("pmem_zero: addr={:#x}, len={:#x}", paddr, len); + assert!(paddr + len <= PMEM_SIZE); + unsafe { core::ptr::write_bytes(MOCK_PHYS_MEM.as_mut_ptr::(paddr), 0, len) }; +} + +pub fn pmem_copy(dst: PhysAddr, src: PhysAddr, len: usize) { + trace!("pmem_copy: {:#x} <- {:#x}, len={:#x}", dst, src, len); + assert!(src + len <= PMEM_SIZE && dst + len <= PMEM_SIZE); + let dst = MOCK_PHYS_MEM.as_mut_ptr::(dst); + let src = MOCK_PHYS_MEM.as_ptr::(src); + unsafe { dst.copy_from_nonoverlapping(src, len) }; +} \ No newline at end of file diff --git a/src/libos/mock_mem.rs b/src/libos/mock_mem.rs new file mode 100644 index 0000000..468abf6 --- /dev/null +++ b/src/libos/mock_mem.rs @@ -0,0 +1,121 @@ +use std::os::unix::io::RawFd; + +use nix::fcntl::{self, OFlag}; +use nix::sys::mman::{self, MapFlags, ProtFlags}; +use nix::{sys::stat::Mode, unistd}; + +use super::mem::PMEM_MAP_VADDR; +use crate::{MMUFlags, PhysAddr, VirtAddr}; + +pub struct MockMemory { + size: usize, + fd: RawFd, +} + +impl MockMemory { + pub fn new(size: usize) -> Self { + let dir = tempfile::tempdir().expect("failed to create pmem directory"); + let path = dir.path().join("rcore-libos-pmem"); + + let fd = fcntl::open( + &path, + OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_RDWR, + Mode::S_IRWXU, + ) + .expect("faild to open"); + unistd::ftruncate(fd, size as _).expect("failed to set size of shared memory!"); + + let mem = Self { size, fd }; + mem.mmap(PMEM_MAP_VADDR, size, 0, MMUFlags::READ | MMUFlags::WRITE); + mem + } + + /// Mmap `paddr` to `vaddr` in frame file. + pub fn mmap(&self, vaddr: VirtAddr, len: usize, paddr: PhysAddr, prot: MMUFlags) { + assert!(paddr < self.size); + assert!(paddr + len <= self.size); + + // workaround on macOS to write text section. + #[cfg(target_os = "macos")] + let prot = if prot.contains(MMUFlags::EXECUTE) { + prot | MMUFlags::WRITE + } else { + prot + }; + + let prot_noexec = ProtFlags::from(prot) - ProtFlags::PROT_EXEC; + let flags = MapFlags::MAP_SHARED | MapFlags::MAP_FIXED; + let fd = self.fd; + let offset = paddr as _; + trace!( + "mmap file: fd={}, offset={:#x}, len={:#x}, vaddr={:#x}, prot={:?}", + fd, + offset, + len, + vaddr, + prot, + ); + + unsafe { mman::mmap(vaddr as _, len, prot_noexec, flags, fd, offset) }.unwrap_or_else( + |err| { + panic!( + "failed to mmap: fd={}, offset={:#x}, len={:#x}, vaddr={:#x}, prot={:?}: {:?}", + fd, offset, len, vaddr, prot, err + ) + }, + ); + if prot.contains(MMUFlags::EXECUTE) { + self.mprotect(vaddr, len, prot); + } + } + + pub fn munmap(&self, vaddr: VirtAddr, len: usize) { + unsafe { mman::munmap(vaddr as _, len) } + .unwrap_or_else(|err| panic!("failed to munmap: vaddr={:#x}: {:?}", vaddr, err)); + } + + pub fn mprotect(&self, vaddr: VirtAddr, len: usize, prot: MMUFlags) { + unsafe { mman::mprotect(vaddr as _, len, prot.into()) }.unwrap_or_else(|err| { + panic!( + "failed to mprotect: vaddr={:#x}, prot={:?}: {:?}", + vaddr, prot, err + ) + }); + } + + pub fn phys_to_virt(&self, paddr: PhysAddr) -> VirtAddr { + assert!(paddr < self.size); + PMEM_MAP_VADDR + paddr + } + + pub fn as_ptr(&self, paddr: PhysAddr) -> *const T { + self.phys_to_virt(paddr) as _ + } + + pub fn as_mut_ptr(&self, paddr: PhysAddr) -> *mut T { + self.phys_to_virt(paddr) as _ + } +} + +impl Drop for MockMemory { + fn drop(&mut self) { + trace!("Drop MockMemory: fd={:?}", self.fd); + unistd::close(self.fd).expect("failed to close shared memory file!"); + } +} + +impl From for ProtFlags { + fn from(f: MMUFlags) -> Self { + let mut flags = Self::empty(); + if f.contains(MMUFlags::READ) { + flags |= ProtFlags::PROT_READ; + } + if f.contains(MMUFlags::WRITE) { + flags |= ProtFlags::PROT_WRITE; + } + if f.contains(MMUFlags::EXECUTE) { + flags |= ProtFlags::PROT_EXEC; + } + flags + } +} diff --git a/src/libos/mod.rs b/src/libos/mod.rs index e69de29..bc4a54b 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -0,0 +1,23 @@ +pub mod api; +pub mod context; +pub mod debug; +pub mod page; +pub mod mem; +pub mod vm; +pub mod mock_mem; +pub mod addr; +use crate::utils::init_once::InitOnce; +use page::PageAlloc; + +#[no_mangle] +fn main() { + unsafe { api::_main_for_arch(0) }; +} + +pub(crate) static PAGE_ALLOC: InitOnce<&dyn PageAlloc> = InitOnce::new(); + +/// Init arch with page allocator, like log crate +/// Please initialize the allocator before calling this function. +pub fn init(page_alloc: &'static dyn PageAlloc) { + PAGE_ALLOC.init_once_by(page_alloc); +} \ No newline at end of file diff --git a/src/libos/page.rs b/src/libos/page.rs new file mode 100644 index 0000000..010e10a --- /dev/null +++ b/src/libos/page.rs @@ -0,0 +1,6 @@ +use crate::PhysAddr; + +pub trait PageAlloc: Sync { + fn alloc(&self) -> PhysAddr; + fn dealloc(&self, ppn: PhysAddr); +} \ No newline at end of file diff --git a/src/libos/vm.rs b/src/libos/vm.rs new file mode 100644 index 0000000..df44508 --- /dev/null +++ b/src/libos/vm.rs @@ -0,0 +1,284 @@ +//! Virtual memory operations. + +use super::mem::{MOCK_PHYS_MEM, PMEM_MAP_VADDR, PMEM_SIZE}; +use crate::{is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE}; + + +/// Errors may occur during address translation. +#[derive(Debug)] +pub enum PagingError { + NoMemory, + NotMapped, + AlreadyMapped, +} + +/// Address translation result. +pub type PagingResult = Result; + +/// The [`PagingError::NotMapped`] can be ignored. +pub trait IgnoreNotMappedErr { + /// If self is `Err(PagingError::NotMapped`, ignores the error and returns + /// `Ok(())`, otherwise remain unchanged. + fn ignore(self) -> PagingResult; +} + +impl IgnoreNotMappedErr for PagingResult { + fn ignore(self) -> PagingResult { + match self { + Ok(_) | Err(PagingError::NotMapped) => Ok(()), + Err(e) => Err(e), + } + } +} + +/// Possible page size (4K, 2M, 1G). +#[repr(usize)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum PageSize { + Size4K = 0x1000, + Size2M = 0x20_0000, + Size1G = 0x4000_0000, +} + +/// A 4K, 2M or 1G size page. +#[derive(Debug, Copy, Clone)] +pub struct Page { + pub vaddr: VirtAddr, + pub size: PageSize, +} + +impl PageSize { + pub const fn is_aligned(self, addr: usize) -> bool { + self.page_offset(addr) == 0 + } + + pub const fn align_down(self, addr: usize) -> usize { + addr & !(self as usize - 1) + } + + pub const fn page_offset(self, addr: usize) -> usize { + addr & (self as usize - 1) + } + + pub const fn is_huge(self) -> bool { + matches!(self, Self::Size1G | Self::Size2M) + } +} + +impl Page { + pub fn new_aligned(vaddr: VirtAddr, size: PageSize) -> Self { + debug_assert!(size.is_aligned(vaddr)); + Self { vaddr, size } + } +} + +/// Dummy page table implemented by `mmap`, `munmap`, and `mprotect`. +pub struct PageTable; + +impl PageTable { + pub fn new() -> Self { + Self + } + + pub fn from_current() -> Self { + Self + } + + pub fn clone_kernel(&self) -> Self { + Self::new() + } +} + +impl Default for PageTable { + fn default() -> Self { + Self::new() + } +} + +pub trait GenericPageTable: Sync + Send { + /// Get the physical address of root page table. + fn table_phys(&self) -> PhysAddr; + + /// Map the `page` to the frame of `paddr` with `flags`. + fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult; + + /// Unmap the page of `vaddr`. + fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, PageSize)>; + + /// Change the `flags` of the page of `vaddr`. + fn update( + &mut self, + vaddr: VirtAddr, + paddr: Option, + flags: Option, + ) -> PagingResult; + + /// Query the physical address which the page of `vaddr` maps to. + fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags, PageSize)>; + + fn map_cont( + &mut self, + start_vaddr: VirtAddr, + size: usize, + start_paddr: PhysAddr, + flags: MMUFlags, + ) -> PagingResult { + assert!(is_aligned(start_vaddr)); + assert!(is_aligned(start_vaddr)); + assert!(is_aligned(size)); + debug!( + "map_cont: {:#x?} => {:#x}, flags={:?}", + start_vaddr..start_vaddr + size, + start_paddr, + flags + ); + let mut vaddr = start_vaddr; + let mut paddr = start_paddr; + let end_vaddr = vaddr + size; + if flags.contains(MMUFlags::HUGE_PAGE) { + while vaddr < end_vaddr { + let remains = end_vaddr - vaddr; + let page_size = if remains >= PageSize::Size1G as usize + && PageSize::Size1G.is_aligned(vaddr) + && PageSize::Size1G.is_aligned(paddr) + { + PageSize::Size1G + } else if remains >= PageSize::Size2M as usize + && PageSize::Size2M.is_aligned(vaddr) + && PageSize::Size2M.is_aligned(paddr) + { + PageSize::Size2M + } else { + PageSize::Size4K + }; + let page = Page::new_aligned(vaddr, page_size); + self.map(page, paddr, flags)?; + vaddr += page_size as usize; + paddr += page_size as usize; + } + } else { + while vaddr < end_vaddr { + let page_size = PageSize::Size4K; + let page = Page::new_aligned(vaddr, page_size); + self.map(page, paddr, flags)?; + vaddr += page_size as usize; + paddr += page_size as usize; + } + } + Ok(()) + } + + fn unmap_cont(&mut self, start_vaddr: VirtAddr, size: usize) -> PagingResult { + assert!(is_aligned(start_vaddr)); + assert!(is_aligned(size)); + debug!( + "{:#x?} unmap_cont: {:#x?}", + self.table_phys(), + start_vaddr..start_vaddr + size + ); + let mut vaddr = start_vaddr; + let end_vaddr = vaddr + size; + while vaddr < end_vaddr { + let page_size = match self.unmap(vaddr) { + Ok((_, s)) => { + assert!(s.is_aligned(vaddr)); + s as usize + } + Err(PagingError::NotMapped) => PageSize::Size4K as usize, + Err(e) => return Err(e), + }; + vaddr += page_size; + assert!(vaddr <= end_vaddr); + } + Ok(()) + } +} + + +impl GenericPageTable for PageTable { + fn table_phys(&self) -> PhysAddr { + 0 + } + + fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult { + debug_assert!(page.size as usize == PAGE_SIZE); + debug_assert!(is_aligned(paddr)); + if paddr < PMEM_SIZE { + MOCK_PHYS_MEM.mmap(page.vaddr, PAGE_SIZE, paddr, flags); + Ok(()) + } else { + Err(PagingError::NoMemory) + } + } + + fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, PageSize)> { + self.unmap_cont(vaddr, PAGE_SIZE)?; + Ok((0, PageSize::Size4K)) + } + + fn update( + &mut self, + vaddr: VirtAddr, + _paddr: Option, + flags: Option, + ) -> PagingResult { + debug_assert!(is_aligned(vaddr)); + if let Some(flags) = flags { + MOCK_PHYS_MEM.mprotect(vaddr as _, PAGE_SIZE, flags); + } + Ok(PageSize::Size4K) + } + + fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags, PageSize)> { + debug_assert!(is_aligned(vaddr)); + if (PMEM_MAP_VADDR..PMEM_MAP_VADDR + PMEM_SIZE).contains(&vaddr) { + Ok(( + vaddr - PMEM_MAP_VADDR, + MMUFlags::READ | MMUFlags::WRITE, + PageSize::Size4K, + )) + } else { + Err(PagingError::NotMapped) + } + } + + fn unmap_cont(&mut self, vaddr: VirtAddr, size: usize) -> PagingResult { + if size == 0 { + return Ok(()); + } + debug_assert!(is_aligned(vaddr)); + MOCK_PHYS_MEM.munmap(vaddr as _, size); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// A valid virtual address base to mmap. + const VBASE: VirtAddr = 0x0002_0000_0000; + + #[test] + fn map_unmap() { + let mut pt = PageTable::new(); + let flags = MMUFlags::READ | MMUFlags::WRITE; + // map 2 pages to 1 frame + pt.map(Page::new_aligned(VBASE, PageSize::Size4K), 0x1000, flags) + .unwrap(); + pt.map( + Page::new_aligned(VBASE + 0x1000, PageSize::Size4K), + 0x1000, + flags, + ) + .unwrap(); + + unsafe { + const MAGIC: usize = 0xdead_beaf; + (VBASE as *mut usize).write(MAGIC); + assert_eq!(((VBASE + 0x1000) as *mut usize).read(), MAGIC); + } + + pt.unmap(VBASE + 0x1000).unwrap(); + } +} diff --git a/src/utils/init_once.rs b/src/utils/init_once.rs new file mode 100644 index 0000000..046c387 --- /dev/null +++ b/src/utils/init_once.rs @@ -0,0 +1,54 @@ +use spin::Once; + +pub struct InitOnce { + inner: Once, + default: Option, +} + +impl InitOnce { + pub const fn new() -> Self { + Self { + inner: Once::new(), + default: None, + } + } + + #[cfg(any(doc, not(target_arch = "x86_64"), feature = "libos"))] + pub const fn new_with_default(value: T) -> Self { + Self { + inner: Once::new(), + default: Some(value), + } + } + + pub fn init_once_by(&self, value: T) { + self.inner.call_once(|| value); + } + + #[cfg(any(doc, target_arch = "riscv64"))] + pub fn init_once(&self, f: F) + where + F: FnOnce() -> T, + { + self.inner.call_once(f); + } + + pub fn default(&self) -> Option<&T> { + self.default.as_ref() + } + + #[cfg(any(doc, feature = "graphic"))] + pub fn try_get(&self) -> Option<&T> { + self.inner.get() + } +} + +impl core::ops::Deref for InitOnce { + type Target = T; + fn deref(&self) -> &Self::Target { + self.inner + .get() + .or_else(|| self.default()) + .unwrap_or_else(|| panic!("uninitialized InitOnce<{}>", core::any::type_name::())) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index d7b8210..e216e0c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,2 @@ -pub(crate) mod once; -pub(crate) mod macros; \ No newline at end of file +pub(crate) mod macros; +pub(crate) mod init_once; \ No newline at end of file From beb70f2e1e474a488f6c41a8bc6a76f66ac0d8db Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 18 May 2024 00:41:30 -0700 Subject: [PATCH 09/26] before refactor --- src/lib.rs | 5 +++++ src/libos/mem.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 888ff22..7b5f914 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,11 @@ cfg_if! { pub use imp::page::PageAlloc; pub use imp::addr::*; pub use imp::init; + pub use imp::mem::free_pmem_regions; + pub use imp::vm::{Page, PageTable, GenericPageTable}; + pub use imp::addr::MMUFlags; + pub use imp::vm::PageSize; + pub use imp::mem::{pmem_read, pmem_copy, pmem_write}; } else { #[path = "bare/mod.rs"] mod imp; diff --git a/src/libos/mem.rs b/src/libos/mem.rs index 37fd7cf..e766ee3 100644 --- a/src/libos/mem.rs +++ b/src/libos/mem.rs @@ -40,7 +40,7 @@ pub fn pmem_read(paddr: PhysAddr, buf: &mut [u8]) { unsafe { buf.as_mut_ptr().copy_from_nonoverlapping(src, buf.len()) }; } -fn pmem_write(paddr: PhysAddr, buf: &[u8]) { +pub fn pmem_write(paddr: PhysAddr, buf: &[u8]) { trace!("pmem write: paddr={:#x}, len={:#x}", paddr, buf.len()); assert!(paddr + buf.len() <= PMEM_SIZE); let dst = MOCK_PHYS_MEM.as_mut_ptr::(paddr); From c94b4064a8c8db62a2f071a967bb55cd50e15a54 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 18 May 2024 11:52:53 -0700 Subject: [PATCH 10/26] adapt bare --- .cargo/config.toml | 2 +- Cargo.lock | 9 +-------- Cargo.toml | 18 +++++++++--------- src/bare/arch/aarch64/mod.rs | 8 ++++---- src/bare/arch/loongarch64/mod.rs | 2 +- src/bare/arch/riscv64/mod.rs | 12 +++++------- src/lib.rs | 3 +-- src/libos/addr.rs | 1 - src/libos/mem.rs | 6 +----- src/utils/init_once.rs | 21 --------------------- 10 files changed, 23 insertions(+), 59 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index b615045..a6b4d94 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,4 +3,4 @@ # target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' # target = 'x86_64-unknown-none' -# target = 'loongarch64-unknown-none' +target = 'loongarch64-unknown-none' diff --git a/Cargo.lock b/Cargo.lock index c4f87ba..0d986c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,12 +266,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "numeric-enum-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e4bdb6b46b592948e700ea1ef24a4296491f6a0ee722b258040abd15a3714" - [[package]] name = "paste" version = "1.0.14" @@ -306,7 +300,7 @@ dependencies = [ "aarch64-cpu", "arm_gic", "arm_pl011", - "bitflags 1.3.2", + "bitflags 2.5.0", "bitmap-allocator", "cfg-if", "fdt", @@ -317,7 +311,6 @@ dependencies = [ "loongArch64", "multiboot", "nix", - "numeric-enum-macro", "percpu", "polyhal-macro", "raw-cpuid 11.0.1", diff --git a/Cargo.toml b/Cargo.toml index 4e7cdb6..e041b00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,25 +12,26 @@ repository = "https://github.com/Byte-OS/polyhal" [features] kcontext = [] multicore = [] -libos = [] +libos = [ + "nix", + "tempfile" +] -default = ["multicore", "libos"] +default = ["multicore"] [dependencies] log = "0.4" -nix = { version = "0.23"} -tempfile = { version = "3"} +nix = { version = "0.23", optional = true} +tempfile = { version = "3", optional = true} fdt = "0.1.5" -bitflags = "1.3" +bitflags = "2.0.1" cfg-if = "1.0.0" percpu = { git = "https://github.com/Byte-OS/percpu.git" } polyhal-macro = { path = "polyhal-macro" } lazy_static = { version = "1.4.0", features = ["spin_no_std"] } -numeric-enum-macro = "0.2" bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator.git", rev = "88e871a5"} lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "8486b8" } - - +spin = { version = "0.9.8", features = ["mutex"] } [target.'cfg(target_arch = "riscv64")'.dependencies] riscv = "0.11.0" @@ -39,7 +40,6 @@ sbi-rt = { version = "0.0.2", features = ["legacy"] } [target.'cfg(target_arch = "x86_64")'.dependencies] x86 = "0.52" x86_64 = "0.14" -spin = { version = "0.9.8", features = ["mutex"] } irq_safety = { git = "https://github.com/theseus-os/irq_safety.git" } multiboot = "0.8.0" x2apic = "0.4" diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index cdcfbd0..8bf8baf 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -26,14 +26,14 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext} pub use page_table::*; pub use psci::system_off as shutdown; -pub use trap::{disable_irq, enable_external_irq, enable_irq, run_user_task}; +pub use trap::run_user_task; use crate::MultiCore; -use crate::utils::once::LazyInit; +use crate::utils::init_once::InitOnce; use crate::PageTable; use super::{clear_bss, CPU_NUM, MEM_AREA, DTB_BIN}; -static DTB_PTR: LazyInit = LazyInit::new(); +static DTB_PTR: InitOnce = InitOnce::new(); pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { clear_bss(); @@ -43,7 +43,7 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { timer::init(); - DTB_PTR.init_by(device_tree | VIRT_ADDR_START); + DTB_PTR.init_once_by(device_tree | VIRT_ADDR_START); if let Ok(fdt) = unsafe { Fdt::from_ptr(*DTB_PTR as *const u8) } { CPU_NUM.init_by(fdt.cpus().count()); diff --git a/src/bare/arch/loongarch64/mod.rs b/src/bare/arch/loongarch64/mod.rs index 0e8f551..203c880 100644 --- a/src/bare/arch/loongarch64/mod.rs +++ b/src/bare/arch/loongarch64/mod.rs @@ -20,7 +20,7 @@ pub use context::TrapFrame; pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext}; use loongArch64::register::euen; pub use page_table::kernel_page_table; -pub use trap::{disable_irq, enable_external_irq, enable_irq, run_user_task}; +pub use trap::run_user_task; pub fn rust_tmp_main(hart_id: usize) { clear_bss(); diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index 8185188..c47c47b 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -15,11 +15,9 @@ use core::slice; use alloc::vec::Vec; pub use consts::*; pub use context::TrapFrame; -pub use entry::{kernel_page_table, switch_to_kernel_page_table}; +pub use entry::kernel_page_table; use fdt::Fdt; -pub use interrupt::{ - disable_irq, enable_external_irq, enable_irq, run_user_task, run_user_task_forever, -}; +pub use interrupt::run_user_task; pub use boards::*; use sbi::*; @@ -30,13 +28,13 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext} use riscv::register::sstatus; -use crate::{frame_alloc, MultiCore, utils::once::LazyInit}; +use crate::{frame_alloc, MultiCore, utils::init_once::InitOnce}; use super::{CPU_NUM, DTB_BIN, MEM_AREA}; #[percpu::def_percpu] static CPU_ID: usize = 0; -static DTB_PTR: LazyInit = LazyInit::new(); +static DTB_PTR: InitOnce = InitOnce::new(); pub(crate) fn rust_main(hartid: usize, device_tree: usize) { super::clear_bss(); @@ -60,7 +58,7 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { Err(_) => 1, }); - DTB_PTR.init_by(device_tree); + DTB_PTR.init_once_by(device_tree); unsafe { crate::_main_for_arch(hartid) }; shutdown(); diff --git a/src/lib.rs b/src/lib.rs index 7b5f914..855932c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,6 @@ extern crate lazy_static; #[macro_use] mod utils; - cfg_if! { if #[cfg(feature = "libos")] { #[path = "libos/mod.rs"] @@ -36,7 +35,7 @@ cfg_if! { pub use imp::vm::{Page, PageTable, GenericPageTable}; pub use imp::addr::MMUFlags; pub use imp::vm::PageSize; - pub use imp::mem::{pmem_read, pmem_copy, pmem_write}; + pub use imp::mem::{pmem_read, pmem_copy, pmem_write, pmem_zero}; } else { #[path = "bare/mod.rs"] mod imp; diff --git a/src/libos/addr.rs b/src/libos/addr.rs index 69ce3a5..c3766db 100644 --- a/src/libos/addr.rs +++ b/src/libos/addr.rs @@ -1,5 +1,4 @@ use bitflags::bitflags; -use numeric_enum_macro::numeric_enum; /// Physical address. pub type PhysAddr = usize; diff --git a/src/libos/mem.rs b/src/libos/mem.rs index e766ee3..a4a46a6 100644 --- a/src/libos/mem.rs +++ b/src/libos/mem.rs @@ -25,10 +25,6 @@ lazy_static! { pub(super) static ref MOCK_PHYS_MEM: MockMemory = MockMemory::new(PMEM_SIZE); } -pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr { - MOCK_PHYS_MEM.phys_to_virt(paddr) -} - pub fn free_pmem_regions() -> Vec> { vec![PAGE_SIZE..PMEM_SIZE] } @@ -47,7 +43,7 @@ pub fn pmem_write(paddr: PhysAddr, buf: &[u8]) { unsafe { dst.copy_from_nonoverlapping(buf.as_ptr(), buf.len()) }; } -fn pmem_zero(paddr: PhysAddr, len: usize) { +pub fn pmem_zero(paddr: PhysAddr, len: usize) { trace!("pmem_zero: addr={:#x}, len={:#x}", paddr, len); assert!(paddr + len <= PMEM_SIZE); unsafe { core::ptr::write_bytes(MOCK_PHYS_MEM.as_mut_ptr::(paddr), 0, len) }; diff --git a/src/utils/init_once.rs b/src/utils/init_once.rs index 046c387..abb8769 100644 --- a/src/utils/init_once.rs +++ b/src/utils/init_once.rs @@ -13,34 +13,13 @@ impl InitOnce { } } - #[cfg(any(doc, not(target_arch = "x86_64"), feature = "libos"))] - pub const fn new_with_default(value: T) -> Self { - Self { - inner: Once::new(), - default: Some(value), - } - } - pub fn init_once_by(&self, value: T) { self.inner.call_once(|| value); } - #[cfg(any(doc, target_arch = "riscv64"))] - pub fn init_once(&self, f: F) - where - F: FnOnce() -> T, - { - self.inner.call_once(f); - } - pub fn default(&self) -> Option<&T> { self.default.as_ref() } - - #[cfg(any(doc, feature = "graphic"))] - pub fn try_get(&self) -> Option<&T> { - self.inner.get() - } } impl core::ops::Deref for InitOnce { From 72fa9cea8377116de20180cf82b20a1beefdf3c8 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sat, 18 May 2024 21:02:27 -0700 Subject: [PATCH 11/26] refactor done --- .cargo/config.toml | 4 ++-- src/libos/addr.rs | 18 ++++++++---------- src/libos/vm.rs | 33 +-------------------------------- 3 files changed, 11 insertions(+), 44 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index a6b4d94..db927a4 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # Just used for rust-analyzer. -[build] +# [build] # target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' # target = 'x86_64-unknown-none' -target = 'loongarch64-unknown-none' +# target = 'loongarch64-unknown-none' diff --git a/src/libos/addr.rs b/src/libos/addr.rs index c3766db..86859ed 100644 --- a/src/libos/addr.rs +++ b/src/libos/addr.rs @@ -1,4 +1,5 @@ use bitflags::bitflags; +use crate::bit; /// Physical address. pub type PhysAddr = usize; @@ -42,16 +43,13 @@ pub type HalResult = core::result::Result; bitflags! { /// Generic memory flags. - pub struct MMUFlags: usize { + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct MMUFlags: u64 { #[allow(clippy::identity_op)] - const CACHE_1 = 1 << 0; - const CACHE_2 = 1 << 1; - const READ = 1 << 2; - const WRITE = 1 << 3; - const EXECUTE = 1 << 4; - const USER = 1 << 5; - const HUGE_PAGE = 1 << 6; - const DEVICE = 1 << 7; - const RXW = Self::READ.bits | Self::WRITE.bits | Self::EXECUTE.bits; + const READ = bit!(2); + const WRITE = bit!(3); + const EXECUTE = bit!(4); + const USER = bit!(5); + const HUGE_PAGE = bit!(6); } } \ No newline at end of file diff --git a/src/libos/vm.rs b/src/libos/vm.rs index df44508..1c07fd5 100644 --- a/src/libos/vm.rs +++ b/src/libos/vm.rs @@ -250,35 +250,4 @@ impl GenericPageTable for PageTable { MOCK_PHYS_MEM.munmap(vaddr as _, size); Ok(()) } -} - -#[cfg(test)] -mod tests { - use super::*; - - /// A valid virtual address base to mmap. - const VBASE: VirtAddr = 0x0002_0000_0000; - - #[test] - fn map_unmap() { - let mut pt = PageTable::new(); - let flags = MMUFlags::READ | MMUFlags::WRITE; - // map 2 pages to 1 frame - pt.map(Page::new_aligned(VBASE, PageSize::Size4K), 0x1000, flags) - .unwrap(); - pt.map( - Page::new_aligned(VBASE + 0x1000, PageSize::Size4K), - 0x1000, - flags, - ) - .unwrap(); - - unsafe { - const MAGIC: usize = 0xdead_beaf; - (VBASE as *mut usize).write(MAGIC); - assert_eq!(((VBASE + 0x1000) as *mut usize).read(), MAGIC); - } - - pt.unmap(VBASE + 0x1000).unwrap(); - } -} +} \ No newline at end of file From 77d09ad9fef44bccaa833bd25eb43a0dd2931ba8 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sun, 19 May 2024 20:41:30 -0700 Subject: [PATCH 12/26] delete redundant content --- Cargo.lock | 175 +++-------------------------------------------- Cargo.toml | 5 +- src/lib.rs | 9 +-- src/libos/mem.rs | 17 ++--- src/libos/mod.rs | 2 + 5 files changed, 20 insertions(+), 188 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d986c5..db6846e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,16 +8,7 @@ version = "9.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287" dependencies = [ - "tock-registers 0.8.1", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", + "tock-registers", ] [[package]] @@ -25,7 +16,7 @@ name = "arm_gic" version = "0.1.0" source = "git+https://github.com/Byte-OS/arm_gic#7a0693ebe4113cfeb2f5ee93920e6e7ea3afe99a" dependencies = [ - "tock-registers 0.8.1", + "tock-registers", ] [[package]] @@ -33,7 +24,7 @@ name = "arm_pl011" version = "0.1.0" source = "git+https://github.com/Byte-OS/arm_pl011.git#8a66e24c7e6ac2a01841cd29c5e1690323aa1d8d" dependencies = [ - "tock-registers 0.8.1", + "tock-registers", ] [[package]] @@ -42,12 +33,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" -[[package]] -name = "bare-metal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" - [[package]] name = "bit" version = "0.1.1" @@ -72,14 +57,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" -[[package]] -name = "bitmap-allocator" -version = "0.1.0" -source = "git+https://github.com/rcore-os/bitmap-allocator.git?rev=88e871a5#88e871a54f28a3d6795478f237466b3332e2fb1d" -dependencies = [ - "bit_field", -] - [[package]] name = "cc" version = "1.0.97" @@ -92,31 +69,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cortex-a" -version = "7.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdecfbb28672ad3664e71ae05a398a52df430d86d660691501b28968cc4467e6" -dependencies = [ - "tock-registers 0.7.0", -] - [[package]] name = "critical-section" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" -[[package]] -name = "embedded-hal" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] - [[package]] name = "embedded-hal" version = "1.0.0" @@ -150,16 +108,7 @@ name = "irq_safety" version = "0.1.1" source = "git+https://github.com/theseus-os/irq_safety.git#11bfab9f410a898df1e42ad6213488612e20c926" dependencies = [ - "spin 0.9.8", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -174,20 +123,6 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" -[[package]] -name = "lock" -version = "0.1.0" -source = "git+https://github.com/DeathWish5/kernel-sync?rev=8486b8#8486b817a71ec5141836e00c817fefb94c9cfbb7" -dependencies = [ - "cfg-if", - "cortex-a", - "raw-cpuid 10.7.0", - "riscv 0.7.0", - "spin 0.9.8", - "tock-registers 0.7.0", - "x86_64", -] - [[package]] name = "lock_api" version = "0.4.11" @@ -214,12 +149,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - [[package]] name = "memoffset" version = "0.6.5" @@ -238,21 +167,6 @@ dependencies = [ "paste", ] -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.1.0", -] - -[[package]] -name = "nb" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" - [[package]] name = "nix" version = "0.23.2" @@ -279,7 +193,7 @@ source = "git+https://github.com/Byte-OS/percpu.git#a71e60e376ac28cdf1a46312e270 dependencies = [ "cfg-if", "percpu_macros", - "spin 0.9.8", + "spin", "x86", ] @@ -301,12 +215,9 @@ dependencies = [ "arm_gic", "arm_pl011", "bitflags 2.5.0", - "bitmap-allocator", "cfg-if", "fdt", "irq_safety", - "lazy_static", - "lock", "log", "loongArch64", "multiboot", @@ -314,11 +225,11 @@ dependencies = [ "percpu", "polyhal-macro", "raw-cpuid 11.0.1", - "riscv 0.11.1", + "riscv", "sbi-rt", - "spin 0.9.8", + "spin", "tempfile", - "tock-registers 0.8.1", + "tock-registers", "x2apic", "x86", "x86_64", @@ -369,46 +280,6 @@ dependencies = [ "bitflags 2.5.0", ] -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "riscv" -version = "0.7.0" -source = "git+https://github.com/rust-embedded/riscv?rev=cd31989ba1#cd31989ba11d5d64e1addd8aab98bfb00dd927d5" -dependencies = [ - "bare-metal", - "bit_field", - "embedded-hal 0.2.7", - "riscv-target", -] - [[package]] name = "riscv" version = "0.11.1" @@ -416,17 +287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" dependencies = [ "critical-section", - "embedded-hal 1.0.0", -] - -[[package]] -name = "riscv-target" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" -dependencies = [ - "lazy_static", - "regex", + "embedded-hal", ] [[package]] @@ -472,12 +333,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -516,12 +371,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "tock-registers" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee8fba06c1f4d0b396ef61a54530bb6b28f0dc61c38bc8bc5a5a48161e6282e" - [[package]] name = "tock-registers" version = "0.8.1" @@ -534,12 +383,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "volatile" version = "0.4.6" diff --git a/Cargo.toml b/Cargo.toml index e041b00..3527268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ libos = [ "tempfile" ] -default = ["multicore"] +default = ["multicore", "libos"] [dependencies] log = "0.4" @@ -28,9 +28,6 @@ bitflags = "2.0.1" cfg-if = "1.0.0" percpu = { git = "https://github.com/Byte-OS/percpu.git" } polyhal-macro = { path = "polyhal-macro" } -lazy_static = { version = "1.4.0", features = ["spin_no_std"] } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator.git", rev = "88e871a5"} -lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "8486b8" } spin = { version = "0.9.8", features = ["mutex"] } [target.'cfg(target_arch = "riscv64")'.dependencies] diff --git a/src/lib.rs b/src/lib.rs index 855932c..f310647 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,9 +14,6 @@ extern crate alloc; extern crate log; #[macro_use] extern crate cfg_if; -#[macro_use] -extern crate lazy_static; - #[macro_use] mod utils; @@ -49,8 +46,8 @@ cfg_if! { use imp::time::*; pub use imp::{ - addr::*, - page::PageAlloc, + addr::*, + page::PageAlloc, pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} }; pub use imp::{ @@ -64,7 +61,7 @@ cfg_if! { }, }; pub use polyhal_macro::{arch_entry, arch_interrupt}; - + #[cfg(feature = "kcontext")] pub use imp::{KContextArgs, current_arch::{KContext, read_current_tp, context_switch_pt, context_switch}}; } diff --git a/src/libos/mem.rs b/src/libos/mem.rs index a4a46a6..02fa962 100644 --- a/src/libos/mem.rs +++ b/src/libos/mem.rs @@ -2,27 +2,20 @@ use alloc::vec::Vec; use core::ops::Range; - -use bitmap_allocator::BitAlloc; -use lock::Mutex; +use crate::utils::init_once::InitOnce; use super::mock_mem::MockMemory; use crate::{PhysAddr, VirtAddr, PAGE_SIZE}; -type FrameAlloc = bitmap_allocator::BitAlloc1M; - /// Map physical memory from here. pub(super) const PMEM_MAP_VADDR: VirtAddr = 0x8_0000_0000; /// Physical memory size = 1GiB pub(super) const PMEM_SIZE: usize = 0x4000_0000; -lazy_static! { - pub(super) static ref FRAME_ALLOCATOR: Mutex = { - let mut allocator = FrameAlloc::DEFAULT; - allocator.insert(1..PMEM_SIZE / PAGE_SIZE); - Mutex::new(allocator) - }; - pub(super) static ref MOCK_PHYS_MEM: MockMemory = MockMemory::new(PMEM_SIZE); +pub(super) static MOCK_PHYS_MEM: InitOnce = InitOnce::new(); + +pub fn init_mock_mem() { + MOCK_PHYS_MEM.init_once_by(MockMemory::new(PMEM_SIZE)); } pub fn free_pmem_regions() -> Vec> { diff --git a/src/libos/mod.rs b/src/libos/mod.rs index bc4a54b..f286061 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -20,4 +20,6 @@ pub(crate) static PAGE_ALLOC: InitOnce<&dyn PageAlloc> = InitOnce::new(); /// Please initialize the allocator before calling this function. pub fn init(page_alloc: &'static dyn PageAlloc) { PAGE_ALLOC.init_once_by(page_alloc); + + self::mem::init_mock_mem(); } \ No newline at end of file From c8ea9e4bcbe81b2da09457160b9d0ac835b72373 Mon Sep 17 00:00:00 2001 From: jackhu Date: Sun, 19 May 2024 20:49:40 -0700 Subject: [PATCH 13/26] delete default libos feat --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3527268..6337cb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ libos = [ "tempfile" ] -default = ["multicore", "libos"] +default = ["multicore"] [dependencies] log = "0.4" From 0efdd5be309806ffc4d02d998d55918d75296741 Mon Sep 17 00:00:00 2001 From: jackhu Date: Tue, 21 May 2024 12:34:00 -0700 Subject: [PATCH 14/26] common refactor --- .cargo/config.toml | 8 +- src/bare/addr.rs | 253 +------------------- src/bare/arch/aarch64/mod.rs | 6 +- src/bare/arch/aarch64/pl011.rs | 2 +- src/bare/arch/loongarch64/console.rs | 2 +- src/bare/arch/riscv64/mod.rs | 6 +- src/bare/arch/riscv64/sbi.rs | 2 +- src/bare/arch/x86_64/mod.rs | 3 +- src/bare/arch/x86_64/uart.rs | 2 +- src/bare/mod.rs | 6 +- src/common/addr.rs | 339 +++++++++++++++++++++++++++ src/{bare => common}/debug.rs | 0 src/common/mod.rs | 3 + src/{bare => common}/page.rs | 0 src/lib.rs | 16 +- src/libos/addr.rs | 37 +-- src/libos/debug.rs | 25 +- src/libos/mem.rs | 26 +- src/libos/mock_mem.rs | 36 ++- src/libos/mod.rs | 9 +- src/libos/page.rs | 6 - src/libos/vm.rs | 155 +++--------- src/utils/init_once.rs | 33 --- src/utils/mod.rs | 2 +- src/{bare => utils}/once.rs | 0 25 files changed, 451 insertions(+), 526 deletions(-) create mode 100644 src/common/addr.rs rename src/{bare => common}/debug.rs (100%) create mode 100644 src/common/mod.rs rename src/{bare => common}/page.rs (100%) delete mode 100644 src/libos/page.rs delete mode 100644 src/utils/init_once.rs rename src/{bare => utils}/once.rs (100%) diff --git a/.cargo/config.toml b/.cargo/config.toml index db927a4..d12a149 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ -# Just used for rust-analyzer. +# # Just used for rust-analyzer. # [build] # target = "riscv64gc-unknown-none-elf" -# target = 'aarch64-unknown-none-softfloat' -# target = 'x86_64-unknown-none' -# target = 'loongarch64-unknown-none' +# # target = 'aarch64-unknown-none-softfloat' +# # target = 'x86_64-unknown-none' +# # target = 'loongarch64-unknown-none' diff --git a/src/bare/addr.rs b/src/bare/addr.rs index 062d1f1..9491e45 100644 --- a/src/bare/addr.rs +++ b/src/bare/addr.rs @@ -1,27 +1,13 @@ use core::{ ffi::CStr, - fmt::{Debug, Display}, mem::size_of, - ops::Add, }; -use crate::{PageTable, VIRT_ADDR_START}; +use crate::{PhysAddr, PhysPage, VirtAddr}; -#[repr(C)] -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub struct PhysAddr(pub(crate) usize); -impl From for PhysAddr { - fn from(value: PhysPage) -> Self { - Self(value.0 << 12) - } -} +use crate::{PageTable, VIRT_ADDR_START}; impl PhysAddr { - #[inline] - pub fn addr(&self) -> usize { - self.0 - } - #[inline] pub fn get_ptr(&self) -> *const T { (self.0 | VIRT_ADDR_START) as *const T @@ -48,79 +34,7 @@ impl PhysAddr { } } -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub struct VirtAddr(pub(crate) usize); - -impl From for VirtAddr { - fn from(value: usize) -> Self { - Self(value) - } -} - -impl From for usize { - fn from(value: VirtAddr) -> Self { - value.0 - } -} - impl VirtAddr { - #[inline] - pub fn addr(&self) -> usize { - self.0 - } - - #[inline] - pub fn get_ptr(&self) -> *const T { - self.0 as *const T - } - - #[inline] - pub fn get_mut_ptr(&self) -> *mut T { - self.0 as *mut T - } - - #[inline] - pub fn get_ref(&self) -> &'static T { - unsafe { &*(self.0 as *const T) } - } - - #[inline] - pub fn get_mut_ref(&self) -> &'static mut T { - unsafe { &mut *(self.0 as *mut T) } - } - - #[inline] - pub fn slice_with_len(&self, len: usize) -> &'static [T] { - unsafe { core::slice::from_raw_parts(self.get_ptr(), len) } - } - - #[inline] - pub fn slice_mut_with_len(&self, len: usize) -> &'static mut [T] { - unsafe { core::slice::from_raw_parts_mut(self.get_mut_ptr(), len) } - } - - #[inline] - pub fn slice_until(&self, is_valid: fn(T) -> bool) -> &'static mut [T] { - let ptr = self.addr() as *mut T; - unsafe { - let mut len = 0; - if !ptr.is_null() { - loop { - if !is_valid(ptr.add(len).read()) { - break; - } - len += 1; - } - } - core::slice::from_raw_parts_mut(ptr, len) - } - } - - #[inline] - pub fn get_cstr(&self) -> &CStr { - unsafe { CStr::from_ptr(self.get_ptr::()) } - } - #[inline] pub fn floor(&self) -> Self { Self(self.0 / PageTable::PAGE_SIZE * PageTable::PAGE_SIZE) @@ -132,72 +46,8 @@ impl VirtAddr { } } -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub struct PhysPage(pub(crate) usize); - -impl From for PhysPage { - fn from(value: usize) -> Self { - Self(value) - } -} - -impl From for PhysPage { - fn from(value: PhysAddr) -> Self { - Self(value.0 >> 12) - } -} - -impl From for usize { - fn from(value: PhysPage) -> Self { - value.0 - } -} - -impl Add for PhysPage { - type Output = PhysPage; - - fn add(self, rhs: PhysPage) -> Self::Output { - PhysPage(self.0 + rhs.0) - } -} - -impl Add for PhysPage { - type Output = PhysPage; - - fn add(self, rhs: usize) -> Self::Output { - PhysPage(self.0 + rhs) - } -} - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub struct VirtPage(pub(crate) usize); -impl From for VirtPage { - fn from(value: VirtAddr) -> Self { - Self(value.0 >> 12) - } -} -impl From for VirtPage { - fn from(value: usize) -> Self { - Self(value) - } -} impl PhysPage { - #[inline] - pub const fn new(ppn: usize) -> Self { - Self(ppn) - } - - #[inline] - pub const fn from_addr(addr: usize) -> Self { - Self(addr >> 12) - } - - #[inline] - pub const fn to_addr(&self) -> usize { - self.0 << 12 - } - #[inline] pub const fn get_buffer(&self) -> &'static mut [u8] { unsafe { @@ -242,101 +92,4 @@ impl PhysPage { asm!(".long 0x01b0000b"); // sync.is } } - - #[inline] - pub fn as_num(&self) -> usize { - self.0 - } -} - -impl Add for VirtPage { - type Output = VirtPage; - - fn add(self, rhs: usize) -> Self::Output { - VirtPage(self.0 + rhs) - } -} - -impl From for VirtAddr { - fn from(value: VirtPage) -> Self { - Self(value.to_addr()) - } -} - -impl PhysAddr { - #[inline] - pub const fn new(addr: usize) -> Self { - Self(addr) - } -} - -impl VirtPage { - #[inline] - pub const fn new(vpn: usize) -> Self { - Self(vpn) - } - - #[inline] - pub const fn from_addr(addr: usize) -> Self { - Self(addr >> 12) - } - #[inline] - pub const fn to_addr(&self) -> usize { - self.0 << 12 - } -} - -impl VirtAddr { - #[inline] - pub const fn new(addr: usize) -> Self { - Self(addr) - } -} - -impl Display for PhysPage { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Display for PhysAddr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Display for VirtPage { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Display for VirtAddr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Debug for PhysPage { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Debug for PhysAddr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Debug for VirtPage { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} - -impl Debug for VirtAddr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_fmt(format_args!("{:#x}", self.0)) - } -} +} \ No newline at end of file diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index 8bf8baf..5491bf0 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -29,11 +29,11 @@ pub use psci::system_off as shutdown; pub use trap::run_user_task; use crate::MultiCore; -use crate::utils::init_once::InitOnce; use crate::PageTable; +use crate::utils::once::LazyInit; use super::{clear_bss, CPU_NUM, MEM_AREA, DTB_BIN}; -static DTB_PTR: InitOnce = InitOnce::new(); +static DTB_PTR: LazyInit = LazyInit::new(); pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { clear_bss(); @@ -43,7 +43,7 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { timer::init(); - DTB_PTR.init_once_by(device_tree | VIRT_ADDR_START); + DTB_PTR.init_by(device_tree | VIRT_ADDR_START); if let Ok(fdt) = unsafe { Fdt::from_ptr(*DTB_PTR as *const u8) } { CPU_NUM.init_by(fdt.cpus().count()); diff --git a/src/bare/arch/aarch64/pl011.rs b/src/bare/arch/aarch64/pl011.rs index fbac0b5..726ed54 100644 --- a/src/bare/arch/aarch64/pl011.rs +++ b/src/bare/arch/aarch64/pl011.rs @@ -3,7 +3,7 @@ use arm_pl011::pl011::Pl011Uart; use irq_safety::MutexIrqSafe; -use crate::{PhysAddr, debug::DebugConsole}; +use crate::{PhysAddr, DebugConsole}; const UART_BASE: PhysAddr = PhysAddr(0x0900_0000); diff --git a/src/bare/arch/loongarch64/console.rs b/src/bare/arch/loongarch64/console.rs index 700d3cf..b397c40 100644 --- a/src/bare/arch/loongarch64/console.rs +++ b/src/bare/arch/loongarch64/console.rs @@ -1,6 +1,6 @@ use spin::Mutex; -use crate::{debug::DebugConsole, VIRT_ADDR_START}; +use crate::{DebugConsole, VIRT_ADDR_START}; #[cfg(not(board = "2k1000"))] const UART_ADDR: usize = 0x01FE001E0 | VIRT_ADDR_START; diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index c47c47b..c5db197 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -28,13 +28,13 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext} use riscv::register::sstatus; -use crate::{frame_alloc, MultiCore, utils::init_once::InitOnce}; +use crate::{frame_alloc, MultiCore, utils::once::LazyInit}; use super::{CPU_NUM, DTB_BIN, MEM_AREA}; #[percpu::def_percpu] static CPU_ID: usize = 0; -static DTB_PTR: InitOnce = InitOnce::new(); +static DTB_PTR: LazyInit = LazyInit::new(); pub(crate) fn rust_main(hartid: usize, device_tree: usize) { super::clear_bss(); @@ -58,7 +58,7 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { Err(_) => 1, }); - DTB_PTR.init_once_by(device_tree); + DTB_PTR.init_by(device_tree); unsafe { crate::_main_for_arch(hartid) }; shutdown(); diff --git a/src/bare/arch/riscv64/sbi.rs b/src/bare/arch/riscv64/sbi.rs index 459a6d3..1e7ecd1 100644 --- a/src/bare/arch/riscv64/sbi.rs +++ b/src/bare/arch/riscv64/sbi.rs @@ -6,7 +6,7 @@ use core::arch::asm; use sbi_rt::{NoReason, Shutdown}; -use crate::debug::DebugConsole; +use crate::DebugConsole; const SBI_SET_TIMER: usize = 0; const SBI_CONSOLE_PUT_CHAR: usize = 1; diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index a57fe15..c1f64a2 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -22,7 +22,6 @@ pub use interrupt::*; pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext}; pub use multiboot::kernel_page_table; use raw_cpuid::CpuId; -pub use uart::*; use x86_64::{ instructions::port::PortWriteOnly, @@ -37,7 +36,7 @@ use crate::imp::{ DTB_BIN, MEM_AREA, }; use crate::MultiCore; -use super::once::LazyInit; +use crate::utils::once::LazyInit; #[percpu::def_percpu] static CPU_ID: usize = 1; diff --git a/src/bare/arch/x86_64/uart.rs b/src/bare/arch/x86_64/uart.rs index 2e85841..fdea46d 100644 --- a/src/bare/arch/x86_64/uart.rs +++ b/src/bare/arch/x86_64/uart.rs @@ -3,7 +3,7 @@ use irq_safety::MutexIrqSafe; use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly}; -use crate::debug::DebugConsole; +use crate::DebugConsole; const UART_CLOCK_FACTOR: usize = 16; const OSC_FREQ: usize = 1_843_200; diff --git a/src/bare/mod.rs b/src/bare/mod.rs index 14efc37..0339f0b 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -144,30 +144,26 @@ cfg_if! { } } -pub mod debug; pub mod instruction; pub mod irq; pub mod mem; pub mod time; pub mod pagetable; -pub mod once; pub mod addr; pub mod api; pub mod consts; pub mod multicore; -pub mod page; use core::mem::size_of; pub use mem::Barrier; use cfg_if::cfg_if; -use once::LazyInit; +use crate::utils::once::LazyInit; use fdt::Fdt; use alloc::vec::Vec; /// Trap Frame use crate::STACK_SIZE; -use crate::PhysPage; use crate::PageAlloc; pub const PAGE_SIZE: usize = crate::PageTable::PAGE_SIZE; diff --git a/src/common/addr.rs b/src/common/addr.rs new file mode 100644 index 0000000..c8d883e --- /dev/null +++ b/src/common/addr.rs @@ -0,0 +1,339 @@ +use core::{ + ffi::CStr, + fmt::{Debug, Display}, + ops::Add, +}; + +#[repr(C)] +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub struct PhysAddr(pub(crate) usize); +impl From for PhysAddr { + fn from(value: PhysPage) -> Self { + Self(value.0 << 12) + } +} + +impl PhysAddr { + #[inline] + pub fn addr(&self) -> usize { + self.0 + } + + // #[inline] + // pub fn get_ptr(&self) -> *const T { + // (self.0 | VIRT_ADDR_START) as *const T + // } + + // #[inline] + // pub const fn get_mut_ptr(&self) -> *mut T { + // (self.0 | VIRT_ADDR_START) as *mut T + // } + + // #[inline] + // pub fn slice_with_len(&self, len: usize) -> &'static [T] { + // unsafe { core::slice::from_raw_parts(self.get_ptr(), len) } + // } + + // #[inline] + // pub fn slice_mut_with_len(&self, len: usize) -> &'static mut [T] { + // unsafe { core::slice::from_raw_parts_mut(self.get_mut_ptr(), len) } + // } + + // #[inline] + // pub fn get_cstr(&self) -> &CStr { + // unsafe { CStr::from_ptr(self.get_ptr::()) } + // } +} + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub struct VirtAddr(pub(crate) usize); + +impl From for VirtAddr { + fn from(value: usize) -> Self { + Self(value) + } +} + +impl From for usize { + fn from(value: VirtAddr) -> Self { + value.0 + } +} + +impl VirtAddr { + #[inline] + pub fn addr(&self) -> usize { + self.0 + } + + #[inline] + pub fn get_ptr(&self) -> *const T { + self.0 as *const T + } + + #[inline] + pub fn get_mut_ptr(&self) -> *mut T { + self.0 as *mut T + } + + #[inline] + pub fn get_ref(&self) -> &'static T { + unsafe { &*(self.0 as *const T) } + } + + #[inline] + pub fn get_mut_ref(&self) -> &'static mut T { + unsafe { &mut *(self.0 as *mut T) } + } + + #[inline] + pub fn slice_with_len(&self, len: usize) -> &'static [T] { + unsafe { core::slice::from_raw_parts(self.get_ptr(), len) } + } + + #[inline] + pub fn slice_mut_with_len(&self, len: usize) -> &'static mut [T] { + unsafe { core::slice::from_raw_parts_mut(self.get_mut_ptr(), len) } + } + + #[inline] + pub fn slice_until(&self, is_valid: fn(T) -> bool) -> &'static mut [T] { + let ptr = self.addr() as *mut T; + unsafe { + let mut len = 0; + if !ptr.is_null() { + loop { + if !is_valid(ptr.add(len).read()) { + break; + } + len += 1; + } + } + core::slice::from_raw_parts_mut(ptr, len) + } + } + + #[inline] + pub fn get_cstr(&self) -> &CStr { + unsafe { CStr::from_ptr(self.get_ptr::()) } + } + + // #[inline] + // pub fn floor(&self) -> Self { + // Self(self.0 / PageTable::PAGE_SIZE * PageTable::PAGE_SIZE) + // } + + // #[inline] + // pub fn ceil(&self) -> Self { + // Self((self.0 + PageTable::PAGE_SIZE - 1) / PageTable::PAGE_SIZE * PageTable::PAGE_SIZE) + // } +} + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub struct PhysPage(pub(crate) usize); + +impl From for PhysPage { + fn from(value: usize) -> Self { + Self(value) + } +} + +impl From for PhysPage { + fn from(value: PhysAddr) -> Self { + Self(value.0 >> 12) + } +} + +impl From for usize { + fn from(value: PhysPage) -> Self { + value.0 + } +} + +impl Add for PhysPage { + type Output = PhysPage; + + fn add(self, rhs: PhysPage) -> Self::Output { + PhysPage(self.0 + rhs.0) + } +} + +impl Add for PhysPage { + type Output = PhysPage; + + fn add(self, rhs: usize) -> Self::Output { + PhysPage(self.0 + rhs) + } +} + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub struct VirtPage(pub(crate) usize); +impl From for VirtPage { + fn from(value: VirtAddr) -> Self { + Self(value.0 >> 12) + } +} +impl From for VirtPage { + fn from(value: usize) -> Self { + Self(value) + } +} + +impl PhysPage { + #[inline] + pub const fn new(ppn: usize) -> Self { + Self(ppn) + } + + #[inline] + pub const fn from_addr(addr: usize) -> Self { + Self(addr >> 12) + } + + #[inline] + pub const fn to_addr(&self) -> usize { + self.0 << 12 + } + + // #[inline] + // pub const fn get_buffer(&self) -> &'static mut [u8] { + // unsafe { + // core::slice::from_raw_parts_mut( + // (self.0 << 12 | VIRT_ADDR_START) as *mut u8, + // PageTable::PAGE_SIZE, + // ) + // } + // } + + // #[inline] + // pub fn copy_value_from_another(&self, ppn: PhysPage) { + // self.get_buffer().copy_from_slice(&ppn.get_buffer()); + // #[cfg(c906)] + // unsafe { + // asm!(".long 0x0010000b"); // dcache.all + // asm!(".long 0x01b0000b"); // sync.is + // } + // #[cfg(board = "2k1000")] + // unsafe { + // core::arch::asm!("dbar 0;ibar 0;") + // } + // } + + // #[inline] + // pub fn drop_clear(&self) { + // // self.get_buffer().fill(0); + // unsafe { + // core::slice::from_raw_parts_mut( + // (self.0 << 12 | VIRT_ADDR_START) as *mut usize, + // PageTable::PAGE_SIZE / size_of::(), + // ) + // .fill(0); + // } + // #[cfg(board = "2k1000")] + // unsafe { + // core::arch::asm!("dbar 0;ibar 0;") + // } + // #[cfg(c906)] + // unsafe { + // asm!(".long 0x0010000b"); // dcache.all + // asm!(".long 0x01b0000b"); // sync.is + // } + // } + + #[inline] + pub fn as_num(&self) -> usize { + self.0 + } +} + +impl Add for VirtPage { + type Output = VirtPage; + + fn add(self, rhs: usize) -> Self::Output { + VirtPage(self.0 + rhs) + } +} + +impl From for VirtAddr { + fn from(value: VirtPage) -> Self { + Self(value.to_addr()) + } +} + +impl PhysAddr { + #[inline] + pub const fn new(addr: usize) -> Self { + Self(addr) + } +} + +impl VirtPage { + #[inline] + pub const fn new(vpn: usize) -> Self { + Self(vpn) + } + + #[inline] + pub const fn from_addr(addr: usize) -> Self { + Self(addr >> 12) + } + #[inline] + pub const fn to_addr(&self) -> usize { + self.0 << 12 + } +} + +impl VirtAddr { + #[inline] + pub const fn new(addr: usize) -> Self { + Self(addr) + } +} + +impl Display for PhysPage { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Display for PhysAddr { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Display for VirtPage { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Display for VirtAddr { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Debug for PhysPage { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Debug for PhysAddr { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Debug for VirtPage { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} + +impl Debug for VirtAddr { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:#x}", self.0)) + } +} diff --git a/src/bare/debug.rs b/src/common/debug.rs similarity index 100% rename from src/bare/debug.rs rename to src/common/debug.rs diff --git a/src/common/mod.rs b/src/common/mod.rs new file mode 100644 index 0000000..c26bb90 --- /dev/null +++ b/src/common/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod addr; +pub(crate) mod page; +pub(crate) mod debug; \ No newline at end of file diff --git a/src/bare/page.rs b/src/common/page.rs similarity index 100% rename from src/bare/page.rs rename to src/common/page.rs diff --git a/src/lib.rs b/src/lib.rs index f310647..fcd4be5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,11 @@ extern crate cfg_if; #[macro_use] mod utils; +mod common; +pub use common::addr::*; +pub use common::debug::DebugConsole; +pub use common::page::PageAlloc; + cfg_if! { if #[cfg(feature = "libos")] { #[path = "libos/mod.rs"] @@ -24,14 +29,11 @@ cfg_if! { pub use polyhal_macro::{arch_entry, arch_interrupt}; pub use imp::context::*; - pub use imp::debug::DebugConsole; - pub use imp::page::PageAlloc; pub use imp::addr::*; pub use imp::init; - pub use imp::mem::free_pmem_regions; + pub use imp::mem::get_mem_areas; pub use imp::vm::{Page, PageTable, GenericPageTable}; pub use imp::addr::MMUFlags; - pub use imp::vm::PageSize; pub use imp::mem::{pmem_read, pmem_copy, pmem_write, pmem_zero}; } else { #[path = "bare/mod.rs"] @@ -41,20 +43,14 @@ cfg_if! { use imp::consts::*; use imp::multicore::MultiCore; use imp::*; - use imp::current_arch::*; - use imp::debug::*; - use imp::time::*; pub use imp::{ - addr::*, - page::PageAlloc, pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} }; pub use imp::{ get_mem_areas, init, TrapFrameArgs, TrapType, PAGE_SIZE, time::*, - debug::DebugConsole, current_arch::{ run_user_task, shutdown, kernel_page_table, TrapFrame, VIRT_ADDR_START, diff --git a/src/libos/addr.rs b/src/libos/addr.rs index 86859ed..c120b97 100644 --- a/src/libos/addr.rs +++ b/src/libos/addr.rs @@ -1,17 +1,27 @@ use bitflags::bitflags; -use crate::bit; +use crate::{bit, PhysAddr, VirtAddr}; +use crate::common::addr::PhysPage; -/// Physical address. -pub type PhysAddr = usize; - -/// Virtual address. -pub type VirtAddr = usize; +pub const PAGE_SIZE: usize = 0x1000; +pub const PAGE_BITS: usize = 12; -/// Device address. -pub type DevVAddr = usize; +impl PhysPage { + pub fn addr(&self) -> PhysAddr { + PhysAddr::new(self.0 << PAGE_BITS) + } +} -pub const PAGE_SIZE: usize = 0x1000; +impl VirtAddr { + pub fn add_offset(&mut self, s: usize) { + self.0 += s; + } +} +impl PhysAddr { + pub fn add_offset(&mut self, s: usize) { + self.0 += s; + } +} pub const fn align_down(addr: usize) -> usize { addr & !(PAGE_SIZE - 1) @@ -33,14 +43,6 @@ pub const fn page_offset(addr: usize) -> usize { addr & (PAGE_SIZE - 1) } -/// The error type which is returned from HAL functions. -/// TODO: more error types. -#[derive(Debug)] -pub struct HalError; - -/// The result type returned by HAL functions. -pub type HalResult = core::result::Result; - bitflags! { /// Generic memory flags. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -50,6 +52,5 @@ bitflags! { const WRITE = bit!(3); const EXECUTE = bit!(4); const USER = bit!(5); - const HUGE_PAGE = bit!(6); } } \ No newline at end of file diff --git a/src/libos/debug.rs b/src/libos/debug.rs index 9bfe79c..6919e6b 100644 --- a/src/libos/debug.rs +++ b/src/libos/debug.rs @@ -1,27 +1,4 @@ -use core::fmt::Write; - -/// This is a console for debugging, -/// If you want to use this logging -/// You need to use like this: -/// -/// #### Put a char to output device(always uart) -/// ```rust -/// DebugConsole::putchar(b'3'); -/// ``` -/// -/// ### Get a char from input device(always uart) -/// ```rust -/// DebugConsole::getchar(); -/// ``` -pub struct DebugConsole; - -// Write string through DebugConsole -impl Write for DebugConsole { - fn write_str(&mut self, s: &str) -> core::fmt::Result { - std::print!("{}", s); - Ok(()) - } -} +use crate::DebugConsole; impl DebugConsole { pub fn putchar(c: u8) { diff --git a/src/libos/mem.rs b/src/libos/mem.rs index 02fa962..f8bb553 100644 --- a/src/libos/mem.rs +++ b/src/libos/mem.rs @@ -2,49 +2,49 @@ use alloc::vec::Vec; use core::ops::Range; -use crate::utils::init_once::InitOnce; +use crate::utils::once::LazyInit; use super::mock_mem::MockMemory; use crate::{PhysAddr, VirtAddr, PAGE_SIZE}; /// Map physical memory from here. -pub(super) const PMEM_MAP_VADDR: VirtAddr = 0x8_0000_0000; +pub(super) const PMEM_MAP_VADDR: VirtAddr = VirtAddr::new(0x8_0000_0000); /// Physical memory size = 1GiB pub(super) const PMEM_SIZE: usize = 0x4000_0000; -pub(super) static MOCK_PHYS_MEM: InitOnce = InitOnce::new(); +pub(super) static MOCK_PHYS_MEM: LazyInit = LazyInit::new(); pub fn init_mock_mem() { - MOCK_PHYS_MEM.init_once_by(MockMemory::new(PMEM_SIZE)); + MOCK_PHYS_MEM.init_by(MockMemory::new(PMEM_SIZE)); } -pub fn free_pmem_regions() -> Vec> { +pub fn get_mem_areas() -> Vec> { vec![PAGE_SIZE..PMEM_SIZE] } pub fn pmem_read(paddr: PhysAddr, buf: &mut [u8]) { - trace!("pmem read: paddr={:#x}, len={:#x}", paddr, buf.len()); - assert!(paddr + buf.len() <= PMEM_SIZE); + trace!("pmem read: paddr={:#x}, len={:#x}", paddr.addr(), buf.len()); + assert!(paddr.addr() + buf.len() <= PMEM_SIZE); let src = MOCK_PHYS_MEM.as_ptr(paddr); unsafe { buf.as_mut_ptr().copy_from_nonoverlapping(src, buf.len()) }; } pub fn pmem_write(paddr: PhysAddr, buf: &[u8]) { - trace!("pmem write: paddr={:#x}, len={:#x}", paddr, buf.len()); - assert!(paddr + buf.len() <= PMEM_SIZE); + trace!("pmem write: paddr={:#x}, len={:#x}", paddr.addr(), buf.len()); + assert!(paddr.addr() + buf.len() <= PMEM_SIZE); let dst = MOCK_PHYS_MEM.as_mut_ptr::(paddr); unsafe { dst.copy_from_nonoverlapping(buf.as_ptr(), buf.len()) }; } pub fn pmem_zero(paddr: PhysAddr, len: usize) { - trace!("pmem_zero: addr={:#x}, len={:#x}", paddr, len); - assert!(paddr + len <= PMEM_SIZE); + trace!("pmem_zero: addr={:#x}, len={:#x}", paddr.addr(), len); + assert!(paddr.addr() + len <= PMEM_SIZE); unsafe { core::ptr::write_bytes(MOCK_PHYS_MEM.as_mut_ptr::(paddr), 0, len) }; } pub fn pmem_copy(dst: PhysAddr, src: PhysAddr, len: usize) { - trace!("pmem_copy: {:#x} <- {:#x}, len={:#x}", dst, src, len); - assert!(src + len <= PMEM_SIZE && dst + len <= PMEM_SIZE); + trace!("pmem_copy: {:#x} <- {:#x}, len={:#x}", dst.addr(), src.addr(), len); + assert!(src.addr() + len <= PMEM_SIZE && dst.addr() + len <= PMEM_SIZE); let dst = MOCK_PHYS_MEM.as_mut_ptr::(dst); let src = MOCK_PHYS_MEM.as_ptr::(src); unsafe { dst.copy_from_nonoverlapping(src, len) }; diff --git a/src/libos/mock_mem.rs b/src/libos/mock_mem.rs index 468abf6..21dff59 100644 --- a/src/libos/mock_mem.rs +++ b/src/libos/mock_mem.rs @@ -26,41 +26,33 @@ impl MockMemory { unistd::ftruncate(fd, size as _).expect("failed to set size of shared memory!"); let mem = Self { size, fd }; - mem.mmap(PMEM_MAP_VADDR, size, 0, MMUFlags::READ | MMUFlags::WRITE); + mem.mmap(PMEM_MAP_VADDR, size, PhysAddr::new(0), MMUFlags::READ | MMUFlags::WRITE); mem } /// Mmap `paddr` to `vaddr` in frame file. pub fn mmap(&self, vaddr: VirtAddr, len: usize, paddr: PhysAddr, prot: MMUFlags) { - assert!(paddr < self.size); - assert!(paddr + len <= self.size); - - // workaround on macOS to write text section. - #[cfg(target_os = "macos")] - let prot = if prot.contains(MMUFlags::EXECUTE) { - prot | MMUFlags::WRITE - } else { - prot - }; + assert!(paddr.addr() < self.size); + assert!(paddr.addr() + len <= self.size); let prot_noexec = ProtFlags::from(prot) - ProtFlags::PROT_EXEC; let flags = MapFlags::MAP_SHARED | MapFlags::MAP_FIXED; let fd = self.fd; - let offset = paddr as _; + let offset = paddr.addr() as _; trace!( "mmap file: fd={}, offset={:#x}, len={:#x}, vaddr={:#x}, prot={:?}", fd, offset, len, - vaddr, + vaddr.addr(), prot, ); - unsafe { mman::mmap(vaddr as _, len, prot_noexec, flags, fd, offset) }.unwrap_or_else( + unsafe { mman::mmap(vaddr.addr() as _, len, prot_noexec, flags, fd, offset) }.unwrap_or_else( |err| { panic!( "failed to mmap: fd={}, offset={:#x}, len={:#x}, vaddr={:#x}, prot={:?}: {:?}", - fd, offset, len, vaddr, prot, err + fd, offset, len, vaddr.addr(), prot, err ) }, ); @@ -70,22 +62,22 @@ impl MockMemory { } pub fn munmap(&self, vaddr: VirtAddr, len: usize) { - unsafe { mman::munmap(vaddr as _, len) } - .unwrap_or_else(|err| panic!("failed to munmap: vaddr={:#x}: {:?}", vaddr, err)); + unsafe { mman::munmap(vaddr.addr() as _, len) } + .unwrap_or_else(|err| panic!("failed to munmap: vaddr={:#x}: {:?}", vaddr.addr(), err)); } pub fn mprotect(&self, vaddr: VirtAddr, len: usize, prot: MMUFlags) { - unsafe { mman::mprotect(vaddr as _, len, prot.into()) }.unwrap_or_else(|err| { + unsafe { mman::mprotect(vaddr.addr() as _, len, prot.into()) }.unwrap_or_else(|err| { panic!( "failed to mprotect: vaddr={:#x}, prot={:?}: {:?}", - vaddr, prot, err + vaddr.addr(), prot, err ) }); } - pub fn phys_to_virt(&self, paddr: PhysAddr) -> VirtAddr { - assert!(paddr < self.size); - PMEM_MAP_VADDR + paddr + pub fn phys_to_virt(&self, paddr: PhysAddr) -> usize { + assert!(paddr.addr() < self.size); + PMEM_MAP_VADDR.addr() + paddr.addr() } pub fn as_ptr(&self, paddr: PhysAddr) -> *const T { diff --git a/src/libos/mod.rs b/src/libos/mod.rs index f286061..2186b73 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -1,25 +1,24 @@ pub mod api; pub mod context; pub mod debug; -pub mod page; pub mod mem; pub mod vm; pub mod mock_mem; pub mod addr; -use crate::utils::init_once::InitOnce; -use page::PageAlloc; +use crate::utils::once::LazyInit; +use crate::PageAlloc; #[no_mangle] fn main() { unsafe { api::_main_for_arch(0) }; } -pub(crate) static PAGE_ALLOC: InitOnce<&dyn PageAlloc> = InitOnce::new(); +pub(crate) static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); /// Init arch with page allocator, like log crate /// Please initialize the allocator before calling this function. pub fn init(page_alloc: &'static dyn PageAlloc) { - PAGE_ALLOC.init_once_by(page_alloc); + PAGE_ALLOC.init_by(page_alloc); self::mem::init_mock_mem(); } \ No newline at end of file diff --git a/src/libos/page.rs b/src/libos/page.rs deleted file mode 100644 index 010e10a..0000000 --- a/src/libos/page.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::PhysAddr; - -pub trait PageAlloc: Sync { - fn alloc(&self) -> PhysAddr; - fn dealloc(&self, ppn: PhysAddr); -} \ No newline at end of file diff --git a/src/libos/vm.rs b/src/libos/vm.rs index 1c07fd5..2969de3 100644 --- a/src/libos/vm.rs +++ b/src/libos/vm.rs @@ -1,9 +1,6 @@ -//! Virtual memory operations. - use super::mem::{MOCK_PHYS_MEM, PMEM_MAP_VADDR, PMEM_SIZE}; use crate::{is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE}; - /// Errors may occur during address translation. #[derive(Debug)] pub enum PagingError { @@ -31,44 +28,15 @@ impl IgnoreNotMappedErr for PagingResult { } } -/// Possible page size (4K, 2M, 1G). -#[repr(usize)] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum PageSize { - Size4K = 0x1000, - Size2M = 0x20_0000, - Size1G = 0x4000_0000, -} - /// A 4K, 2M or 1G size page. #[derive(Debug, Copy, Clone)] pub struct Page { pub vaddr: VirtAddr, - pub size: PageSize, -} - -impl PageSize { - pub const fn is_aligned(self, addr: usize) -> bool { - self.page_offset(addr) == 0 - } - - pub const fn align_down(self, addr: usize) -> usize { - addr & !(self as usize - 1) - } - - pub const fn page_offset(self, addr: usize) -> usize { - addr & (self as usize - 1) - } - - pub const fn is_huge(self) -> bool { - matches!(self, Self::Size1G | Self::Size2M) - } } impl Page { - pub fn new_aligned(vaddr: VirtAddr, size: PageSize) -> Self { - debug_assert!(size.is_aligned(vaddr)); - Self { vaddr, size } + pub fn new(vaddr: VirtAddr) -> Self { + Self { vaddr } } } @@ -103,18 +71,10 @@ pub trait GenericPageTable: Sync + Send { fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult; /// Unmap the page of `vaddr`. - fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, PageSize)>; - - /// Change the `flags` of the page of `vaddr`. - fn update( - &mut self, - vaddr: VirtAddr, - paddr: Option, - flags: Option, - ) -> PagingResult; + fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult; /// Query the physical address which the page of `vaddr` maps to. - fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags, PageSize)>; + fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags)>; fn map_cont( &mut self, @@ -123,87 +83,50 @@ pub trait GenericPageTable: Sync + Send { start_paddr: PhysAddr, flags: MMUFlags, ) -> PagingResult { - assert!(is_aligned(start_vaddr)); - assert!(is_aligned(start_vaddr)); + assert!(is_aligned(start_vaddr.addr())); + assert!(is_aligned(start_vaddr.addr())); assert!(is_aligned(size)); - debug!( - "map_cont: {:#x?} => {:#x}, flags={:?}", - start_vaddr..start_vaddr + size, - start_paddr, - flags - ); let mut vaddr = start_vaddr; let mut paddr = start_paddr; - let end_vaddr = vaddr + size; - if flags.contains(MMUFlags::HUGE_PAGE) { - while vaddr < end_vaddr { - let remains = end_vaddr - vaddr; - let page_size = if remains >= PageSize::Size1G as usize - && PageSize::Size1G.is_aligned(vaddr) - && PageSize::Size1G.is_aligned(paddr) - { - PageSize::Size1G - } else if remains >= PageSize::Size2M as usize - && PageSize::Size2M.is_aligned(vaddr) - && PageSize::Size2M.is_aligned(paddr) - { - PageSize::Size2M - } else { - PageSize::Size4K - }; - let page = Page::new_aligned(vaddr, page_size); - self.map(page, paddr, flags)?; - vaddr += page_size as usize; - paddr += page_size as usize; - } - } else { - while vaddr < end_vaddr { - let page_size = PageSize::Size4K; - let page = Page::new_aligned(vaddr, page_size); - self.map(page, paddr, flags)?; - vaddr += page_size as usize; - paddr += page_size as usize; - } + let end_vaddr = vaddr.addr() + size; + while vaddr.addr() < end_vaddr { + let page = Page::new(vaddr); + self.map(page, paddr, flags)?; + vaddr.add_offset(PAGE_SIZE); + paddr.add_offset(PAGE_SIZE); } Ok(()) } fn unmap_cont(&mut self, start_vaddr: VirtAddr, size: usize) -> PagingResult { - assert!(is_aligned(start_vaddr)); + assert!(is_aligned(start_vaddr.addr())); assert!(is_aligned(size)); - debug!( - "{:#x?} unmap_cont: {:#x?}", - self.table_phys(), - start_vaddr..start_vaddr + size - ); let mut vaddr = start_vaddr; - let end_vaddr = vaddr + size; - while vaddr < end_vaddr { + let end_vaddr = vaddr.addr() + size; + while vaddr.addr() < end_vaddr { let page_size = match self.unmap(vaddr) { - Ok((_, s)) => { - assert!(s.is_aligned(vaddr)); - s as usize + Ok(s) => { + info!("unmap_cont: {:?}", s); + PAGE_SIZE } - Err(PagingError::NotMapped) => PageSize::Size4K as usize, + Err(PagingError::NotMapped) => PAGE_SIZE, Err(e) => return Err(e), }; - vaddr += page_size; - assert!(vaddr <= end_vaddr); + vaddr.add_offset(page_size as usize); + assert!(vaddr.addr() <= end_vaddr); } Ok(()) } } - impl GenericPageTable for PageTable { fn table_phys(&self) -> PhysAddr { - 0 + PhysAddr::new(0) } fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult { - debug_assert!(page.size as usize == PAGE_SIZE); - debug_assert!(is_aligned(paddr)); - if paddr < PMEM_SIZE { + debug_assert!(is_aligned(paddr.addr())); + if paddr.addr() < PMEM_SIZE { MOCK_PHYS_MEM.mmap(page.vaddr, PAGE_SIZE, paddr, flags); Ok(()) } else { @@ -211,31 +134,17 @@ impl GenericPageTable for PageTable { } } - fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, PageSize)> { + fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult { self.unmap_cont(vaddr, PAGE_SIZE)?; - Ok((0, PageSize::Size4K)) + Ok(PhysAddr::new(0)) } - fn update( - &mut self, - vaddr: VirtAddr, - _paddr: Option, - flags: Option, - ) -> PagingResult { - debug_assert!(is_aligned(vaddr)); - if let Some(flags) = flags { - MOCK_PHYS_MEM.mprotect(vaddr as _, PAGE_SIZE, flags); - } - Ok(PageSize::Size4K) - } - - fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags, PageSize)> { - debug_assert!(is_aligned(vaddr)); - if (PMEM_MAP_VADDR..PMEM_MAP_VADDR + PMEM_SIZE).contains(&vaddr) { + fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags)> { + debug_assert!(is_aligned(vaddr.addr())); + if (PMEM_MAP_VADDR.addr()..PMEM_MAP_VADDR.addr() + PMEM_SIZE).contains(&vaddr.addr()) { Ok(( - vaddr - PMEM_MAP_VADDR, + PhysAddr::new(vaddr.addr() - PMEM_MAP_VADDR.addr()), MMUFlags::READ | MMUFlags::WRITE, - PageSize::Size4K, )) } else { Err(PagingError::NotMapped) @@ -246,8 +155,8 @@ impl GenericPageTable for PageTable { if size == 0 { return Ok(()); } - debug_assert!(is_aligned(vaddr)); + debug_assert!(is_aligned(vaddr.addr())); MOCK_PHYS_MEM.munmap(vaddr as _, size); Ok(()) } -} \ No newline at end of file +} diff --git a/src/utils/init_once.rs b/src/utils/init_once.rs deleted file mode 100644 index abb8769..0000000 --- a/src/utils/init_once.rs +++ /dev/null @@ -1,33 +0,0 @@ -use spin::Once; - -pub struct InitOnce { - inner: Once, - default: Option, -} - -impl InitOnce { - pub const fn new() -> Self { - Self { - inner: Once::new(), - default: None, - } - } - - pub fn init_once_by(&self, value: T) { - self.inner.call_once(|| value); - } - - pub fn default(&self) -> Option<&T> { - self.default.as_ref() - } -} - -impl core::ops::Deref for InitOnce { - type Target = T; - fn deref(&self) -> &Self::Target { - self.inner - .get() - .or_else(|| self.default()) - .unwrap_or_else(|| panic!("uninitialized InitOnce<{}>", core::any::type_name::())) - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index e216e0c..a1dca5e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,2 @@ pub(crate) mod macros; -pub(crate) mod init_once; \ No newline at end of file +pub(crate) mod once; \ No newline at end of file diff --git a/src/bare/once.rs b/src/utils/once.rs similarity index 100% rename from src/bare/once.rs rename to src/utils/once.rs From 9212f9ef5e61ff84aaf5e32ecc2d9e2939afdc44 Mon Sep 17 00:00:00 2001 From: jackhu Date: Tue, 21 May 2024 16:33:13 -0700 Subject: [PATCH 15/26] refactor then --- .cargo/config.toml | 12 ++-- src/lib.rs | 3 +- src/libos/api.rs | 3 - src/libos/mod.rs | 7 ++- src/libos/vm.rs | 137 ++------------------------------------------- 5 files changed, 19 insertions(+), 143 deletions(-) delete mode 100644 src/libos/api.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index d12a149..bac0add 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ -# # Just used for rust-analyzer. -# [build] -# target = "riscv64gc-unknown-none-elf" -# # target = 'aarch64-unknown-none-softfloat' -# # target = 'x86_64-unknown-none' -# # target = 'loongarch64-unknown-none' +# Just used for rust-analyzer. +[build] +target = "riscv64gc-unknown-none-elf" +# target = 'aarch64-unknown-none-softfloat' +# target = 'x86_64-unknown-none' +# target = 'loongarch64-unknown-none' diff --git a/src/lib.rs b/src/lib.rs index fcd4be5..046b603 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ cfg_if! { pub use imp::addr::*; pub use imp::init; pub use imp::mem::get_mem_areas; - pub use imp::vm::{Page, PageTable, GenericPageTable}; + pub use imp::vm::{Page, PageTable}; pub use imp::addr::MMUFlags; pub use imp::mem::{pmem_read, pmem_copy, pmem_write, pmem_zero}; } else { @@ -43,6 +43,7 @@ cfg_if! { use imp::consts::*; use imp::multicore::MultiCore; use imp::*; + use imp::current_arch::*; pub use imp::{ pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} diff --git a/src/libos/api.rs b/src/libos/api.rs deleted file mode 100644 index 5ba118d..0000000 --- a/src/libos/api.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern "Rust" { - pub(crate) fn _main_for_arch(hartid: usize); -} \ No newline at end of file diff --git a/src/libos/mod.rs b/src/libos/mod.rs index 2186b73..b67cce8 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -1,4 +1,3 @@ -pub mod api; pub mod context; pub mod debug; pub mod mem; @@ -8,9 +7,13 @@ pub mod addr; use crate::utils::once::LazyInit; use crate::PageAlloc; +extern "Rust" { + pub(crate) fn _main_for_arch(hartid: usize); +} + #[no_mangle] fn main() { - unsafe { api::_main_for_arch(0) }; + unsafe { _main_for_arch(0) }; } pub(crate) static PAGE_ALLOC: LazyInit<&dyn PageAlloc> = LazyInit::new(); diff --git a/src/libos/vm.rs b/src/libos/vm.rs index 2969de3..c93be2f 100644 --- a/src/libos/vm.rs +++ b/src/libos/vm.rs @@ -1,34 +1,6 @@ -use super::mem::{MOCK_PHYS_MEM, PMEM_MAP_VADDR, PMEM_SIZE}; +use super::mem::{MOCK_PHYS_MEM, PMEM_SIZE}; use crate::{is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE}; -/// Errors may occur during address translation. -#[derive(Debug)] -pub enum PagingError { - NoMemory, - NotMapped, - AlreadyMapped, -} - -/// Address translation result. -pub type PagingResult = Result; - -/// The [`PagingError::NotMapped`] can be ignored. -pub trait IgnoreNotMappedErr { - /// If self is `Err(PagingError::NotMapped`, ignores the error and returns - /// `Ok(())`, otherwise remain unchanged. - fn ignore(self) -> PagingResult; -} - -impl IgnoreNotMappedErr for PagingResult { - fn ignore(self) -> PagingResult { - match self { - Ok(_) | Err(PagingError::NotMapped) => Ok(()), - Err(e) => Err(e), - } - } -} - -/// A 4K, 2M or 1G size page. #[derive(Debug, Copy, Clone)] pub struct Page { pub vaddr: VirtAddr, @@ -47,116 +19,19 @@ impl PageTable { pub fn new() -> Self { Self } - - pub fn from_current() -> Self { - Self - } - - pub fn clone_kernel(&self) -> Self { - Self::new() - } -} - -impl Default for PageTable { - fn default() -> Self { - Self::new() - } -} - -pub trait GenericPageTable: Sync + Send { - /// Get the physical address of root page table. - fn table_phys(&self) -> PhysAddr; - - /// Map the `page` to the frame of `paddr` with `flags`. - fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult; - - /// Unmap the page of `vaddr`. - fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult; - - /// Query the physical address which the page of `vaddr` maps to. - fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags)>; - - fn map_cont( - &mut self, - start_vaddr: VirtAddr, - size: usize, - start_paddr: PhysAddr, - flags: MMUFlags, - ) -> PagingResult { - assert!(is_aligned(start_vaddr.addr())); - assert!(is_aligned(start_vaddr.addr())); - assert!(is_aligned(size)); - let mut vaddr = start_vaddr; - let mut paddr = start_paddr; - let end_vaddr = vaddr.addr() + size; - while vaddr.addr() < end_vaddr { - let page = Page::new(vaddr); - self.map(page, paddr, flags)?; - vaddr.add_offset(PAGE_SIZE); - paddr.add_offset(PAGE_SIZE); - } - Ok(()) - } - - fn unmap_cont(&mut self, start_vaddr: VirtAddr, size: usize) -> PagingResult { - assert!(is_aligned(start_vaddr.addr())); - assert!(is_aligned(size)); - let mut vaddr = start_vaddr; - let end_vaddr = vaddr.addr() + size; - while vaddr.addr() < end_vaddr { - let page_size = match self.unmap(vaddr) { - Ok(s) => { - info!("unmap_cont: {:?}", s); - PAGE_SIZE - } - Err(PagingError::NotMapped) => PAGE_SIZE, - Err(e) => return Err(e), - }; - vaddr.add_offset(page_size as usize); - assert!(vaddr.addr() <= end_vaddr); - } - Ok(()) - } } -impl GenericPageTable for PageTable { - fn table_phys(&self) -> PhysAddr { - PhysAddr::new(0) - } - - fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) -> PagingResult { +impl PageTable { + pub fn map(&mut self, page: Page, paddr: PhysAddr, flags: MMUFlags) { debug_assert!(is_aligned(paddr.addr())); if paddr.addr() < PMEM_SIZE { MOCK_PHYS_MEM.mmap(page.vaddr, PAGE_SIZE, paddr, flags); - Ok(()) } else { - Err(PagingError::NoMemory) + error!("failed to map(no memory): paddr={:#x}, flags={:?}", paddr.addr(), flags); } } - fn unmap(&mut self, vaddr: VirtAddr) -> PagingResult { - self.unmap_cont(vaddr, PAGE_SIZE)?; - Ok(PhysAddr::new(0)) - } - - fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags)> { - debug_assert!(is_aligned(vaddr.addr())); - if (PMEM_MAP_VADDR.addr()..PMEM_MAP_VADDR.addr() + PMEM_SIZE).contains(&vaddr.addr()) { - Ok(( - PhysAddr::new(vaddr.addr() - PMEM_MAP_VADDR.addr()), - MMUFlags::READ | MMUFlags::WRITE, - )) - } else { - Err(PagingError::NotMapped) - } - } - - fn unmap_cont(&mut self, vaddr: VirtAddr, size: usize) -> PagingResult { - if size == 0 { - return Ok(()); - } - debug_assert!(is_aligned(vaddr.addr())); - MOCK_PHYS_MEM.munmap(vaddr as _, size); - Ok(()) + pub fn unmap(&mut self, vaddr: VirtAddr) { + MOCK_PHYS_MEM.munmap(vaddr as _, PAGE_SIZE); } } From ffa751e846c6e19371a837b4fdef41b760b23101 Mon Sep 17 00:00:00 2001 From: jackhu Date: Wed, 22 May 2024 07:24:49 -0700 Subject: [PATCH 16/26] refactor project dir --- src/bare/addr.rs | 2 +- src/bare/api.rs | 2 +- src/bare/arch/aarch64/gic.rs | 2 +- src/bare/arch/aarch64/mod.rs | 2 +- src/bare/arch/aarch64/page_table.rs | 2 +- src/bare/arch/aarch64/pl011.rs | 3 +- src/bare/arch/loongarch64/console.rs | 2 +- src/bare/arch/loongarch64/page_table.rs | 2 +- src/bare/arch/loongarch64/sigtrx.rs | 2 +- src/bare/arch/riscv64/entry.rs | 8 +-- src/bare/arch/riscv64/mod.rs | 2 +- src/bare/arch/riscv64/page_table/mod.rs | 2 +- src/bare/arch/riscv64/page_table/sv39.rs | 2 +- src/bare/arch/riscv64/sbi.rs | 2 +- src/bare/arch/x86_64/multiboot.rs | 2 +- src/bare/arch/x86_64/page_table.rs | 2 +- src/bare/arch/x86_64/uart.rs | 2 +- src/bare/mod.rs | 4 +- src/bare/pagetable.rs | 2 +- src/common/addr.rs | 80 ------------------------ src/common/mod.rs | 6 +- src/common/page.rs | 2 +- src/lib.rs | 10 +-- src/libos/addr.rs | 3 +- src/libos/debug.rs | 2 +- src/libos/mem.rs | 2 +- src/libos/mock_mem.rs | 2 +- src/libos/vm.rs | 2 +- 28 files changed, 37 insertions(+), 119 deletions(-) diff --git a/src/bare/addr.rs b/src/bare/addr.rs index 9491e45..332d64d 100644 --- a/src/bare/addr.rs +++ b/src/bare/addr.rs @@ -3,7 +3,7 @@ use core::{ mem::size_of, }; -use crate::{PhysAddr, PhysPage, VirtAddr}; +use crate::common::addr::{PhysAddr, PhysPage, VirtAddr}; use crate::{PageTable, VIRT_ADDR_START}; diff --git a/src/bare/api.rs b/src/bare/api.rs index 746f1fe..7d51a49 100644 --- a/src/bare/api.rs +++ b/src/bare/api.rs @@ -1,4 +1,4 @@ -use crate::PhysPage; +use crate::common::addr::PhysPage; use crate::{TrapFrame, TrapType, PAGE_ALLOC}; extern "Rust" { diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index b3ea0f3..d6c4cd9 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -2,7 +2,7 @@ use arm_gic::gic_v2::{GicCpuInterface, GicDistributor}; use arm_gic::{translate_irq, InterruptType}; use irq_safety::MutexIrqSafe; -use crate::PhysAddr; +use crate::addr::PhysAddr; /// The maximum number of IRQs. #[allow(dead_code)] diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index 5491bf0..987cca4 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -62,7 +62,7 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { } pub fn kernel_page_table() -> PageTable { - PageTable(crate::PhysAddr(TTBR0_EL1.get_baddr() as _)) + PageTable(crate::addr::PhysAddr(TTBR0_EL1.get_baddr() as _)) } #[inline] diff --git a/src/bare/arch/aarch64/page_table.rs b/src/bare/arch/aarch64/page_table.rs index 31e5c12..dabb89b 100644 --- a/src/bare/arch/aarch64/page_table.rs +++ b/src/bare/arch/aarch64/page_table.rs @@ -1,6 +1,6 @@ use aarch64_cpu::registers::{Writeable, TTBR0_EL1}; -use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::{MappingFlags, PageTable, PTE, TLB}; use crate::bit; diff --git a/src/bare/arch/aarch64/pl011.rs b/src/bare/arch/aarch64/pl011.rs index 726ed54..d527dab 100644 --- a/src/bare/arch/aarch64/pl011.rs +++ b/src/bare/arch/aarch64/pl011.rs @@ -3,7 +3,8 @@ use arm_pl011::pl011::Pl011Uart; use irq_safety::MutexIrqSafe; -use crate::{PhysAddr, DebugConsole}; +use crate::addr::PhysAddr; +use crate::debug::DebugConsole; const UART_BASE: PhysAddr = PhysAddr(0x0900_0000); diff --git a/src/bare/arch/loongarch64/console.rs b/src/bare/arch/loongarch64/console.rs index b397c40..700d3cf 100644 --- a/src/bare/arch/loongarch64/console.rs +++ b/src/bare/arch/loongarch64/console.rs @@ -1,6 +1,6 @@ use spin::Mutex; -use crate::{DebugConsole, VIRT_ADDR_START}; +use crate::{debug::DebugConsole, VIRT_ADDR_START}; #[cfg(not(board = "2k1000"))] const UART_ADDR: usize = 0x01FE001E0 | VIRT_ADDR_START; diff --git a/src/bare/arch/loongarch64/page_table.rs b/src/bare/arch/loongarch64/page_table.rs index 364e53f..9f8984f 100644 --- a/src/bare/arch/loongarch64/page_table.rs +++ b/src/bare/arch/loongarch64/page_table.rs @@ -1,6 +1,6 @@ use loongArch64::register::pgdl; -use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage, MappingFlags, PageTable, PTE, TLB}; +use crate::{addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}, MappingFlags, PageTable, PTE, TLB}; use super::sigtrx::get_trx_mapping; use crate::bit; diff --git a/src/bare/arch/loongarch64/sigtrx.rs b/src/bare/arch/loongarch64/sigtrx.rs index ee5ac72..2f90b22 100644 --- a/src/bare/arch/loongarch64/sigtrx.rs +++ b/src/bare/arch/loongarch64/sigtrx.rs @@ -26,7 +26,7 @@ static mut TRX_STEP: [[PTE; PageTable::PTE_NUM_IN_PAGE]; 2] = pub fn init() { unsafe { TRX_STEP[0][0] = PTE::from_addr( - crate::PhysAddr(_sigreturn as usize & !VIRT_ADDR_START), + crate::addr::PhysAddr(_sigreturn as usize & !VIRT_ADDR_START), MappingFlags::URX.into(), ); TRX_STEP[1][0] = PTE(TRX_STEP.as_ptr() as usize & !VIRT_ADDR_START); diff --git a/src/bare/arch/riscv64/entry.rs b/src/bare/arch/riscv64/entry.rs index bacd00e..91e6e37 100644 --- a/src/bare/arch/riscv64/entry.rs +++ b/src/bare/arch/riscv64/entry.rs @@ -1,9 +1,9 @@ use core::arch::riscv64::sfence_vma_all; -use crate::{PageTable, PTE}; -use crate::VIRT_ADDR_START; - use super::page_table::PTEFlags; +use crate::addr::PhysAddr; +use crate::VIRT_ADDR_START; +use crate::{PageTable, PTE}; #[link_section = ".data.prepage.entry"] pub(crate) static mut PAGE_TABLE: [PTE; PageTable::PTE_NUM_IN_PAGE] = { @@ -144,7 +144,7 @@ pub fn switch_to_kernel_page_table() { } pub fn kernel_page_table() -> PageTable { - PageTable(crate::PhysAddr(unsafe { + PageTable(PhysAddr(unsafe { PAGE_TABLE.as_ptr() as usize & !VIRT_ADDR_START })) } diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index c5db197..1876428 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -132,7 +132,7 @@ impl MultiCore { /// Boot all application cores. pub fn boot_all() { use self::entry::secondary_start; - use crate::{VirtPage, MappingFlags, MappingSize, PageTable}; + use crate::{addr::VirtPage, MappingFlags, MappingSize, PageTable}; let page_table = PageTable::current(); diff --git a/src/bare/arch/riscv64/page_table/mod.rs b/src/bare/arch/riscv64/page_table/mod.rs index aa1d389..61d7238 100644 --- a/src/bare/arch/riscv64/page_table/mod.rs +++ b/src/bare/arch/riscv64/page_table/mod.rs @@ -5,7 +5,7 @@ use core::arch::riscv64::sfence_vma; pub use sv39::*; -use crate::VirtAddr; +use crate::addr::VirtAddr; use crate::TLB; /// TLB operations diff --git a/src/bare/arch/riscv64/page_table/sv39.rs b/src/bare/arch/riscv64/page_table/sv39.rs index 6086917..c666b9b 100644 --- a/src/bare/arch/riscv64/page_table/sv39.rs +++ b/src/bare/arch/riscv64/page_table/sv39.rs @@ -1,7 +1,7 @@ use bitflags::bitflags; use riscv::register::satp; -use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::kernel_page_table; use crate::MappingFlags; use crate::{PageTable, PTE, TLB}; diff --git a/src/bare/arch/riscv64/sbi.rs b/src/bare/arch/riscv64/sbi.rs index 1e7ecd1..459a6d3 100644 --- a/src/bare/arch/riscv64/sbi.rs +++ b/src/bare/arch/riscv64/sbi.rs @@ -6,7 +6,7 @@ use core::arch::asm; use sbi_rt::{NoReason, Shutdown}; -use crate::DebugConsole; +use crate::debug::DebugConsole; const SBI_SET_TIMER: usize = 0; const SBI_CONSOLE_PUT_CHAR: usize = 1; diff --git a/src/bare/arch/x86_64/multiboot.rs b/src/bare/arch/x86_64/multiboot.rs index 5fcc155..c919c3a 100644 --- a/src/bare/arch/x86_64/multiboot.rs +++ b/src/bare/arch/x86_64/multiboot.rs @@ -78,7 +78,7 @@ pub fn kernel_page_table() -> PageTable { extern "C" { fn _kernel_page_table(); } - PageTable(crate::PhysAddr( + PageTable(crate::addr::PhysAddr( _kernel_page_table as usize - VIRT_ADDR_START, )) } diff --git a/src/bare/arch/x86_64/page_table.rs b/src/bare/arch/x86_64/page_table.rs index aedcc51..4f1f825 100644 --- a/src/bare/arch/x86_64/page_table.rs +++ b/src/bare/arch/x86_64/page_table.rs @@ -3,7 +3,7 @@ use bitflags::bitflags; use x86::tlb; use x86_64::registers::control::Cr3; -use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use crate::imp::current_arch::VIRT_ADDR_START; use crate::{MappingFlags, PageTable, PTE, TLB}; use crate::bit; diff --git a/src/bare/arch/x86_64/uart.rs b/src/bare/arch/x86_64/uart.rs index fdea46d..2e85841 100644 --- a/src/bare/arch/x86_64/uart.rs +++ b/src/bare/arch/x86_64/uart.rs @@ -3,7 +3,7 @@ use irq_safety::MutexIrqSafe; use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly}; -use crate::DebugConsole; +use crate::debug::DebugConsole; const UART_CLOCK_FACTOR: usize = 16; const OSC_FREQ: usize = 1_843_200; diff --git a/src/bare/mod.rs b/src/bare/mod.rs index 0339f0b..585210f 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -149,7 +149,7 @@ pub mod irq; pub mod mem; pub mod time; pub mod pagetable; -pub mod addr; +mod addr; pub mod api; pub mod consts; pub mod multicore; @@ -164,7 +164,7 @@ use alloc::vec::Vec; /// Trap Frame use crate::STACK_SIZE; -use crate::PageAlloc; +use crate::common::page::PageAlloc; pub const PAGE_SIZE: usize = crate::PageTable::PAGE_SIZE; pub const USER_VADDR_END: usize = crate::PageTable::USER_VADDR_END; diff --git a/src/bare/pagetable.rs b/src/bare/pagetable.rs index 2f1489e..73a0485 100644 --- a/src/bare/pagetable.rs +++ b/src/bare/pagetable.rs @@ -1,6 +1,6 @@ use core::ops::Deref; -use crate::{PhysAddr, PhysPage, VirtAddr, VirtPage}; +use crate::common::addr::{VirtAddr, VirtPage, PhysAddr, PhysPage}; use crate::{frame_alloc, frame_dealloc}; use bitflags::bitflags; use crate::bit; diff --git a/src/common/addr.rs b/src/common/addr.rs index c8d883e..45075ab 100644 --- a/src/common/addr.rs +++ b/src/common/addr.rs @@ -18,31 +18,6 @@ impl PhysAddr { pub fn addr(&self) -> usize { self.0 } - - // #[inline] - // pub fn get_ptr(&self) -> *const T { - // (self.0 | VIRT_ADDR_START) as *const T - // } - - // #[inline] - // pub const fn get_mut_ptr(&self) -> *mut T { - // (self.0 | VIRT_ADDR_START) as *mut T - // } - - // #[inline] - // pub fn slice_with_len(&self, len: usize) -> &'static [T] { - // unsafe { core::slice::from_raw_parts(self.get_ptr(), len) } - // } - - // #[inline] - // pub fn slice_mut_with_len(&self, len: usize) -> &'static mut [T] { - // unsafe { core::slice::from_raw_parts_mut(self.get_mut_ptr(), len) } - // } - - // #[inline] - // pub fn get_cstr(&self) -> &CStr { - // unsafe { CStr::from_ptr(self.get_ptr::()) } - // } } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -117,16 +92,6 @@ impl VirtAddr { pub fn get_cstr(&self) -> &CStr { unsafe { CStr::from_ptr(self.get_ptr::()) } } - - // #[inline] - // pub fn floor(&self) -> Self { - // Self(self.0 / PageTable::PAGE_SIZE * PageTable::PAGE_SIZE) - // } - - // #[inline] - // pub fn ceil(&self) -> Self { - // Self((self.0 + PageTable::PAGE_SIZE - 1) / PageTable::PAGE_SIZE * PageTable::PAGE_SIZE) - // } } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -195,51 +160,6 @@ impl PhysPage { self.0 << 12 } - // #[inline] - // pub const fn get_buffer(&self) -> &'static mut [u8] { - // unsafe { - // core::slice::from_raw_parts_mut( - // (self.0 << 12 | VIRT_ADDR_START) as *mut u8, - // PageTable::PAGE_SIZE, - // ) - // } - // } - - // #[inline] - // pub fn copy_value_from_another(&self, ppn: PhysPage) { - // self.get_buffer().copy_from_slice(&ppn.get_buffer()); - // #[cfg(c906)] - // unsafe { - // asm!(".long 0x0010000b"); // dcache.all - // asm!(".long 0x01b0000b"); // sync.is - // } - // #[cfg(board = "2k1000")] - // unsafe { - // core::arch::asm!("dbar 0;ibar 0;") - // } - // } - - // #[inline] - // pub fn drop_clear(&self) { - // // self.get_buffer().fill(0); - // unsafe { - // core::slice::from_raw_parts_mut( - // (self.0 << 12 | VIRT_ADDR_START) as *mut usize, - // PageTable::PAGE_SIZE / size_of::(), - // ) - // .fill(0); - // } - // #[cfg(board = "2k1000")] - // unsafe { - // core::arch::asm!("dbar 0;ibar 0;") - // } - // #[cfg(c906)] - // unsafe { - // asm!(".long 0x0010000b"); // dcache.all - // asm!(".long 0x01b0000b"); // sync.is - // } - // } - #[inline] pub fn as_num(&self) -> usize { self.0 diff --git a/src/common/mod.rs b/src/common/mod.rs index c26bb90..1286eac 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,3 +1,3 @@ -pub(crate) mod addr; -pub(crate) mod page; -pub(crate) mod debug; \ No newline at end of file +pub mod addr; +pub mod page; +pub mod debug; \ No newline at end of file diff --git a/src/common/page.rs b/src/common/page.rs index 6cbe6ab..7a480d1 100644 --- a/src/common/page.rs +++ b/src/common/page.rs @@ -1,4 +1,4 @@ -use crate::PhysPage; +use crate::common::addr::PhysPage; pub trait PageAlloc: Sync { fn alloc(&self) -> PhysPage; diff --git a/src/lib.rs b/src/lib.rs index 046b603..e7b71ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,7 @@ extern crate cfg_if; mod utils; mod common; -pub use common::addr::*; -pub use common::debug::DebugConsole; -pub use common::page::PageAlloc; +pub use common::{page::PageAlloc, *}; cfg_if! { if #[cfg(feature = "libos")] { @@ -42,13 +40,11 @@ cfg_if! { use imp::pagetable::*; use imp::consts::*; use imp::multicore::MultiCore; - use imp::*; use imp::current_arch::*; + pub use imp::{ - pagetable::{PageTable, PageTableWrapper, MappingFlags, MappingSize} - }; - pub use imp::{ + *, get_mem_areas, init, TrapFrameArgs, TrapType, PAGE_SIZE, time::*, diff --git a/src/libos/addr.rs b/src/libos/addr.rs index c120b97..e36b49f 100644 --- a/src/libos/addr.rs +++ b/src/libos/addr.rs @@ -1,5 +1,6 @@ use bitflags::bitflags; -use crate::{bit, PhysAddr, VirtAddr}; +use crate::addr::{PhysAddr, VirtAddr}; +use crate::bit; use crate::common::addr::PhysPage; pub const PAGE_SIZE: usize = 0x1000; diff --git a/src/libos/debug.rs b/src/libos/debug.rs index 6919e6b..1317615 100644 --- a/src/libos/debug.rs +++ b/src/libos/debug.rs @@ -1,4 +1,4 @@ -use crate::DebugConsole; +use crate::debug::DebugConsole; impl DebugConsole { pub fn putchar(c: u8) { diff --git a/src/libos/mem.rs b/src/libos/mem.rs index f8bb553..62ca6cf 100644 --- a/src/libos/mem.rs +++ b/src/libos/mem.rs @@ -5,7 +5,7 @@ use core::ops::Range; use crate::utils::once::LazyInit; use super::mock_mem::MockMemory; -use crate::{PhysAddr, VirtAddr, PAGE_SIZE}; +use crate::{addr::{PhysAddr, VirtAddr}, PAGE_SIZE}; /// Map physical memory from here. pub(super) const PMEM_MAP_VADDR: VirtAddr = VirtAddr::new(0x8_0000_0000); diff --git a/src/libos/mock_mem.rs b/src/libos/mock_mem.rs index 21dff59..7a1311d 100644 --- a/src/libos/mock_mem.rs +++ b/src/libos/mock_mem.rs @@ -5,7 +5,7 @@ use nix::sys::mman::{self, MapFlags, ProtFlags}; use nix::{sys::stat::Mode, unistd}; use super::mem::PMEM_MAP_VADDR; -use crate::{MMUFlags, PhysAddr, VirtAddr}; +use crate::{MMUFlags, addr::{PhysAddr, VirtAddr}}; pub struct MockMemory { size: usize, diff --git a/src/libos/vm.rs b/src/libos/vm.rs index c93be2f..44e74e2 100644 --- a/src/libos/vm.rs +++ b/src/libos/vm.rs @@ -1,5 +1,5 @@ use super::mem::{MOCK_PHYS_MEM, PMEM_SIZE}; -use crate::{is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE}; +use crate::{is_aligned, MMUFlags, addr::{PhysAddr, VirtAddr}, PAGE_SIZE}; #[derive(Debug, Copy, Clone)] pub struct Page { From e8c7600e448cb089adf5aaab0e5210df72780e6b Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 27 May 2024 17:30:03 -0700 Subject: [PATCH 17/26] support ctx_switch of x86 64 --- src/bare/arch/x86_64/kcontext.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/bare/arch/x86_64/kcontext.rs b/src/bare/arch/x86_64/kcontext.rs index c3f0afc..3121a38 100644 --- a/src/bare/arch/x86_64/kcontext.rs +++ b/src/bare/arch/x86_64/kcontext.rs @@ -107,11 +107,36 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext core::arch::asm!( // Save Kernel Context. " - + pop r8 + mov [rdi + 0 * 8], rsp + mov [rdi + 2 * 8], rbx + mov [rdi + 3 * 8], rbp + mov [rdi + 4 * 8], r12 + mov [rdi + 5 * 8], r13 + mov [rdi + 6 * 8], r14 + mov [rdi + 7 * 8], r15 + mov [rdi + 8 * 8], r8 # save old rip to stack + + mov ecx, 0xC0000100 + rdmsr + mov [rdi + 1*8], eax # push fabase + mov [rdi + 1*8+4], edx ", // Restore Kernel Context. " - + mov ecx, 0xC0000100 + mov eax, [rsi + 1*8] + mov edx, [rsi + 1*8+4] + wrmsr # pop fsbase + mov rsp, [rsi + 0 * 8] + mov rbx, [rsi + 2 * 8] + mov rbp, [rsi + 3 * 8] + mov r12, [rsi + 4 * 8] + mov r13, [rsi + 5 * 8] + mov r14, [rsi + 6 * 8] + mov r15, [rsi + 7 * 8] + mov r8, [rsi + 8 * 8] + push r8 ret ", options(noreturn) From ae9fff231ffdb0cb0a7af925545d0d754f7b782c Mon Sep 17 00:00:00 2001 From: jackhu Date: Tue, 28 May 2024 11:34:08 -0700 Subject: [PATCH 18/26] open debug --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6337cb5..0bdb26a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,3 +52,6 @@ arm_gic = { git = "https://github.com/Byte-OS/arm_gic" } [target.'cfg(target_arch = "loongarch64")'.dependencies] spin = { version = "0.9.8", features = ["mutex"] } loongArch64 = "0.2.2" + +[profile.release] +debug = true \ No newline at end of file From 0153a755b333628d727e1b8c45b3d44751258ee5 Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 21:59:42 -0700 Subject: [PATCH 19/26] feat: add loongarch fetchpagefault --- src/bare/arch/loongarch64/trap.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bare/arch/loongarch64/trap.rs b/src/bare/arch/loongarch64/trap.rs index 3d8c6ba..571f4c7 100644 --- a/src/bare/arch/loongarch64/trap.rs +++ b/src/bare/arch/loongarch64/trap.rs @@ -349,7 +349,8 @@ fn loongarch64_trap_handler(tf: &mut TrapFrame) -> TrapType { // TrapType::Un TrapType::StorePageFault(badv::read().vaddr()) } - Trap::Exception(Exception::LoadPageFault) => TrapType::LoadPageFault(badv::read().vaddr()), + Trap::Exception(Exception::FetchPageFault) + | Trap::Exception(Exception::LoadPageFault) => TrapType::LoadPageFault(badv::read().vaddr()), _ => { panic!( "Unhandled trap {:?} @ {:#x} BADV: {:#x}:\n{:#x?}", From 82aeb0fbdac5cda7385412b390877e6ca5081888 Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 22:04:42 -0700 Subject: [PATCH 20/26] feat: add irq support for aarch64 and x86_64 --- src/bare/arch/aarch64/gic.rs | 25 +++++++++++++------ src/bare/arch/aarch64/timer.rs | 5 ++-- src/bare/arch/loongarch64/timer.rs | 16 ++++++++++++ src/bare/arch/loongarch64/trap.rs | 5 ++-- src/bare/arch/riscv64/irq.rs | 16 ++++++++++++ src/bare/arch/riscv64/mod.rs | 1 + src/bare/arch/x86_64/apic.rs | 40 +++++++++++++++++++----------- 7 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 src/bare/arch/riscv64/irq.rs diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index d6c4cd9..abc1a84 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -1,9 +1,9 @@ +use crate::addr::PhysAddr; +use crate::irq::IRQ; use arm_gic::gic_v2::{GicCpuInterface, GicDistributor}; use arm_gic::{translate_irq, InterruptType}; use irq_safety::MutexIrqSafe; -use crate::addr::PhysAddr; - /// The maximum number of IRQs. #[allow(dead_code)] pub const MAX_IRQ_COUNT: usize = 1024; @@ -24,12 +24,6 @@ static GICD: MutexIrqSafe = // per-CPU, no lock static GICC: GicCpuInterface = GicCpuInterface::new(GICC_BASE.get_mut_ptr()); -/// Enables or disables the given IRQ. -pub fn set_enable(irq_num: usize, enabled: bool) { - trace!("GICD set enable: {} {}", irq_num, enabled); - GICD.lock().set_enable(irq_num as _, enabled); -} - /// Initializes GICD, GICC on the primary CPU. pub(crate) fn init() { info!("Initialize GICv2..."); @@ -44,3 +38,18 @@ where { GICC.handle_irq(f) } + +/// Implement IRQ operations for the IRQ interface. +impl IRQ { + /// Enable irq for the given IRQ number. + #[inline] + pub fn enable(irq_num: usize) { + GICD.lock().set_enable(irq_num, true); + } + + /// Disable irq for the given IRQ number. + #[inline] + pub fn disable(irq_num: usize) { + GICD.lock().set_enable(irq_num, false); + } +} \ No newline at end of file diff --git a/src/bare/arch/aarch64/timer.rs b/src/bare/arch/aarch64/timer.rs index 6cc1837..f6c07f5 100644 --- a/src/bare/arch/aarch64/timer.rs +++ b/src/bare/arch/aarch64/timer.rs @@ -3,7 +3,7 @@ use aarch64_cpu::registers::{CNTFRQ_EL0, CNTPCT_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0}; use tock_registers::interfaces::{Readable, Writeable}; -use crate::time::Time; +use crate::{irq::IRQ, time::Time}; impl Time { #[inline] @@ -27,6 +27,7 @@ pub fn init() { debug!("freq: {}", freq); CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET); CNTP_TVAL_EL0.set(0); - super::gic::set_enable(super::gic::TIMER_IRQ_NUM, true); + // Enable the timer irq. + IRQ::enable(super::gic::TIMER_IRQ_NUM); set_next_timer(); } diff --git a/src/bare/arch/loongarch64/timer.rs b/src/bare/arch/loongarch64/timer.rs index 536f34c..6167782 100644 --- a/src/bare/arch/loongarch64/timer.rs +++ b/src/bare/arch/loongarch64/timer.rs @@ -3,6 +3,7 @@ use loongArch64::register::tcfg; /// Returns the current clock time in hardware ticks. use loongArch64::time::{get_timer_freq, Time}; use spin::Lazy; +use crate::irq::IRQ; // static mut FREQ: usize = 0; static FREQ: Lazy = Lazy::new(|| get_timer_freq()); @@ -32,3 +33,18 @@ pub fn init_timer() { | LineBasedInterrupt::HWI0; ecfg::set_lie(inter); } + +/// Implement IRQ operations for the IRQ interface. +impl IRQ { + /// Enable irq for the given IRQ number. + #[inline] + pub fn enable(_irq_num: usize) { + log::warn!("irq not implemented in loongarch64 platform yet"); + } + + /// Disable irq for the given IRQ number. + #[inline] + pub fn disable(_irq_num: usize) { + log::warn!("irq not implemented in loongarch64 platform yet"); + } +} \ No newline at end of file diff --git a/src/bare/arch/loongarch64/trap.rs b/src/bare/arch/loongarch64/trap.rs index 571f4c7..fdf9772 100644 --- a/src/bare/arch/loongarch64/trap.rs +++ b/src/bare/arch/loongarch64/trap.rs @@ -349,8 +349,9 @@ fn loongarch64_trap_handler(tf: &mut TrapFrame) -> TrapType { // TrapType::Un TrapType::StorePageFault(badv::read().vaddr()) } - Trap::Exception(Exception::FetchPageFault) - | Trap::Exception(Exception::LoadPageFault) => TrapType::LoadPageFault(badv::read().vaddr()), + Trap::Exception(Exception::FetchPageFault) | Trap::Exception(Exception::LoadPageFault) => { + TrapType::LoadPageFault(badv::read().vaddr()) + } _ => { panic!( "Unhandled trap {:?} @ {:#x} BADV: {:#x}:\n{:#x?}", diff --git a/src/bare/arch/riscv64/irq.rs b/src/bare/arch/riscv64/irq.rs new file mode 100644 index 0000000..71b114c --- /dev/null +++ b/src/bare/arch/riscv64/irq.rs @@ -0,0 +1,16 @@ +use crate::irq::IRQ; + +/// Implement IRQ operations for the IRQ interface. +impl IRQ { + /// Enable irq for the given IRQ number. + #[inline] + pub fn enable(_irq_num: usize) { + log::warn!("irq not implemented in riscv platform yet"); + } + + /// Disable irq for the given IRQ number. + #[inline] + pub fn disable(_irq_num: usize) { + log::warn!("irq not implemented in riscv platform yet"); + } +} \ No newline at end of file diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index 1876428..9d08a01 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -9,6 +9,7 @@ mod kcontext; mod page_table; mod sbi; mod timer; +mod irq; use core::slice; diff --git a/src/bare/arch/x86_64/apic.rs b/src/bare/arch/x86_64/apic.rs index 7376d38..f228d36 100644 --- a/src/bare/arch/x86_64/apic.rs +++ b/src/bare/arch/x86_64/apic.rs @@ -5,6 +5,7 @@ use spin::Once; use x2apic::ioapic::IoApic; use x2apic::lapic::{xapic_base, LocalApic, LocalApicBuilder}; use x86_64::instructions::port::Port; +use crate::irq::IRQ; use self::vectors::*; use crate::imp::current_arch::VIRT_ADDR_START; @@ -27,20 +28,6 @@ static mut LOCAL_APIC: Option = None; static mut IS_X2APIC: bool = false; static IO_APIC: Once> = Once::new(); -/// Enables or disables the given IRQ. -pub fn set_enable(vector: usize, enabled: bool) { - // should not affect LAPIC interrupts - if vector < APIC_TIMER_VECTOR as _ { - unsafe { - if enabled { - IO_APIC.get_unchecked().lock().enable_irq(vector as u8); - } else { - IO_APIC.get_unchecked().lock().disable_irq(vector as u8); - } - } - } -} - /// Registers an IRQ handler for the given IRQ. /// /// It also enables the IRQ if the registration succeeds. It returns `false` if @@ -112,3 +99,28 @@ pub(super) fn init() { let io_apic = unsafe { IoApic::new(IO_APIC_BASE) }; IO_APIC.call_once(|| MutexIrqSafe::new(io_apic)); } + +/// Implement IRQ operations for the IRQ interface. +impl IRQ { + /// Enable irq for the given IRQ number. + #[inline] + pub fn enable(irq_num: usize) { + // should not affect LAPIC interrupts + if irq_num < APIC_TIMER_VECTOR as _ { + unsafe { + IO_APIC.get_unchecked().lock().enable_irq(irq_num as _); + } + } + } + + /// Disable irq for the given IRQ number. + #[inline] + pub fn disable(irq_num: usize) { + // should not affect LAPIC interrupts + if irq_num < APIC_TIMER_VECTOR as _ { + unsafe { + IO_APIC.get_unchecked().lock().disable_irq(irq_num as _); + } + } + } +} \ No newline at end of file From 00745ba656378d750cb0a0e585734c82f913ff87 Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 22:07:46 -0700 Subject: [PATCH 21/26] feat: support irq and int --- src/bare/arch/aarch64/gic.rs | 25 ++++++++++++++++++++++--- src/bare/arch/aarch64/timer.rs | 2 +- src/bare/arch/loongarch64/timer.rs | 23 +++++++++++++++++++++-- src/bare/arch/riscv64/irq.rs | 23 +++++++++++++++++++++-- src/bare/irq.rs | 20 +++++++++++++++++--- 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index abc1a84..1e1cec7 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -1,3 +1,5 @@ +use aarch64_cpu::registers::{Readable, Writeable, DAIF}; +use tock_registers::interfaces::ReadWriteable; use crate::addr::PhysAddr; use crate::irq::IRQ; use arm_gic::gic_v2::{GicCpuInterface, GicDistributor}; @@ -39,17 +41,34 @@ where GICC.handle_irq(f) } -/// Implement IRQ operations for the IRQ interface. impl IRQ { /// Enable irq for the given IRQ number. #[inline] - pub fn enable(irq_num: usize) { + pub fn irq_enable(irq_num: usize) { GICD.lock().set_enable(irq_num, true); } /// Disable irq for the given IRQ number. #[inline] - pub fn disable(irq_num: usize) { + pub fn irq_disable(irq_num: usize) { GICD.lock().set_enable(irq_num, false); } + + /// Enable interrupt. + #[inline] + pub fn int_enable() { + DAIF.modify(DAIF::I::Unmasked); + } + + /// Disable interrupt. + #[inline] + pub fn int_disable() { + DAIF.modify(DAIF::I::Masked); + } + + /// Check if the interrupt was enabled. + #[inline] + pub fn int_enabled() -> bool { + DAIF.read(DAIF::I) == 0 + } } \ No newline at end of file diff --git a/src/bare/arch/aarch64/timer.rs b/src/bare/arch/aarch64/timer.rs index f6c07f5..5bad27a 100644 --- a/src/bare/arch/aarch64/timer.rs +++ b/src/bare/arch/aarch64/timer.rs @@ -28,6 +28,6 @@ pub fn init() { CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET); CNTP_TVAL_EL0.set(0); // Enable the timer irq. - IRQ::enable(super::gic::TIMER_IRQ_NUM); + IRQ::irq_enable(super::gic::TIMER_IRQ_NUM); set_next_timer(); } diff --git a/src/bare/arch/loongarch64/timer.rs b/src/bare/arch/loongarch64/timer.rs index 6167782..fec861f 100644 --- a/src/bare/arch/loongarch64/timer.rs +++ b/src/bare/arch/loongarch64/timer.rs @@ -38,13 +38,32 @@ pub fn init_timer() { impl IRQ { /// Enable irq for the given IRQ number. #[inline] - pub fn enable(_irq_num: usize) { + pub fn irq_enable(_irq_num: usize) { log::warn!("irq not implemented in loongarch64 platform yet"); } /// Disable irq for the given IRQ number. #[inline] - pub fn disable(_irq_num: usize) { + pub fn irq_disable(_irq_num: usize) { log::warn!("irq not implemented in loongarch64 platform yet"); } + + /// Enable interrupt + #[inline] + pub fn int_enable() { + log::warn!("int_enable not implemented in loongarch64 platform yet"); + } + + /// Disable interrupt + #[inline] + pub fn int_disable() { + log::warn!("int_disable not implemented in loongarch64 platform yet"); + } + + /// Check if the interrupt was enabled. + #[inline] + pub fn int_enabled() -> bool { + log::warn!("int_enabled not implemented in loongarch64 platform yet"); + false + } } \ No newline at end of file diff --git a/src/bare/arch/riscv64/irq.rs b/src/bare/arch/riscv64/irq.rs index 71b114c..9e1b03d 100644 --- a/src/bare/arch/riscv64/irq.rs +++ b/src/bare/arch/riscv64/irq.rs @@ -1,16 +1,35 @@ +use riscv::register::sstatus::{self, clear_sie, set_sie}; use crate::irq::IRQ; /// Implement IRQ operations for the IRQ interface. impl IRQ { /// Enable irq for the given IRQ number. #[inline] - pub fn enable(_irq_num: usize) { + pub fn irq_enable(_irq_num: usize) { log::warn!("irq not implemented in riscv platform yet"); } /// Disable irq for the given IRQ number. #[inline] - pub fn disable(_irq_num: usize) { + pub fn irq_disable(_irq_num: usize) { log::warn!("irq not implemented in riscv platform yet"); } + + /// Enable interrupts. + #[inline] + pub fn int_enable() { + unsafe { set_sie() } + } + + /// Disable interrupts. + #[inline] + pub fn int_disable() { + unsafe { clear_sie() } + } + + /// Check if the interrupts was enabled. + #[inline] + pub fn int_enabled() -> bool { + sstatus::read().sie() + } } \ No newline at end of file diff --git a/src/bare/irq.rs b/src/bare/irq.rs index 4d9e0db..643c0e9 100644 --- a/src/bare/irq.rs +++ b/src/bare/irq.rs @@ -7,16 +7,30 @@ /// // Init irq /// IRQ::init(); /// +/// [IRQ::irq_enable] /// // Enable irq 3 -/// IRQ::enable(3); +/// IRQ::irq_enable(3); /// +/// [IRQ::irq_disable] /// // Disable irq 3 -/// IRQ::disable(3); +/// IRQ::irq_disable(3); /// +/// [IRQ::irq_enabled] /// // Check if irq is enabled /// // Return true if the irq is enabled. -/// IRQ::enabled(3); +/// IRQ::irq_enabled(3); /// +/// [IRQ::int_enable] +/// // Enable interrupt +/// IRQ::int_enable(); +/// +/// [IRQ::int_disable] +/// // Disable interrupt +/// IRQ::int_disable(); +/// +/// [IRQ::int_enabled] +/// // Check if interrupt is enabled +/// let enabled = IRQ::int_enabled(); /// ``` pub struct IRQ; From d7b4e30190436cf2f1a014e2409f0e546f3e673b Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 22:20:28 -0700 Subject: [PATCH 22/26] feat: support irq and int ops --- src/bare/arch/aarch64/context.rs | 8 +++++- src/bare/arch/aarch64/gic.rs | 32 +++++++++++++++------ src/bare/arch/aarch64/trap.S | 2 +- src/bare/arch/aarch64/trap.rs | 23 +++++++++++---- src/bare/arch/riscv64/context.rs | 8 +++++- src/bare/arch/riscv64/irq.rs | 19 +++++++++++-- src/bare/arch/riscv64/mod.rs | 14 +++++---- src/bare/arch/x86_64/context.rs | 3 +- src/bare/arch/x86_64/irq.rs | 49 ++++++++++++++++++++++++++++++++ src/bare/arch/x86_64/mod.rs | 1 + src/bare/irq.rs | 3 ++ src/bare/mod.rs | 26 ++++++++--------- src/lib.rs | 2 +- 13 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 src/bare/arch/x86_64/irq.rs diff --git a/src/bare/arch/aarch64/context.rs b/src/bare/arch/aarch64/context.rs index 94b89cc..80d3385 100644 --- a/src/bare/arch/aarch64/context.rs +++ b/src/bare/arch/aarch64/context.rs @@ -34,6 +34,12 @@ impl TrapFrame { ] } + /// Check if the trapframe was from user. + #[inline] + pub fn from_user(&self) -> bool { + (self.spsr >> 2) & 0x3 == 0 + } + #[inline] pub fn syscall_ok(&mut self) {} } @@ -70,4 +76,4 @@ impl IndexMut for TrapFrame { TrapFrameArgs::SYSCALL => &mut self.regs[8], } } -} +} \ No newline at end of file diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index 1e1cec7..d0c6a75 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -1,7 +1,7 @@ -use aarch64_cpu::registers::{Readable, Writeable, DAIF}; +use aarch64_cpu::registers::{Readable, DAIF}; use tock_registers::interfaces::ReadWriteable; use crate::addr::PhysAddr; -use crate::irq::IRQ; +use crate::irq::{IRQVector, IRQ}; use arm_gic::gic_v2::{GicCpuInterface, GicDistributor}; use arm_gic::{translate_irq, InterruptType}; use irq_safety::MutexIrqSafe; @@ -33,12 +33,23 @@ pub(crate) fn init() { GICC.init(); } +/// Implmente the irq vector methods +impl IRQVector { + /// Get the irq number in this vector + #[inline] + pub const fn irq_num(&self) -> usize { + self.0 & 0x3ff + } + + /// Acknowledge the irq + pub fn ack(&self) { + GICC.eoi(self.0 as u32); + } +} + #[inline] -pub fn handle_irq(f: F) -where - F: FnOnce(u32), -{ - GICC.handle_irq(f) +pub fn get_irq() -> IRQVector { + IRQVector(GICC.iar() as _) } impl IRQ { @@ -46,6 +57,7 @@ impl IRQ { #[inline] pub fn irq_enable(irq_num: usize) { GICD.lock().set_enable(irq_num, true); + // GICD.lock().configure_interrupt(irq_num, arm_gic::TriggerMode::Level); } /// Disable irq for the given IRQ number. @@ -57,13 +69,15 @@ impl IRQ { /// Enable interrupt. #[inline] pub fn int_enable() { - DAIF.modify(DAIF::I::Unmasked); + unsafe { core::arch::asm!("msr daifclr, #2") }; + // DAIF.modify(DAIF::I::Unmasked); } /// Disable interrupt. #[inline] pub fn int_disable() { - DAIF.modify(DAIF::I::Masked); + unsafe { core::arch::asm!("msr daifset, #2") }; + // DAIF.modify(DAIF::I::Masked); } /// Check if the interrupt was enabled. diff --git a/src/bare/arch/aarch64/trap.S b/src/bare/arch/aarch64/trap.S index 82b66df..0dec969 100644 --- a/src/bare/arch/aarch64/trap.S +++ b/src/bare/arch/aarch64/trap.S @@ -35,7 +35,7 @@ .macro USER_TRAP, kind .p2align 7 - msr daifset, #2 + msr daifset, #2 str x1, [sp, 17 * 8] ldr x1, [sp, 16 * 8] diff --git a/src/bare/arch/aarch64/trap.rs b/src/bare/arch/aarch64/trap.rs index 4aa5244..af50683 100644 --- a/src/bare/arch/aarch64/trap.rs +++ b/src/bare/arch/aarch64/trap.rs @@ -1,15 +1,16 @@ use core::arch::{asm, global_asm}; -use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, VBAR_EL1}; +use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, SCTLR_EL2::I, VBAR_EL1}; use tock_registers::interfaces::Readable; use crate::{ - current_arch::{gic::handle_irq, timer::set_next_timer}, + currrent_arch::{gic::TIMER_IRQ_NUM, timer::set_next_timer}, instruction::Instruction, + irq::IRQVector, TrapType, }; -use super::TrapFrame; +use super::{gic::get_irq, TrapFrame}; global_asm!(include_str!("trap.S")); @@ -36,9 +37,19 @@ enum TrapSource { #[no_mangle] fn handle_exception(tf: &mut TrapFrame, kind: TrapKind, source: TrapSource) -> TrapType { if kind == TrapKind::Irq { - set_next_timer(); - handle_irq(|_irq| {}); - return TrapType::Time; + let irq = get_irq(); + let trap_type = match irq.irq_num() { + TIMER_IRQ_NUM => { + irq.ack(); + set_next_timer(); + TrapType::Time + } + _ => { + TrapType::Irq(irq) + } + }; + unsafe { crate::api::_interrupt_for_arch(tf, trap_type) }; + return trap_type; } if kind != TrapKind::Synchronous { panic!( diff --git a/src/bare/arch/riscv64/context.rs b/src/bare/arch/riscv64/context.rs index 1474f9e..69ab738 100644 --- a/src/bare/arch/riscv64/context.rs +++ b/src/bare/arch/riscv64/context.rs @@ -3,7 +3,7 @@ use core::{ ops::{Index, IndexMut}, }; -use riscv::register::sstatus::{self, Sstatus}; +use riscv::register::sstatus::{self, Sstatus, SPP}; use crate::TrapFrameArgs; @@ -75,6 +75,12 @@ impl TrapFrame { self.x[10..16].try_into().expect("args slice force convert") } + /// Check if the trapframe was from user. + #[inline] + pub fn from_user(&self) -> bool { + self.sstatus.spp() == SPP::User + } + #[inline] pub fn syscall_ok(&mut self) { self.sepc += 4; diff --git a/src/bare/arch/riscv64/irq.rs b/src/bare/arch/riscv64/irq.rs index 9e1b03d..95254e9 100644 --- a/src/bare/arch/riscv64/irq.rs +++ b/src/bare/arch/riscv64/irq.rs @@ -1,5 +1,5 @@ +use crate::irq::{IRQVector, IRQ}; use riscv::register::sstatus::{self, clear_sie, set_sie}; -use crate::irq::IRQ; /// Implement IRQ operations for the IRQ interface. impl IRQ { @@ -32,4 +32,19 @@ impl IRQ { pub fn int_enabled() -> bool { sstatus::read().sie() } -} \ No newline at end of file +} + +/// Implmente the irq vector methods +impl IRQVector { + /// Get the irq number in this vector + #[inline] + pub fn irq_num(&self) -> usize { + log::warn!("ack not implemented in riscv platform yet"); + self.0 + } + + /// Acknowledge the irq + pub fn ack(&self) { + log::warn!("ack not implemented in riscv platform yet"); + } +} diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index 9d08a01..aa12cfe 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -4,22 +4,22 @@ mod consts; mod context; mod entry; mod interrupt; +mod irq; #[cfg(feature = "kcontext")] mod kcontext; mod page_table; mod sbi; mod timer; -mod irq; use core::slice; use alloc::vec::Vec; +pub use boards::*; pub use consts::*; pub use context::TrapFrame; pub use entry::kernel_page_table; use fdt::Fdt; pub use interrupt::run_user_task; -pub use boards::*; use sbi::*; pub use sbi::shutdown; @@ -27,10 +27,10 @@ pub use sbi::shutdown; #[cfg(feature = "kcontext")] pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext}; -use riscv::register::sstatus; +use riscv::register::{sie, sstatus}; -use crate::{frame_alloc, MultiCore, utils::once::LazyInit}; use super::{CPU_NUM, DTB_BIN, MEM_AREA}; +use crate::{frame_alloc, utils::once::LazyInit, MultiCore}; #[percpu::def_percpu] static CPU_ID: usize = 0; @@ -52,6 +52,8 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { unsafe { // 开启浮点运算 sstatus::set_fs(sstatus::FS::Dirty); + sie::set_sext(); + sie::set_ssoft(); } CPU_NUM.init_by(match unsafe { Fdt::from_ptr(device_tree as *const u8) } { @@ -76,6 +78,8 @@ pub(crate) extern "C" fn rust_secondary_main(hartid: usize) { unsafe { // 开启浮点运算 sstatus::set_fs(sstatus::FS::Dirty); + sie::set_sext(); + sie::set_ssoft(); } info!("secondary hart {} started", hartid); @@ -166,4 +170,4 @@ impl MultiCore { } }); } -} \ No newline at end of file +} diff --git a/src/bare/arch/x86_64/context.rs b/src/bare/arch/x86_64/context.rs index 050f39f..cc4fd1a 100644 --- a/src/bare/arch/x86_64/context.rs +++ b/src/bare/arch/x86_64/context.rs @@ -122,8 +122,9 @@ impl TrapFrame { // self.sepc += 4; } + /// Check if the trapframe was from user. #[inline] - pub fn is_user(&self) -> bool { + pub fn from_user(&self) -> bool { self.cs == GdtStruct::UCODE64_SELECTOR.0 as _ } } diff --git a/src/bare/arch/x86_64/irq.rs b/src/bare/arch/x86_64/irq.rs new file mode 100644 index 0000000..16b8d58 --- /dev/null +++ b/src/bare/arch/x86_64/irq.rs @@ -0,0 +1,49 @@ +use crate::irq::{IRQVector, IRQ}; + +/// Implement IRQ operations for the IRQ interface. +impl IRQ { + /// Enable irq for the given IRQ number. + #[inline] + pub fn irq_enable(_irq_num: usize) { + log::warn!("irq not implemented in riscv platform yet"); + } + + /// Disable irq for the given IRQ number. + #[inline] + pub fn irq_disable(_irq_num: usize) { + log::warn!("irq not implemented in riscv platform yet"); + } + + /// Enable interrupts. + #[inline] + pub fn int_enable() { + x86_64::instructions::interrupts::enable(); + } + + /// Disable interrupts. + #[inline] + pub fn int_disable() { + x86_64::instructions::interrupts::disable(); + } + + /// Check if the interrupts was enabled. + #[inline] + pub fn int_enabled() -> bool { + x86_64::instructions::interrupts::are_enabled() + } +} + +/// Implmente the irq vector methods +impl IRQVector { + /// Get the irq number in this vector + #[inline] + pub fn irq_num(&self) -> usize { + log::warn!("ack not implemented in x86_64 platform yet"); + self.0 + } + + /// Acknowledge the irq + pub fn ack(&self) { + log::warn!("ack not implemented in x86_64 platform yet"); + } +} diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index c1f64a2..455a296 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -12,6 +12,7 @@ mod page_table; mod sigtrx; mod time; mod uart; +mod irq; use ::multiboot::information::MemoryType; use alloc::vec::Vec; diff --git a/src/bare/irq.rs b/src/bare/irq.rs index 643c0e9..d78c7d0 100644 --- a/src/bare/irq.rs +++ b/src/bare/irq.rs @@ -35,3 +35,6 @@ pub struct IRQ; impl IRQ {} + +#[derive(Debug, Clone, Copy)] +pub struct IRQVector(pub(crate) usize); \ No newline at end of file diff --git a/src/bare/mod.rs b/src/bare/mod.rs index 585210f..9577128 100644 --- a/src/bare/mod.rs +++ b/src/bare/mod.rs @@ -125,7 +125,6 @@ //! //! TIPS: You should have finished [init] before using [get_mem_areas] and [get_fdt]. - cfg_if! { if #[cfg(target_arch = "x86_64")] { #[path = "arch/x86_64/mod.rs"] @@ -144,27 +143,27 @@ cfg_if! { } } -pub mod instruction; -pub mod irq; -pub mod mem; -pub mod time; -pub mod pagetable; mod addr; pub mod api; pub mod consts; +pub mod instruction; +pub mod irq; +pub mod mem; pub mod multicore; +pub mod pagetable; +pub mod time; -use core::mem::size_of; -pub use mem::Barrier; -use cfg_if::cfg_if; +use crate::irq::IRQVector; use crate::utils::once::LazyInit; -use fdt::Fdt; use alloc::vec::Vec; +use cfg_if::cfg_if; +use core::mem::size_of; +use fdt::Fdt; +pub use mem::Barrier; +use crate::common::page::PageAlloc; /// Trap Frame - use crate::STACK_SIZE; -use crate::common::page::PageAlloc; pub const PAGE_SIZE: usize = crate::PageTable::PAGE_SIZE; pub const USER_VADDR_END: usize = crate::PageTable::USER_VADDR_END; @@ -210,6 +209,7 @@ pub enum TrapType { LoadPageFault(usize), InstructionPageFault(usize), IllegalInstruction(usize), + Irq(IRQVector), } #[link_section = ".bss.stack"] @@ -262,4 +262,4 @@ pub fn get_fdt() -> Option> { /// Get the number of cpus pub fn get_cpu_num() -> usize { *CPU_NUM -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index e7b71ff..7dc895a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ cfg_if! { use imp::consts::*; use imp::multicore::MultiCore; use imp::current_arch::*; - + use irq::IRQVector; pub use imp::{ *, From c1eb5e429bb4cf67254026a7cd6e4844ea650889 Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 22:28:17 -0700 Subject: [PATCH 23/26] fix: fix x86_64 timer --- src/bare/arch/aarch64/gic.rs | 1 + src/bare/arch/aarch64/trap.rs | 4 +- src/bare/arch/x86_64/interrupt.rs | 10 ++-- src/bare/arch/x86_64/mod.rs | 15 +++--- src/bare/arch/x86_64/multiboot.rs | 12 ++++- src/bare/arch/x86_64/time.rs | 76 ++++++++++++++++++++++++++++--- 6 files changed, 97 insertions(+), 21 deletions(-) diff --git a/src/bare/arch/aarch64/gic.rs b/src/bare/arch/aarch64/gic.rs index d0c6a75..b1fa018 100644 --- a/src/bare/arch/aarch64/gic.rs +++ b/src/bare/arch/aarch64/gic.rs @@ -47,6 +47,7 @@ impl IRQVector { } } +/// Get the irq Vector that was #[inline] pub fn get_irq() -> IRQVector { IRQVector(GICC.iar() as _) diff --git a/src/bare/arch/aarch64/trap.rs b/src/bare/arch/aarch64/trap.rs index af50683..65581b8 100644 --- a/src/bare/arch/aarch64/trap.rs +++ b/src/bare/arch/aarch64/trap.rs @@ -44,9 +44,7 @@ fn handle_exception(tf: &mut TrapFrame, kind: TrapKind, source: TrapSource) -> T set_next_timer(); TrapType::Time } - _ => { - TrapType::Irq(irq) - } + _ => TrapType::Irq(irq), }; unsafe { crate::api::_interrupt_for_arch(tf, trap_type) }; return trap_type; diff --git a/src/bare/arch/x86_64/interrupt.rs b/src/bare/arch/x86_64/interrupt.rs index caad9b9..e9a0a61 100644 --- a/src/bare/arch/x86_64/interrupt.rs +++ b/src/bare/arch/x86_64/interrupt.rs @@ -8,10 +8,10 @@ use x86_64::VirtAddr; use x86::{controlregs::cr2, irq::*}; -use crate::TRAPFRAME_SIZE; use crate::imp::current_arch::gdt::set_tss_kernel_sp; -use crate::imp::current_arch::SYSCALL_VECTOR; use crate::imp::current_arch::gdt::GdtStruct; +use crate::imp::current_arch::SYSCALL_VECTOR; +use crate::TRAPFRAME_SIZE; use crate::{imp::current_arch::TrapFrame, TrapType}; use super::apic::vectors::APIC_TIMER_VECTOR; @@ -99,7 +99,10 @@ fn kernel_callback(context: &mut TrapFrame) { context ); } - APIC_TIMER_VECTOR => TrapType::Time, + APIC_TIMER_VECTOR => { + unsafe { super::apic::local_apic().end_of_interrupt() }; + TrapType::Time + } // IRQ_VECTOR_START..=IRQ_VECTOR_END => crate::trap::handle_irq_extern(tf.vector as _), _ => { panic!( @@ -109,7 +112,6 @@ fn kernel_callback(context: &mut TrapFrame) { } }; unsafe { crate::_interrupt_for_arch(context, trap_type) }; - unsafe { super::apic::local_apic().end_of_interrupt() }; } #[naked] diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index 455a296..910f0ff 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -5,6 +5,7 @@ mod context; mod gdt; mod idt; mod interrupt; +mod irq; #[cfg(feature = "kcontext")] mod kcontext; mod multiboot; @@ -12,7 +13,6 @@ mod page_table; mod sigtrx; mod time; mod uart; -mod irq; use ::multiboot::information::MemoryType; use alloc::vec::Vec; @@ -32,12 +32,9 @@ use x86_64::{ }, }; -use crate::imp::{ - current_arch::multiboot::use_multiboot, CPU_NUM, - DTB_BIN, MEM_AREA, -}; -use crate::MultiCore; +use crate::imp::{current_arch::multiboot::use_multiboot, CPU_NUM, DTB_BIN, MEM_AREA}; use crate::utils::once::LazyInit; +use crate::MultiCore; #[percpu::def_percpu] static CPU_ID: usize = 1; @@ -68,6 +65,12 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) { CpuId::new().get_feature_info().map(|features| { info!("is there a avx feature: {}", features.has_avx()); info!("is there a xsave feature: {}", features.has_xsave()); + // Add OSXSave flag to cr4 register if supported + if features.has_xsave() { + unsafe { + Cr4::write(Cr4::read() | Cr4Flags::OSXSAVE); + } + } info!("cr4 has OSXSAVE feature: {:?}", Cr4::read()); if features.has_avx() && features.has_xsave() && Cr4::read().contains(Cr4Flags::OSXSAVE) { unsafe { diff --git a/src/bare/arch/x86_64/multiboot.rs b/src/bare/arch/x86_64/multiboot.rs index c919c3a..edb548a 100644 --- a/src/bare/arch/x86_64/multiboot.rs +++ b/src/bare/arch/x86_64/multiboot.rs @@ -17,17 +17,27 @@ const MULTIBOOT_HEADER_FLAGS: usize = 0x0001_0002; /// The magic field should contain this. const MULTIBOOT_HEADER_MAGIC: usize = 0x1BADB002; +/// CR0 Registers introduction: https://wiki.osdev.org/CPU_Registers_x86-64#CR0 const CR0: u64 = Cr0Flags::PROTECTED_MODE_ENABLE.bits() | Cr0Flags::MONITOR_COPROCESSOR.bits() | Cr0Flags::NUMERIC_ERROR.bits() | Cr0Flags::WRITE_PROTECT.bits() | Cr0Flags::PAGING.bits(); +/// CR4 registers introduction: https://wiki.osdev.org/CPU_Registers_x86-64#CR4 +/// Physical Address Extension const CR4: u64 = Cr4Flags::PHYSICAL_ADDRESS_EXTENSION.bits() + // Page Global Enable | Cr4Flags::PAGE_GLOBAL.bits() + // OS support for fxsave and fxrstor instructions | Cr4Flags::OSFXSR.bits() - | Cr4Flags::OSXSAVE.bits() + // XSAVE And Processor Extended States Enable + // This bit should open if the processor was supported. + // | Cr4Flags::OSXSAVE.bits() + // OS Support for unmasked simd floating point exceptions | Cr4Flags::OSXMMEXCPT_ENABLE.bits(); + +/// EFER registers introduction: https://wiki.osdev.org/CPU_Registers_x86-64#IA32_EFER const EFER: u64 = EferFlags::LONG_MODE_ENABLE.bits() | EferFlags::NO_EXECUTE_ENABLE.bits(); static mut MEM: Mem = Mem; diff --git a/src/bare/arch/x86_64/time.rs b/src/bare/arch/x86_64/time.rs index 2a00445..efe9892 100644 --- a/src/bare/arch/x86_64/time.rs +++ b/src/bare/arch/x86_64/time.rs @@ -1,8 +1,7 @@ use raw_cpuid::CpuId; - +use x86_64::structures::port::{self, PortRead}; use crate::time::Time; -static mut INIT_TICK: usize = 0; static mut CPU_FREQ_MHZ: usize = 4000_000_000; impl Time { @@ -31,17 +30,80 @@ pub(super) fn init_early() { } } - unsafe { INIT_TICK = core::arch::x86_64::_rdtsc() as _ }; - debug!("INIT_TICK: {}", unsafe { INIT_TICK }); - unsafe { use x2apic::lapic::{TimerDivide, TimerMode}; let lapic = super::apic::local_apic(); lapic.set_timer_mode(TimerMode::Periodic); - lapic.set_timer_divide(TimerDivide::Div256); // indeed it is Div1, the name is confusing. + lapic.set_timer_divide(TimerDivide::Div2); // indeed it is Div1, the name is confusing. lapic.enable_timer(); - lapic.set_timer_initial(0x20_0000); + // PIT(Programmable Interval Timer) + // https://wiki.osdev.org/Pit + // Bits Usage + // 6 and 7 Select channel : + // 0 0 = Channel 0 + // 0 1 = Channel 1 + // 1 0 = Channel 2 + // 1 1 = Read-back command (8254 only) + // 4 and 5 Access mode : + // 0 0 = Latch count value command + // 0 1 = Access mode: lobyte only + // 1 0 = Access mode: hibyte only + // 1 1 = Access mode: lobyte/hibyte + // 1 to 3 Operating mode : + // 0 0 0 = Mode 0 (interrupt on terminal count) + // 0 0 1 = Mode 1 (hardware re-triggerable one-shot) + // 0 1 0 = Mode 2 (rate generator) + // 0 1 1 = Mode 3 (square wave generator) + // 1 0 0 = Mode 4 (software triggered strobe) + // 1 0 1 = Mode 5 (hardware triggered strobe) + // 1 1 0 = Mode 2 (rate generator, same as 010b) + // 1 1 1 = Mode 3 (square wave generator, same as 011b) + // 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD + // open PIT2 + let pcspeaker = u8::read_from_port(0x61); + u8::write_to_port(0x61, pcspeaker | 1); + + const PIT_FREQ: u16 = 11931; + use port::PortWrite; + // Set PIT2 one-shott mode + u8::write_to_port(0x43, 0b10110010); + + // Write frequency to port + u16::write_to_port(0x42, PIT_FREQ & 0xff); + u16::write_to_port(0x42, (PIT_FREQ >> 8) & 0xff); + + // Reset PIT2 counter + let pcspeaker = u8::read_from_port(0x61); + u8::write_to_port(0x61, pcspeaker & 0xfd); + u8::write_to_port(0x61, pcspeaker | 1); + + // Reset loapic counter + lapic.set_timer_initial(0xFFFF_FFFF); + + // Read count + loop { + let mut count = u16::read_from_port(0x42); + count |= u16::read_from_port(0x42) << 8; + if count == 0 || count >= 60000 { + break; + } + } + let end = lapic.timer_current(); + log::info!( + "end {:#x} start: {:#x}, interval: {:#x}", + end, + 0xFFFF_FFFFu32, + 0xFFFF_FFFF - end + ); + + let ticks10ms = 0xFFFF_FFFF - end; + // lapic.set_timer_initial(0x20_000); + // Set ticks 1s + log::info!("ticks 50us: {}", ticks10ms / 10 / 20); + // lapic.set_timer_initial(ticks10ms * 0x100); + // Set 500us ticks + lapic.set_timer_initial(ticks10ms / 20); debug!("count: {}", lapic.timer_current()); // set_oneshot_timer(2000); } From 51ae6b9a7f56ae9cb19a343b23096925a6b9d7f8 Mon Sep 17 00:00:00 2001 From: jackhu Date: Mon, 3 Jun 2024 22:37:05 -0700 Subject: [PATCH 24/26] feat: display boot infomation except loongarch --- .cargo/config.toml | 4 +-- src/bare/arch/aarch64/mod.rs | 21 +++++++++++++ src/bare/arch/aarch64/trap.rs | 2 +- src/bare/arch/riscv64/mod.rs | 20 ++++++++++++ src/bare/arch/x86_64/mod.rs | 57 ++++++++++++++++++++++++----------- src/bare/banner.txt | 8 +++++ src/common/debug.rs | 30 ++++++++++++++++++ src/lib.rs | 3 +- 8 files changed, 123 insertions(+), 22 deletions(-) create mode 100644 src/bare/banner.txt diff --git a/.cargo/config.toml b/.cargo/config.toml index bac0add..a6b4d94 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # Just used for rust-analyzer. [build] -target = "riscv64gc-unknown-none-elf" +# target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' # target = 'x86_64-unknown-none' -# target = 'loongarch64-unknown-none' +target = 'loongarch64-unknown-none' diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index 987cca4..6b53d63 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -14,6 +14,7 @@ mod trap; use core::slice; +use crate::debug::{display_info, println}; use aarch64_cpu::registers::CPACR_EL1; use aarch64_cpu::registers::{Readable, Writeable, MPIDR_EL1, TTBR0_EL1}; use alloc::vec::Vec; @@ -55,6 +56,26 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { CPACR_EL1.write(CPACR_EL1::FPEN::TrapNothing); aarch64_cpu::asm::barrier::isb(aarch64_cpu::asm::barrier::SY); + // Display Polyhal and Platform Information + display_info!(); + println!(include_str!("../../banner.txt")); + display_info!("Platform Name", "aarch64"); + if let Ok(fdt) = unsafe { Fdt::from_ptr(device_tree as *const u8) } { + display_info!("Platform HART Count", "{}", fdt.cpus().count()); + fdt.memory().regions().for_each(|x| { + display_info!( + "Platform Memory Region", + "{:#p} - {:#018x}", + x.starting_address, + x.starting_address as usize + x.size.unwrap() + ); + }); + } + display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START); + display_info!(); + display_info!("Boot HART ID", "{}", hart_id); + display_info!(); + // Enter to kernel entry point(`main` function). unsafe { crate::_main_for_arch(hart_id) }; diff --git a/src/bare/arch/aarch64/trap.rs b/src/bare/arch/aarch64/trap.rs index 65581b8..2769b1e 100644 --- a/src/bare/arch/aarch64/trap.rs +++ b/src/bare/arch/aarch64/trap.rs @@ -4,7 +4,7 @@ use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, SCTLR_EL2::I, VBAR_EL1 use tock_registers::interfaces::Readable; use crate::{ - currrent_arch::{gic::TIMER_IRQ_NUM, timer::set_next_timer}, + current_arch::{gic::TIMER_IRQ_NUM, timer::set_next_timer}, instruction::Instruction, irq::IRQVector, TrapType, diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index aa12cfe..c47084a 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -31,6 +31,7 @@ use riscv::register::{sie, sstatus}; use super::{CPU_NUM, DTB_BIN, MEM_AREA}; use crate::{frame_alloc, utils::once::LazyInit, MultiCore}; +use crate::debug::{display_info, println}; #[percpu::def_percpu] static CPU_ID: usize = 0; @@ -63,6 +64,25 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { DTB_PTR.init_by(device_tree); + display_info!(); + println!(include_str!("../../banner.txt")); + display_info!("Platform Name", "riscv64"); + if let Ok(fdt) = unsafe { Fdt::from_ptr(device_tree as *const u8) } { + display_info!("Platform HART Count", "{}", fdt.cpus().count()); + fdt.memory().regions().for_each(|x| { + display_info!( + "Platform Memory Region", + "{:#p} - {:#018x}", + x.starting_address, + x.starting_address as usize + x.size.unwrap() + ); + }); + } + display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START); + display_info!(); + display_info!("Boot HART ID", "{}", hartid); + display_info!(); + unsafe { crate::_main_for_arch(hartid) }; shutdown(); } diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index 910f0ff..471013a 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -14,6 +14,7 @@ mod sigtrx; mod time; mod uart; +use core::cmp; use ::multiboot::information::MemoryType; use alloc::vec::Vec; pub use consts::*; @@ -35,6 +36,7 @@ use x86_64::{ use crate::imp::{current_arch::multiboot::use_multiboot, CPU_NUM, DTB_BIN, MEM_AREA}; use crate::utils::once::LazyInit; use crate::MultiCore; +use crate::debug::{display_info, println}; #[percpu::def_percpu] static CPU_ID: usize = 1; @@ -82,22 +84,47 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) { // TODO: This is will be fixed with ACPI support CPU_NUM.init_by(1); - info!( - "TEST CPU ID: {} ptr: {:#x}", - CPU_ID.read_current(), - unsafe { CPU_ID.current_ptr() } as usize - ); - CPU_ID.write_current(345); - info!( - "TEST CPU ID: {} ptr: {:#x}", - CPU_ID.read_current(), - unsafe { CPU_ID.current_ptr() } as usize - ); - info!("magic: {:#x}, mboot_ptr: {:#x}", magic, mboot_ptr); MBOOT_PTR.init_by(mboot_ptr); + display_info!(); + println!(include_str!("../../banner.txt")); + display_info!("Platform Arch", "x86_64"); + if let Some(features) = CpuId::new().get_feature_info() { + display_info!( + "Platform Hart Count", + "{}", + cmp::max(1, features.max_logical_processor_ids()) + ); + display_info!("Platform FPU Support", "{}", features.has_fpu()); + } + display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START); + if let Some(mboot) = use_multiboot(mboot_ptr as _) { + mboot + .command_line() + .inspect(|cl| display_info!("Platform Command Line", "{}", cl)); + if let Some(mr) = mboot.memory_regions() { + mr.for_each(|mm| { + display_info!( + "Platform Memory Region", + "{:#018x} - {:#018x} {:?}", + mm.base_address(), + mm.base_address() + mm.length(), + mm.memory_type() + ) + }); + } + display_info!(); + display_info!( + "Boot Image Highest Addr", + "{:#018x}", + mboot.find_highest_address() + ); + } + display_info!("Boot HART ID", "{}", CPU_ID.read_current()); + display_info!(); + unsafe { crate::_main_for_arch(0) }; shutdown() @@ -106,12 +133,6 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) { pub fn arch_init() { DTB_BIN.init_by(Vec::new()); if let Some(mboot) = use_multiboot(*MBOOT_PTR as _) { - mboot - .boot_loader_name() - .inspect(|x| info!("bootloader: {}", x)); - mboot - .command_line() - .inspect(|x| info!("command_line: {}", x)); let mut mem_area = Vec::new(); if mboot.has_memory_map() { mboot diff --git a/src/bare/banner.txt b/src/bare/banner.txt new file mode 100644 index 0000000..4f05405 --- /dev/null +++ b/src/bare/banner.txt @@ -0,0 +1,8 @@ + _____ _ _ _ _ + | __ \ | | | | | | /\ | | + | |__) |__ | |_ _| |__| | / \ | | + | ___/ _ \| | | | | __ | / /\ \ | | + | | | (_) | | |_| | | | |/ ____ \| |____ + |_| \___/|_|\__, |_| |_/_/ \_\______| + __/ | + |___/ \ No newline at end of file diff --git a/src/common/debug.rs b/src/common/debug.rs index 94f4723..24c97e2 100644 --- a/src/common/debug.rs +++ b/src/common/debug.rs @@ -13,6 +13,36 @@ use core::fmt::Write; /// ```rust /// DebugConsole::getchar(); /// ``` +/// +/// Print macro to print polyhal information with newline +pub(crate) macro println { + () => { + $crate::debug::print(format_args!("\n")) + }, + ($fmt: expr $(, $($arg: tt)+)?) => { + $crate::debug::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + }, +} + +/// Display Platform Information with specified format +/// display_info!("item name", "{}", "format"); +/// The output format like below: +/// item name : format +pub(crate) macro display_info{ + () => { + $crate::debug::print(format_args!("\n")) + }, + ($item:literal,$fmt: expr $(, $($arg: tt)+)?) => { + $crate::debug::print(format_args!(concat!("{:<26}: ", $fmt, "\n"),$item $(, $($arg)+)?)) + } +} + +/// Print the given arguments +#[inline] +pub(crate) fn print(args: core::fmt::Arguments) { + DebugConsole.write_fmt(args).expect("can't print arguments"); +} + pub struct DebugConsole; // Write string through DebugConsole diff --git a/src/lib.rs b/src/lib.rs index 7dc895a..5492a6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(feature = "libos"), no_std)] +#![feature(decl_macro)] #![no_main] #![feature(naked_functions)] #![feature(asm_const)] @@ -16,7 +17,7 @@ extern crate log; extern crate cfg_if; #[macro_use] mod utils; - +#[macro_use] mod common; pub use common::{page::PageAlloc, *}; From e9897b9d694d975a0b36f55b2116fb3a757a1a77 Mon Sep 17 00:00:00 2001 From: jackhu Date: Tue, 4 Jun 2024 01:04:42 -0700 Subject: [PATCH 25/26] support shutdown in libos --- src/lib.rs | 1 + src/libos/mod.rs | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5492a6e..b2f388e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ cfg_if! { pub use imp::vm::{Page, PageTable}; pub use imp::addr::MMUFlags; pub use imp::mem::{pmem_read, pmem_copy, pmem_write, pmem_zero}; + pub use imp::shutdown; } else { #[path = "bare/mod.rs"] mod imp; diff --git a/src/libos/mod.rs b/src/libos/mod.rs index b67cce8..c991e5b 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -1,9 +1,9 @@ +pub mod addr; pub mod context; pub mod debug; pub mod mem; -pub mod vm; pub mod mock_mem; -pub mod addr; +pub mod vm; use crate::utils::once::LazyInit; use crate::PageAlloc; @@ -13,6 +13,11 @@ extern "Rust" { #[no_mangle] fn main() { + display_info!(); + println!(include_str!("../../banner.txt")); + display_info!("Platform Name", "libos"); + display_info!("Boot HART ID", "{}", 0); + display_info!(); unsafe { _main_for_arch(0) }; } @@ -24,4 +29,9 @@ pub fn init(page_alloc: &'static dyn PageAlloc) { PAGE_ALLOC.init_by(page_alloc); self::mem::init_mock_mem(); -} \ No newline at end of file +} + +pub fn shutdown() { + // 退出程序 + std::process::exit(0); +} From 4b0eb2f56d68dcd42a0720a176abca567c7189f0 Mon Sep 17 00:00:00 2001 From: jackhu Date: Tue, 4 Jun 2024 02:20:40 -0700 Subject: [PATCH 26/26] support libos banner --- .cargo/config.toml | 4 ++-- src/bare/arch/aarch64/mod.rs | 42 ++++++++++++++++----------------- src/bare/arch/riscv64/mod.rs | 4 ++-- src/bare/arch/x86_64/mod.rs | 6 ++--- src/{bare => common}/banner.txt | 0 src/libos/mod.rs | 4 ++-- 6 files changed, 30 insertions(+), 30 deletions(-) rename src/{bare => common}/banner.txt (100%) diff --git a/.cargo/config.toml b/.cargo/config.toml index a6b4d94..bac0add 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ # Just used for rust-analyzer. [build] -# target = "riscv64gc-unknown-none-elf" +target = "riscv64gc-unknown-none-elf" # target = 'aarch64-unknown-none-softfloat' # target = 'x86_64-unknown-none' -target = 'loongarch64-unknown-none' +# target = 'loongarch64-unknown-none' diff --git a/src/bare/arch/aarch64/mod.rs b/src/bare/arch/aarch64/mod.rs index 6b53d63..31f1f3e 100644 --- a/src/bare/arch/aarch64/mod.rs +++ b/src/bare/arch/aarch64/mod.rs @@ -29,10 +29,10 @@ pub use page_table::*; pub use psci::system_off as shutdown; pub use trap::run_user_task; +use super::{clear_bss, CPU_NUM, DTB_BIN, MEM_AREA}; +use crate::utils::once::LazyInit; use crate::MultiCore; use crate::PageTable; -use crate::utils::once::LazyInit; -use super::{clear_bss, CPU_NUM, MEM_AREA, DTB_BIN}; static DTB_PTR: LazyInit = LazyInit::new(); @@ -56,25 +56,25 @@ pub fn rust_tmp_main(hart_id: usize, device_tree: usize) { CPACR_EL1.write(CPACR_EL1::FPEN::TrapNothing); aarch64_cpu::asm::barrier::isb(aarch64_cpu::asm::barrier::SY); - // Display Polyhal and Platform Information - display_info!(); - println!(include_str!("../../banner.txt")); - display_info!("Platform Name", "aarch64"); - if let Ok(fdt) = unsafe { Fdt::from_ptr(device_tree as *const u8) } { - display_info!("Platform HART Count", "{}", fdt.cpus().count()); - fdt.memory().regions().for_each(|x| { - display_info!( - "Platform Memory Region", - "{:#p} - {:#018x}", - x.starting_address, - x.starting_address as usize + x.size.unwrap() - ); - }); - } - display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START); - display_info!(); - display_info!("Boot HART ID", "{}", hart_id); - display_info!(); + // Display Polyhal and Platform Information + display_info!(); + println!(include_str!("../../../common/banner.txt")); + display_info!("Platform Name", "aarch64"); + if let Ok(fdt) = unsafe { Fdt::from_ptr(device_tree as *const u8) } { + display_info!("Platform HART Count", "{}", fdt.cpus().count()); + fdt.memory().regions().for_each(|x| { + display_info!( + "Platform Memory Region", + "{:#p} - {:#018x}", + x.starting_address, + x.starting_address as usize + x.size.unwrap() + ); + }); + } + display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START); + display_info!(); + display_info!("Boot HART ID", "{}", hart_id); + display_info!(); // Enter to kernel entry point(`main` function). unsafe { crate::_main_for_arch(hart_id) }; diff --git a/src/bare/arch/riscv64/mod.rs b/src/bare/arch/riscv64/mod.rs index c47084a..38f55f7 100644 --- a/src/bare/arch/riscv64/mod.rs +++ b/src/bare/arch/riscv64/mod.rs @@ -30,8 +30,8 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext} use riscv::register::{sie, sstatus}; use super::{CPU_NUM, DTB_BIN, MEM_AREA}; -use crate::{frame_alloc, utils::once::LazyInit, MultiCore}; use crate::debug::{display_info, println}; +use crate::{frame_alloc, utils::once::LazyInit, MultiCore}; #[percpu::def_percpu] static CPU_ID: usize = 0; @@ -65,7 +65,7 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) { DTB_PTR.init_by(device_tree); display_info!(); - println!(include_str!("../../banner.txt")); + println!(include_str!("../../../common/banner.txt")); display_info!("Platform Name", "riscv64"); if let Ok(fdt) = unsafe { Fdt::from_ptr(device_tree as *const u8) } { display_info!("Platform HART Count", "{}", fdt.cpus().count()); diff --git a/src/bare/arch/x86_64/mod.rs b/src/bare/arch/x86_64/mod.rs index 471013a..b4ee204 100644 --- a/src/bare/arch/x86_64/mod.rs +++ b/src/bare/arch/x86_64/mod.rs @@ -14,11 +14,11 @@ mod sigtrx; mod time; mod uart; -use core::cmp; use ::multiboot::information::MemoryType; use alloc::vec::Vec; pub use consts::*; pub use context::TrapFrame; +use core::cmp; pub use interrupt::*; #[cfg(feature = "kcontext")] pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext}; @@ -33,10 +33,10 @@ use x86_64::{ }, }; +use crate::debug::{display_info, println}; use crate::imp::{current_arch::multiboot::use_multiboot, CPU_NUM, DTB_BIN, MEM_AREA}; use crate::utils::once::LazyInit; use crate::MultiCore; -use crate::debug::{display_info, println}; #[percpu::def_percpu] static CPU_ID: usize = 1; @@ -89,7 +89,7 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) { MBOOT_PTR.init_by(mboot_ptr); display_info!(); - println!(include_str!("../../banner.txt")); + println!(include_str!("../../../common/banner.txt")); display_info!("Platform Arch", "x86_64"); if let Some(features) = CpuId::new().get_feature_info() { display_info!( diff --git a/src/bare/banner.txt b/src/common/banner.txt similarity index 100% rename from src/bare/banner.txt rename to src/common/banner.txt diff --git a/src/libos/mod.rs b/src/libos/mod.rs index c991e5b..6c2bf0e 100644 --- a/src/libos/mod.rs +++ b/src/libos/mod.rs @@ -4,6 +4,7 @@ pub mod debug; pub mod mem; pub mod mock_mem; pub mod vm; +use crate::debug::display_info; use crate::utils::once::LazyInit; use crate::PageAlloc; @@ -14,7 +15,7 @@ extern "Rust" { #[no_mangle] fn main() { display_info!(); - println!(include_str!("../../banner.txt")); + println!(include_str!("../common/banner.txt")); display_info!("Platform Name", "libos"); display_info!("Boot HART ID", "{}", 0); display_info!(); @@ -32,6 +33,5 @@ pub fn init(page_alloc: &'static dyn PageAlloc) { } pub fn shutdown() { - // 退出程序 std::process::exit(0); }