From 06fe2d25d5e3541d4f171f1518f95c4726ebc9b0 Mon Sep 17 00:00:00 2001 From: riii111 Date: Mon, 17 Nov 2025 00:38:59 +0900 Subject: [PATCH 1/7] chore: example port mapped I/O --- wasabi/src/main.rs | 17 +++++++++++++++++ wasabi/src/serial.rs | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/wasabi/src/main.rs b/wasabi/src/main.rs index f3d40b8..6087576 100644 --- a/wasabi/src/main.rs +++ b/wasabi/src/main.rs @@ -20,6 +20,7 @@ use wasabi::print::set_global_vram; use wasabi::println; use wasabi::qemu::exit_qemu; use wasabi::qemu::QemuExitCode; +use wasabi::serial::SerialPort; use wasabi::uefi::init_vram; use wasabi::uefi::locate_loaded_image_protocol; use wasabi::uefi::EfiHandle; @@ -67,9 +68,25 @@ fn efi_main(image_handle: EfiHandle, efi_system_table: &EfiSystemTable) { } Ok(()) }); + let serial_task = Task::new(async { + let sp = SerialPort::default(); + if let Err(e) = sp.loopback_test() { + error!("{e:?}"); + return Err("serial: loopback test failed"); + } + info!("Started to monitor serial port"); + loop { + if let Some(v) = sp.try_read() { + let c = char::from_u32(v as u32); + info!("serial input: {v:#04X} = {c:?}"); + } + TimeoutFuture::new(Duration::from_millis(20)).await; + } + }); let mut executor = Executor::new(); executor.enqueue(task1); executor.enqueue(task2); + executor.enqueue(serial_task); Executor::run(executor) } diff --git a/wasabi/src/serial.rs b/wasabi/src/serial.rs index dd1be4b..0c1c163 100644 --- a/wasabi/src/serial.rs +++ b/wasabi/src/serial.rs @@ -1,3 +1,4 @@ +use crate::result::Result; use crate::x86::busy_loop_hint; use crate::x86::read_io_port_u8; use crate::x86::write_io_port_u8; @@ -38,6 +39,17 @@ impl SerialPort { } write_io_port_u8(self.base, c as u8); } + pub fn loopback_test(&self) -> Result<()> { + // Set in loopback mode + write_io_port_u8(self.base + 4, 0x1e); + self.send_char('T'); + if self.try_read().ok_or("loopback_test failed: No response")? != b'T' { + return Err("loopback_test failed: wrong data received"); + } + // Return to the normal mode + write_io_port_u8(self.base + 4, 0x0f); + Ok(()) + } pub fn send_str(&self, s: &str) { let mut sc = s.chars(); let slen = s.chars().count(); @@ -45,6 +57,16 @@ impl SerialPort { self.send_char(sc.next().unwrap()); } } + pub fn try_read(&self) -> Option { + if read_io_port_u8(self.base + 5) & 0x01 == 0 { + None + } else { + let c = read_io_port_u8(self.base); + // Enable FIFO, clear them, with 14-byte threshold + write_io_port_u8(self.base + 2, 0xC7); + Some(c) + } + } } impl fmt::Write for SerialPort { fn write_str(&mut self, s: &str) -> fmt::Result { From 3473505311de9a5e1478c352f735dcc9c8da8958 Mon Sep 17 00:00:00 2001 From: riii111 Date: Mon, 17 Nov 2025 11:16:11 +0900 Subject: [PATCH 2/7] chore: get the starting address of the ECAM region --- wasabi/scripts/launch_qemu.sh | 1 + wasabi/src/acpi.rs | 68 ++++++++++++++++++++++++++++++++++- wasabi/src/init.rs | 10 ++++++ wasabi/src/main.rs | 2 ++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/wasabi/scripts/launch_qemu.sh b/wasabi/scripts/launch_qemu.sh index 7c6ed71..03a392f 100644 --- a/wasabi/scripts/launch_qemu.sh +++ b/wasabi/scripts/launch_qemu.sh @@ -11,6 +11,7 @@ mkdir -p log qemu-system-x86_64 \ -m 4G\ -bios third_party/ovmf/RELEASEX64_OVMF.fd \ + -machine q35 \ -drive format=raw,file=fat:rw:mnt \ -chardev stdio,id=char_com1,mux=on,logfile=log/com1.txt \ -serial chardev:char_com1 \ diff --git a/wasabi/src/acpi.rs b/wasabi/src/acpi.rs index 195484b..0bce21e 100644 --- a/wasabi/src/acpi.rs +++ b/wasabi/src/acpi.rs @@ -1,5 +1,6 @@ use crate::hpet::HpetRegisters; use crate::result::Result; +use core::fmt; use core::mem::size_of; #[repr(packed)] @@ -118,7 +119,7 @@ impl GenericAddress { #[repr(packed)] pub struct AcpiHpetDescriptor { - _header: SystemDescriptionTableHeader, + header: SystemDescriptionTableHeader, _reserved0: u32, address: GenericAddress, _reserved1: u32, @@ -157,4 +158,69 @@ impl AcpiRsdpStruct { let xsdt = self.xsdt(); xsdt.find_table(b"HPET").map(AcpiHpetDescriptor::new) } + pub fn mcfg(&self) -> Option<&AcpiMcfgDescriptor> { + let xsdt = self.xsdt(); + xsdt.find_table(b"MCFG").map(AcpiMcfgDescriptor::new) + } +} + +#[repr(C, packed)] +#[derive(Debug)] +#[allow(dead_code)] +pub struct AcpiMcfgDescriptor { + // https://wiki.osdev.org/PCI_Express + header: SystemDescriptionTableHeader, + _unused: [u8; 8], + // 44 + (16 * n) -> Configuration space base address allocation structures + // [EcamEntry; ?] +} +impl AcpiTable for AcpiMcfgDescriptor { + const SIGNATURE: &'static [u8; 4] = b"MCFG"; + type Table = Self; +} +const _: () = assert!(size_of::() == 44); +impl AcpiMcfgDescriptor { + pub fn header_size(&self) -> usize { + size_of::() + } + pub fn num_of_entries(&self) -> usize { + (self.header.length as usize - self.header_size()) / size_of::() + } + pub fn entry(&self, index: usize) -> Option<&EcamEntry> { + if index >= self.num_of_entries() { + None + } else { + Some(unsafe { + &*((self as *const Self as *const u8).add(self.header_size()) as *const EcamEntry) + .add(index) + }) + } + } +} + +#[repr(packed)] +pub struct EcamEntry { + ecm_base_addr: u64, + _pci_segment_group: u16, + start_pci_bus: u8, + end_pci_bus: u8, + _reserved: u32, +} +impl EcamEntry { + pub fn base_address(&self) -> u64 { + self.ecm_base_addr + } +} +impl fmt::Display for EcamEntry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // To avoid "error: reference to packed field is unaligned" + let base = self.ecm_base_addr; + let bus_start = self.start_pci_bus; + let bus_end = self.end_pci_bus; + write!( + f, + "ECAM: Bus [{}..={}] is mapped at {:#X}", + bus_start, bus_end, base + ) + } } diff --git a/wasabi/src/init.rs b/wasabi/src/init.rs index 0ccfa66..048ff5e 100644 --- a/wasabi/src/init.rs +++ b/wasabi/src/init.rs @@ -87,3 +87,13 @@ pub fn init_display(vram: &mut VramBufferInfo) { fill_rect(vram, 0x000000, 0, 0, vw, vh).expect("fill_rect failed"); draw_test_pattern(vram); } + +pub fn init_pci(acpi: &AcpiRsdpStruct) { + if let Some(mcfg) = acpi.mcfg() { + for i in 0..mcfg.num_of_entries() { + if let Some(e) = mcfg.entry(i) { + info!("{}", e) + } + } + } +} diff --git a/wasabi/src/main.rs b/wasabi/src/main.rs index 6087576..d3b48ce 100644 --- a/wasabi/src/main.rs +++ b/wasabi/src/main.rs @@ -14,6 +14,7 @@ use wasabi::init::init_allocator; use wasabi::init::init_basic_runtime; use wasabi::init::init_display; use wasabi::init::init_hpet; +use wasabi::init::init_pci; use wasabi::init::init_paging; use wasabi::print::hexdump; use wasabi::print::set_global_vram; @@ -53,6 +54,7 @@ fn efi_main(image_handle: EfiHandle, efi_system_table: &EfiSystemTable) { init_paging(&memory_map); init_hpet(acpi); + init_pci(acpi); let t0 = global_timestamp(); let task1 = Task::new(async move { for i in 100..=103 { From 1e71f47ba169f1f80fda73593baaaf1e60f88ebc Mon Sep 17 00:00:00 2001 From: riii111 Date: Tue, 18 Nov 2025 22:10:45 +0900 Subject: [PATCH 3/7] chore: display PCI device list --- wasabi/src/init.rs | 3 + wasabi/src/lib.rs | 1 + wasabi/src/main.rs | 2 +- wasabi/src/pci.rs | 155 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 wasabi/src/pci.rs diff --git a/wasabi/src/init.rs b/wasabi/src/init.rs index 048ff5e..821222e 100644 --- a/wasabi/src/init.rs +++ b/wasabi/src/init.rs @@ -8,6 +8,7 @@ use crate::graphics::Bitmap; use crate::hpet::set_global_hpet; use crate::hpet::Hpet; use crate::info; +use crate::pci::Pci; use crate::uefi::exit_from_efi_boot_services; use crate::uefi::EfiHandle; use crate::uefi::EfiMemoryType; @@ -95,5 +96,7 @@ pub fn init_pci(acpi: &AcpiRsdpStruct) { info!("{}", e) } } + let pci = Pci::new(mcfg); + pci.probe_devices(); } } diff --git a/wasabi/src/lib.rs b/wasabi/src/lib.rs index caa0026..3660451 100644 --- a/wasabi/src/lib.rs +++ b/wasabi/src/lib.rs @@ -14,6 +14,7 @@ pub mod graphics; pub mod hpet; pub mod init; pub mod mutex; +pub mod pci; pub mod print; pub mod qemu; pub mod result; diff --git a/wasabi/src/main.rs b/wasabi/src/main.rs index d3b48ce..c28bf87 100644 --- a/wasabi/src/main.rs +++ b/wasabi/src/main.rs @@ -14,8 +14,8 @@ use wasabi::init::init_allocator; use wasabi::init::init_basic_runtime; use wasabi::init::init_display; use wasabi::init::init_hpet; -use wasabi::init::init_pci; use wasabi::init::init_paging; +use wasabi::init::init_pci; use wasabi::print::hexdump; use wasabi::print::set_global_vram; use wasabi::println; diff --git a/wasabi/src/pci.rs b/wasabi/src/pci.rs new file mode 100644 index 0000000..667de88 --- /dev/null +++ b/wasabi/src/pci.rs @@ -0,0 +1,155 @@ +use crate::acpi::AcpiMcfgDescriptor; +use crate::info; +use crate::result::Result; +use core::fmt; +use core::marker::PhantomData; +use core::mem::size_of; +use core::ops::Range; +use core::ptr::read_volatile; + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct VendorDeviceId { + pub vendor: u16, + pub device: u16, +} +impl VendorDeviceId { + pub fn fmt_common(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "(vendor: {:#06X}, device: {:#06X})", + self.vendor, self.device, + ) + } +} +impl fmt::Debug for VendorDeviceId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.fmt_common(f) + } +} +impl fmt::Display for VendorDeviceId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.fmt_common(f) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct BusDeviceFunction { + id: u16, +} +const MASK_BUS: usize = 0b1111_1111_0000_0000; +const SHIFT_BUS: usize = 8; +const MASK_DEVICE: usize = 0b0000_0000_1111_1000; +const SHIFT_DEVICE: usize = 3; +const MASK_FUNCTION: usize = 0b0000_0000_0000_0111; +const SHIFT_FUNCTION: usize = 0; +impl BusDeviceFunction { + pub fn new(bus: usize, device: usize, function: usize) -> Result { + if !(0..256).contains(&bus) || !(0..32).contains(&device) || !(0..8).contains(&function) { + Err("PCI bus device function out of range") + } else { + Ok(Self { + id: ((bus << SHIFT_BUS) | (device << SHIFT_DEVICE) | (function << SHIFT_FUNCTION)) + as u16, + }) + } + } + pub fn bus(&self) -> usize { + ((self.id as usize) & MASK_BUS) >> SHIFT_BUS + } + pub fn device(&self) -> usize { + ((self.id as usize) & MASK_DEVICE) >> SHIFT_DEVICE + } + pub fn function(&self) -> usize { + ((self.id as usize) & MASK_FUNCTION) >> SHIFT_FUNCTION + } + pub fn iter() -> BusDeviceFunctionIterator { + BusDeviceFunctionIterator { next_id: 0 } + } + pub fn fmt_common(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "/pci/bus/{:#04X}/device/{:#04X}/function/{:#03X}", + self.bus(), + self.device(), + self.function() + ) + } +} +impl fmt::Debug for BusDeviceFunction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.fmt_common(f) + } +} +impl fmt::Display for BusDeviceFunction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.fmt_common(f) + } +} +pub struct BusDeviceFunctionIterator { + next_id: usize, +} +impl Iterator for BusDeviceFunctionIterator { + type Item = BusDeviceFunction; + fn next(&mut self) -> Option { + let id = self.next_id; + if id > 0xffff { + None + } else { + self.next_id += 1; + let id = id as u16; + Some(BusDeviceFunction { id }) + } + } +} + +struct ConfigRegisters { + access_type: PhantomData, +} +impl ConfigRegisters { + fn read(ecm_base: *mut T, byte_offset: usize) -> Result { + if !(0..256).contains(&byte_offset) || byte_offset % size_of::() != 0 { + Err("PCI ConfigRegisters read out of range") + } else { + unsafe { Ok(read_volatile(ecm_base.add(byte_offset / size_of::()))) } + } + } +} + +pub struct Pci { + ecm_ragne: Range, +} +impl Pci { + pub fn new(mcfg: &AcpiMcfgDescriptor) -> Self { + // To simpify, assume that there is one mcfg entry that maps all the + // pci configuration spaces. + assert!(mcfg.num_of_entries() == 1); + let pci_config_space_base = mcfg.entry(0).expect("Out of range").base_address() as usize; + let pci_config_space_end = pci_config_space_base + (1 << 24); + Self { + ecm_ragne: pci_config_space_base..pci_config_space_end, + } + } + pub fn ecm_base(&self, id: BusDeviceFunction) -> *mut T { + (self.ecm_ragne.start + ((id.id as usize) << 12)) as *mut T + } + pub fn read_register_u16(&self, bdf: BusDeviceFunction, byte_offset: usize) -> Result { + ConfigRegisters::read(self.ecm_base(bdf), byte_offset) + } + pub fn read_vendor_id_and_device_id(&self, id: BusDeviceFunction) -> Option { + let vendor = self.read_register_u16(id, 0).ok()?; + let device = self.read_register_u16(id, 2).ok()?; + if vendor == 0xFFFF || device == 0xFFFF { + // Not connected + None + } else { + Some(VendorDeviceId { vendor, device }) + } + } + pub fn probe_devices(&self) { + for bdf in BusDeviceFunction::iter() { + if let Some(vd) = self.read_vendor_id_and_device_id(bdf) { + info!("{vd}"); + } + } + } +} From cf373a1d558ac2de29ab84ea362ac477aad10527 Mon Sep 17 00:00:00 2001 From: riii111 Date: Tue, 18 Nov 2025 22:20:18 +0900 Subject: [PATCH 4/7] chore: allow access via telnet --- wasabi/scripts/launch_qemu.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/wasabi/scripts/launch_qemu.sh b/wasabi/scripts/launch_qemu.sh index 03a392f..6bbb496 100644 --- a/wasabi/scripts/launch_qemu.sh +++ b/wasabi/scripts/launch_qemu.sh @@ -13,6 +13,7 @@ qemu-system-x86_64 \ -bios third_party/ovmf/RELEASEX64_OVMF.fd \ -machine q35 \ -drive format=raw,file=fat:rw:mnt \ + -monitor telnet:0.0.0.0:2345,server,logfile=log/qemu_monitor.txt \ -chardev stdio,id=char_com1,mux=on,logfile=log/com1.txt \ -serial chardev:char_com1 \ -device isa-debug-exit,iobase=0xf4,iosize=0x01 From 7dc932c98d3100c0ba6876c9b3bb38ac16d97ae2 Mon Sep 17 00:00:00 2001 From: riii111 Date: Tue, 18 Nov 2025 22:54:44 +0900 Subject: [PATCH 5/7] chore --- wasabi/src/acpi.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wasabi/src/acpi.rs b/wasabi/src/acpi.rs index 0bce21e..0145ddf 100644 --- a/wasabi/src/acpi.rs +++ b/wasabi/src/acpi.rs @@ -118,6 +118,8 @@ impl GenericAddress { } #[repr(packed)] +#[derive(Debug)] +#[allow(dead_code)] pub struct AcpiHpetDescriptor { header: SystemDescriptionTableHeader, _reserved0: u32, From e6e4977519150ca376b86ca1aa295ffba1e01f6d Mon Sep 17 00:00:00 2001 From: riii111 Date: Tue, 18 Nov 2025 23:48:36 +0900 Subject: [PATCH 6/7] refactor: global executor --- wasabi/scripts/launch_qemu.sh | 1 + wasabi/src/acpi.rs | 1 - wasabi/src/executor.rs | 39 +++++++++++++++++++++++++---------- wasabi/src/lib.rs | 1 + wasabi/src/main.rs | 33 ++++++++++++++--------------- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/wasabi/scripts/launch_qemu.sh b/wasabi/scripts/launch_qemu.sh index 6bbb496..5236913 100644 --- a/wasabi/scripts/launch_qemu.sh +++ b/wasabi/scripts/launch_qemu.sh @@ -16,6 +16,7 @@ qemu-system-x86_64 \ -monitor telnet:0.0.0.0:2345,server,logfile=log/qemu_monitor.txt \ -chardev stdio,id=char_com1,mux=on,logfile=log/com1.txt \ -serial chardev:char_com1 \ + -device qemu-xhci \ -device isa-debug-exit,iobase=0xf4,iosize=0x01 RETCODE=$? set -e diff --git a/wasabi/src/acpi.rs b/wasabi/src/acpi.rs index 0145ddf..44386c5 100644 --- a/wasabi/src/acpi.rs +++ b/wasabi/src/acpi.rs @@ -118,7 +118,6 @@ impl GenericAddress { } #[repr(packed)] -#[derive(Debug)] #[allow(dead_code)] pub struct AcpiHpetDescriptor { header: SystemDescriptionTableHeader, diff --git a/wasabi/src/executor.rs b/wasabi/src/executor.rs index 968746b..20214a8 100644 --- a/wasabi/src/executor.rs +++ b/wasabi/src/executor.rs @@ -1,6 +1,7 @@ extern crate alloc; use crate::hpet::global_timestamp; use crate::info; +use crate::mutex::Mutex; use crate::result::Result; use crate::x86::busy_loop_hint; use alloc::boxed::Box; @@ -19,14 +20,14 @@ use core::task::RawWakerVTable; use core::task::Waker; use core::time::Duration; -pub struct Task { +struct Task { future: Pin>>>, created_at_file: &'static str, created_at_line: u32, } impl Task { #[track_caller] - pub fn new(future: impl Future> + 'static) -> Task { + fn new(future: impl Future> + 'static) -> Task { Task { // Pin the task here to avoid invalidating the self references used in the futur3 future: Box::pin(future), @@ -52,7 +53,7 @@ fn no_op_raw_waker() -> RawWaker { let vtable = &RawWakerVTable::new(clone, no_op, no_op, no_op); RawWaker::new(null::<()>(), vtable) } -pub fn no_op_waker() -> Waker { +fn no_op_waker() -> Waker { unsafe { Waker::from_raw(no_op_raw_waker()) } } @@ -74,7 +75,7 @@ pub struct Executor { task_queue: Option>>, } impl Executor { - pub const fn new() -> Self { + const fn new() -> Self { Self { task_queue: None } } fn task_queue(&mut self) -> &mut VecDeque> { @@ -83,14 +84,14 @@ impl Executor { } self.task_queue.as_mut().unwrap() } - pub fn enqueue(&mut self, task: Task<()>) { + fn enqueue(&mut self, task: Task<()>) { self.task_queue().push_back(task) } - pub fn run(mut executor: Self) -> ! { + fn run(executor: &Mutex>) -> ! { info!("Executor starts running..."); loop { - let task = executor.task_queue().pop_front(); - if let Some(mut task) = task { + let task = executor.lock().as_mut().map(|e| e.task_queue().pop_front()); + if let Some(Some(mut task)) = task { let waker = no_op_waker(); let mut context = Context::from_waker(&waker); match task.poll(&mut context) { @@ -98,7 +99,9 @@ impl Executor { info!("Task completed: {:?}: {:?}", task, result); } Poll::Pending => { - executor.task_queue().push_back(task); + if let Some(e) = executor.lock().as_mut() { + e.task_queue().push_back(task); + } } } } @@ -112,7 +115,7 @@ impl Default for Executor { } #[derive(Default)] -pub struct Yield { +struct Yield { polled: AtomicBool, } impl Future for Yield { @@ -130,7 +133,7 @@ pub struct TimeoutFuture { time_out: Duration, } impl TimeoutFuture { - pub fn new(duration: Duration) -> Self { + fn new(duration: Duration) -> Self { Self { time_out: global_timestamp() + duration, } @@ -146,3 +149,17 @@ impl Future for TimeoutFuture { } } } +pub async fn sleep(duration: Duration) { + TimeoutFuture::new(duration).await +} + +static GLOBAL_EXECUTOR: Mutex> = Mutex::new(None); +#[track_caller] +pub fn spawn_global(future: impl Future> + 'static) { + let task = Task::new(future); + GLOBAL_EXECUTOR.lock().get_or_insert_default().enqueue(task); +} +pub fn start_global_executor() -> ! { + info!("Starting global executor loop"); + Executor::run(&GLOBAL_EXECUTOR); +} diff --git a/wasabi/src/lib.rs b/wasabi/src/lib.rs index 3660451..e4af1dc 100644 --- a/wasabi/src/lib.rs +++ b/wasabi/src/lib.rs @@ -4,6 +4,7 @@ #![feature(sync_unsafe_cell)] #![feature(const_caller_location)] #![feature(const_location_fields)] +#![feature(option_get_or_insert_default)] #![test_runner(crate::test_runner::test_runner)] #![reexport_test_harness_main = "run_unit_tests"] #![no_main] diff --git a/wasabi/src/main.rs b/wasabi/src/main.rs index c28bf87..0c845c3 100644 --- a/wasabi/src/main.rs +++ b/wasabi/src/main.rs @@ -5,9 +5,9 @@ use core::panic::PanicInfo; use core::time::Duration; use wasabi::error; -use wasabi::executor::Executor; -use wasabi::executor::Task; -use wasabi::executor::TimeoutFuture; +use wasabi::executor::sleep; +use wasabi::executor::spawn_global; +use wasabi::executor::start_global_executor; use wasabi::hpet::global_timestamp; use wasabi::info; use wasabi::init::init_allocator; @@ -56,21 +56,21 @@ fn efi_main(image_handle: EfiHandle, efi_system_table: &EfiSystemTable) { init_hpet(acpi); init_pci(acpi); let t0 = global_timestamp(); - let task1 = Task::new(async move { + let task1 = async move { for i in 100..=103 { info!("{i} hpet.main_counter = {:?}", global_timestamp() - t0); - TimeoutFuture::new(Duration::from_secs(1)).await; + sleep(Duration::from_secs(1)).await; } Ok(()) - }); - let task2 = Task::new(async move { + }; + let task2 = async move { for i in 200..=203 { info!("{i} hpet.main_counter = {:?}", global_timestamp() - t0); - TimeoutFuture::new(Duration::from_secs(2)).await; + sleep(Duration::from_secs(2)).await; } Ok(()) - }); - let serial_task = Task::new(async { + }; + let serial_task = async { let sp = SerialPort::default(); if let Err(e) = sp.loopback_test() { error!("{e:?}"); @@ -82,14 +82,13 @@ fn efi_main(image_handle: EfiHandle, efi_system_table: &EfiSystemTable) { let c = char::from_u32(v as u32); info!("serial input: {v:#04X} = {c:?}"); } - TimeoutFuture::new(Duration::from_millis(20)).await; + sleep(Duration::from_millis(20)).await; } - }); - let mut executor = Executor::new(); - executor.enqueue(task1); - executor.enqueue(task2); - executor.enqueue(serial_task); - Executor::run(executor) + }; + spawn_global(task1); + spawn_global(task2); + spawn_global(serial_task); + start_global_executor() } #[panic_handler] From a18df175a59338f1b2447227c847e26d9ca5278e Mon Sep 17 00:00:00 2001 From: riii111 Date: Tue, 18 Nov 2025 23:57:35 +0900 Subject: [PATCH 7/7] refactor: init page table --- wasabi/src/x86.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/wasabi/src/x86.rs b/wasabi/src/x86.rs index d60844a..3eaf194 100644 --- a/wasabi/src/x86.rs +++ b/wasabi/src/x86.rs @@ -68,11 +68,11 @@ pub enum TranslationResult { } #[repr(transparent)] -pub struct Entry { +pub struct Entry { value: u64, next_type: PhantomData, } -impl Entry { +impl Entry { fn read_value(&self) -> u64 { self.value } @@ -137,22 +137,22 @@ impl Entry { } } } -impl fmt::Display for Entry { +impl fmt::Display for Entry { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } -impl fmt::Debug for Entry { +impl fmt::Debug for Entry { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } #[repr(align(4096))] -pub struct Table { - entry: [Entry; 512], +pub struct Table { + entry: [Entry; 512], } -impl Table { +impl Table { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "L{}Table @ {:#p} {{", LEVEL, self)?; for i in 0..512 { @@ -164,25 +164,26 @@ impl Table usize { + (LEVEL - 1) * 9 + 12 + } pub fn next_level(&self, index: usize) -> Option<&NEXT> { self.entry.get(index).and_then(|e| e.table().ok()) } fn calc_index(&self, addr: u64) -> usize { - ((addr >> SHIFT) & 0b1_1111_1111) as usize + ((addr >> Self::index_shift()) & 0b1_1111_1111) as usize } } -impl fmt::Debug - for Table -{ +impl fmt::Debug for Table { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.format(f) } } -pub type PT = Table<1, 12, [u8; PAGE_SIZE]>; -pub type PD = Table<2, 21, PT>; -pub type PDPT = Table<3, 30, PD>; -pub type PML4 = Table<4, 39, PDPT>; +pub type PT = Table<1, [u8; PAGE_SIZE]>; +pub type PD = Table<2, PT>; +pub type PDPT = Table<3, PD>; +pub type PML4 = Table<4, PDPT>; impl PML4 { pub fn new() -> Box {