From 4f3c2ebea31d4ddd87ccf73b7a49097622c793a0 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Thu, 6 Jul 2023 20:13:56 +0800 Subject: [PATCH 01/12] get irqnum support for x86_64 virtio dev --- Cargo.lock | 83 ++++++ modules/axconfig/src/platform/pc-x86.toml | 1 + modules/axhal/Cargo.toml | 2 + modules/axhal/src/arch/x86_64/mod.rs | 3 +- modules/axhal/src/arch/x86_64/trap.rs | 9 + modules/axhal/src/lib.rs | 5 +- modules/axhal/src/platform/pc_x86/acpi.rs | 330 ++++++++++++++++++++++ modules/axhal/src/platform/pc_x86/apic.rs | 23 ++ modules/axhal/src/platform/pc_x86/mod.rs | 2 + 9 files changed, 456 insertions(+), 2 deletions(-) create mode 100644 modules/axhal/src/platform/pc_x86/acpi.rs diff --git a/Cargo.lock b/Cargo.lock index d23373f06d..5a0454c37f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,17 @@ dependencies = [ "tock-registers", ] +[[package]] +name = "acpi" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "654f48ab3178632ea535be1765073b990895cb62f70a7e5671975d7150c26d15" +dependencies = [ + "bit_field", + "log", + "rsdp", +] + [[package]] name = "allocator" version = "0.1.0" @@ -20,6 +31,19 @@ dependencies = [ "slab_allocator", ] +[[package]] +name = "aml" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f8cba7d4260ea05671dda81029f6f718b54402a4ec926a0d9a41bdbb96b415" +dependencies = [ + "bit_field", + "bitvec", + "byteorder", + "log", + "spinning_top", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -279,6 +303,8 @@ name = "axhal" version = "0.1.0" dependencies = [ "aarch64-cpu", + "acpi", + "aml", "arm_gic", "arm_pl011", "axalloc", @@ -458,6 +484,18 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703642b98a00b3b90513279a8ede3fcfa479c126c5fb46e78f3051522f021403" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "buddy_system_allocator" version = "0.9.0" @@ -771,6 +809,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "getrandom" version = "0.2.10" @@ -1202,6 +1246,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" @@ -1289,6 +1339,15 @@ dependencies = [ "embedded-hal", ] +[[package]] +name = "rsdp" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d3add2fc55ef37511bcf81a08ee7a09eff07b23aae38b06a29024a38c604b1" +dependencies = [ + "log", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -1449,6 +1508,15 @@ dependencies = [ "kernel_guard", ] +[[package]] +name = "spinning_top" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1489,6 +1557,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.6.0" @@ -1820,6 +1894,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x2apic" version = "0.4.2" diff --git a/modules/axconfig/src/platform/pc-x86.toml b/modules/axconfig/src/platform/pc-x86.toml index d06e5ce352..24561fef36 100644 --- a/modules/axconfig/src/platform/pc-x86.toml +++ b/modules/axconfig/src/platform/pc-x86.toml @@ -21,6 +21,7 @@ mmio-regions = [ ["0xfec0_0000", "0x1000"], # IO APIC ["0xfed0_0000", "0x1000"], # HPET ["0xfee0_0000", "0x1000"], # Local APIC + ["0xe_0000", "0x2_0000"], #ACPI ] # VirtIO MMIO regions with format (`base_paddr`, `size`). virtio-mmio-regions = [] diff --git a/modules/axhal/Cargo.toml b/modules/axhal/Cargo.toml index f30079a50c..5de30e580c 100644 --- a/modules/axhal/Cargo.toml +++ b/modules/axhal/Cargo.toml @@ -50,6 +50,8 @@ x86 = "0.52" x86_64 = "0.14" x2apic = "0.4" raw-cpuid = "11.0" +acpi = "4.1.1" +aml = "0.16.4" [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] riscv = "0.10" diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index 5a51ac620b..92fde501e1 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -2,7 +2,7 @@ mod context; mod gdt; mod idt; -#[cfg(target_os = "none")] +// #[cfg(target_os = "none")] mod trap; use core::arch::asm; @@ -15,6 +15,7 @@ pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame}; pub use self::gdt::GdtStruct; pub use self::idt::IdtStruct; pub use x86_64::structures::tss::TaskStateSegment; +pub use self::trap::{irq_to_vector,vector_to_irq}; /// Allows the current CPU to respond to interrupts. #[inline] diff --git a/modules/axhal/src/arch/x86_64/trap.rs b/modules/axhal/src/arch/x86_64/trap.rs index 121a6864f9..60df0658a6 100644 --- a/modules/axhal/src/arch/x86_64/trap.rs +++ b/modules/axhal/src/arch/x86_64/trap.rs @@ -44,3 +44,12 @@ fn x86_trap_handler(tf: &mut TrapFrame) { } } } + +/// map external IRQ to vector +pub fn irq_to_vector(irq:u8)->usize{ + (irq + IRQ_VECTOR_START )as usize +} +/// map vector to external IRQ +pub fn vector_to_irq(vector:usize)->u8{ + vector as u8 - IRQ_VECTOR_START +} diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index f8201362fd..b1afa6d5af 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -31,12 +31,15 @@ #![feature(naked_functions)] #![feature(const_maybe_uninit_zeroed)] #![feature(doc_auto_cfg)] +#![feature(allocator_api)] +#![feature(alloc_layout_extra)] #[allow(unused_imports)] #[macro_use] extern crate log; +extern crate alloc; -mod platform; +pub mod platform; pub mod arch; pub mod cpu; diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs new file mode 100644 index 0000000000..b34e73b99b --- /dev/null +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -0,0 +1,330 @@ +extern crate alloc; + +use alloc::boxed::Box; +use alloc::format; +use core::alloc::{AllocError, Layout}; +use core::ptr::NonNull; + +use acpi::{AcpiTables, PhysicalMapping}; +use aml::{AmlContext, AmlName, DebugVerbosity}; +use aml::pci_routing::{IrqDescriptor, PciRoutingTable, Pin}; + +use axalloc::global_allocator; +use lazy_init::LazyInit; +use memory_addr::PhysAddr; +use crate::mem::phys_to_virt; + +use crate::arch::irq_to_vector; + +#[derive(Clone)] +struct LocalAcpiHandler; + +impl acpi::AcpiHandler for LocalAcpiHandler { + unsafe fn map_physical_region( + &self, + physical_address: usize, + size: usize, + ) -> PhysicalMapping { + let vaddr = phys_to_virt(PhysAddr::from(physical_address)).as_usize(); + PhysicalMapping::new( + physical_address, + NonNull::new_unchecked(vaddr as *mut i32 as *mut _), + size, + size, + self.clone(), + ) + } + fn unmap_physical_region(_region: &PhysicalMapping) {} +} + +struct LocalAmlHandler; + +impl aml::Handler for LocalAmlHandler { + fn read_u8(&self, address: usize) -> u8 { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_ptr(); + unsafe { vaddr.read_volatile() } + } + + fn read_u16(&self, address: usize) -> u16 { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_ptr() as *const u16; + unsafe { vaddr.read_volatile() } + } + + fn read_u32(&self, address: usize) -> u32 { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_ptr() as *const u32; + unsafe { vaddr.read_volatile() } + } + + fn read_u64(&self, address: usize) -> u64 { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_ptr() as *const u64; + unsafe { vaddr.read_volatile() } + } + + fn write_u8(&mut self, address: usize, value: u8) { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_mut_ptr(); + unsafe { vaddr.write_volatile(value) } + } + + fn write_u16(&mut self, address: usize, value: u16) { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_mut_ptr() as *mut u16; + unsafe { vaddr.write_volatile(value) } + } + + fn write_u32(&mut self, address: usize, value: u32) { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_mut_ptr() as *mut u32; + unsafe { vaddr.write_volatile(value) } + } + + fn write_u64(&mut self, address: usize, value: u64) { + let vaddr = phys_to_virt(PhysAddr::from(address)).as_mut_ptr() as *mut u64; + unsafe { vaddr.write_volatile(value) } + } + + fn read_io_u8(&self, port: u16) -> u8 { + unsafe { x86::io::inb(port) } + } + + fn read_io_u16(&self, port: u16) -> u16 { + unsafe { x86::io::inw(port) } + } + + fn read_io_u32(&self, port: u16) -> u32 { + unsafe { x86::io::inl(port) } + } + + fn write_io_u8(&self, port: u16, value: u8) { + unsafe { + x86::io::outb(port, value); + } + } + + fn write_io_u16(&self, port: u16, value: u16) { + unsafe { + x86::io::outw(port, value); + } + } + + fn write_io_u32(&self, port: u16, value: u32) { + unsafe { + x86::io::outl(port, value); + } + } + + fn read_pci_u8(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16) -> u8 { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u8; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.read_volatile() } + } + + fn read_pci_u16(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16) -> u16 { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u16; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.read_volatile() } + } + + fn read_pci_u32(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16) -> u32 { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u32; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.read_volatile() } + } + + fn write_pci_u8(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u8) { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u8; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.write_volatile(value) } + } + + fn write_pci_u16(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u16) { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u16; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.write_volatile(value) } + } + + fn write_pci_u32(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u32) { + let paddr = unsafe { + ACPI.get_pci_config_regions_addr(segment, bus, device, function) + .unwrap() + }; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u32; + let address = unsafe { vaddr.add(offset as usize) }; + unsafe { address.write_volatile(value) } + } +} + +#[derive(Clone, Debug)] +struct LocalAllocator; + +unsafe impl core::alloc::Allocator for LocalAllocator { + fn allocate(&self, layout: Layout) -> Result, AllocError> { + match layout.size() { + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + size => { + let raw_ptr = global_allocator() + .alloc(layout.size(), layout.align()) + .unwrap() as *mut u8; + let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; + Ok(NonNull::slice_from_raw_parts(ptr, size)) + } + } + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + if layout.size() != 0 { + global_allocator().dealloc(ptr.as_ptr() as usize, layout.size(), layout.align()) + } + } +} + +struct Acpi { + rsdp: AcpiTables, + aml_context: AmlContext, +} + +/// irq model used in ACPI +pub enum X86IrqModel { + /// PIC model + PIC, + /// APIC model + APIC, +} + +impl Acpi { + pub unsafe fn new() -> Self { + Acpi { + rsdp: AcpiTables::search_for_rsdp_bios(LocalAcpiHandler).unwrap(), + aml_context: AmlContext::new(Box::new(LocalAmlHandler), DebugVerbosity::None), + } + } + + fn init(&mut self) -> bool { + let dsdt = self.rsdp.dsdt.as_ref().unwrap(); + let paddr = PhysAddr::from(dsdt.address); + let vaddr = phys_to_virt(paddr).as_ptr(); + let slice = unsafe { + core::slice::from_raw_parts_mut(vaddr as *mut u8, dsdt.length as usize) + }; + if self.aml_context.parse_table(slice).is_err() { + return false; + } + self.set_irq_model(X86IrqModel::APIC) + } + + /// Set IRQ model that ACPI uses by invoking ACPI global method _PIC. + /// + /// This method changes the routing tables (PIC or APIC) to return when calling _PRT methods. + /// Since this method changes ACPI state, it could lead to concurrent problem. + /// But currently it is only invoked in init thus runs by primary cpu only. + /// We may need a lock for ACPI in the future as more ACPI state altering method implemented. + fn set_irq_model(&mut self, irq_model: X86IrqModel) -> bool { + let value = match irq_model { + X86IrqModel::PIC => 0, + X86IrqModel::APIC => 1, + }; + let mut arg = aml::value::Args::EMPTY; + if arg.store_arg(0, aml::AmlValue::Integer(value)).is_err() { + return false; + } + let result = self + .aml_context + .invoke_method(&AmlName::from_str("\\_PIC").unwrap(), arg); + if let Err(err) = result { + error!("set_irq_model failed:{:#?}", err); + return false; + } + true + } + + /// Get PCI IRQ by invoking device _PRT method. + /// + /// Each PCI bus that ACPI provides interrupt routing information for appears as a device + /// in the ACPI namespace. + /// Each of these devices contains a _PRT method that returns an array of objects describing + /// the interrupt routing for slots on that PCI bus. + fn get_pci_irq_desc(&mut self, bus: u8, device: u8, function: u8) -> Option { + match AmlName::from_str(format!("\\_SB.PCI{bus_id}._PRT", bus_id = bus).as_str()) { + Ok(prt_path) => { + match PciRoutingTable::from_prt_path(&prt_path, &mut self.aml_context) { + Ok(table) => { + if let Ok(irq_descriptor) = table.route( + device as u16, + function as u16, + Pin::IntA, + &mut self.aml_context, + ) { + Some(irq_descriptor) + } else { + None + } + } + Err(_) => None, + } + } + Err(_) => None, + } + } + + /// Get base physical address of the PCIe ECAM space from ACPI MCFG table. + /// + /// Currently the ACPI crate does not export MCFG internal structure, thus we can not get ECAM + /// space address directly. This method get configuration space address of bdf(0:0:0) instead. + fn get_ecam_address(&mut self) -> Option { + if let Ok(config) = acpi::mcfg::PciConfigRegions::new(&self.rsdp) { + return Some(config.physical_address(0, 0, 0, 0).unwrap() ); + } + None + } + + /// Get PCIe configuration space physical address of device function. + fn get_pci_config_regions_addr( + &mut self, + segment_group_no: u16, + bus: u8, + device: u8, + function: u8, + ) -> Option { + if let Ok(config) = acpi::mcfg::PciConfigRegions::new(&self.rsdp) { + return config.physical_address(segment_group_no, bus, device, function); + } + None + } +} + +static mut ACPI: LazyInit = LazyInit::new(); + +pub(crate) fn init() { + unsafe { + let mut acpi = Acpi::new(); + acpi.init(); + ACPI.init_by(acpi); + } +} + +/// Get PCI IRQ and map it to vector used in OS. +pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { + unsafe { ACPI.get_pci_irq_desc(bus, device, function) }.map(|irq_desc| irq_to_vector(irq_desc.irq as u8)) +} + +/// Get PCIe ECAM space physical address. +pub fn get_ecam_address() -> Option { + unsafe { ACPI.get_ecam_address() } +} \ No newline at end of file diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index eb4e3e5930..76ce63ca83 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -10,6 +10,13 @@ use x86_64::instructions::port::Port; use self::vectors::*; use crate::mem::phys_to_virt; +#[cfg(feature = "irq")] +use crate::platform::pc_x86::current_cpu_id; +#[cfg(feature = "irq")] +use x2apic::ioapic::{IrqFlags, IrqMode}; +#[cfg(feature = "irq")] +use crate::arch::{vector_to_irq}; + pub(super) mod vectors { pub const APIC_TIMER_VECTOR: u8 = 0xf0; pub const APIC_SPURIOUS_VECTOR: u8 = 0xf1; @@ -43,12 +50,28 @@ pub fn set_enable(vector: usize, enabled: bool) { } } +/// Program IO_APIC in order to route IO_APIC IRQ to vector. +#[cfg(feature = "irq")] +fn ioapic_redirect(vector:usize){ + let irq = vector_to_irq(vector); + let mut table_entry = unsafe{IO_APIC.lock().table_entry(irq)}; + table_entry.set_vector(vector as u8); + table_entry.set_mode(IrqMode::Fixed); + let irq_flag = table_entry.flags() - IrqFlags::MASKED; + table_entry.set_flags(irq_flag); + table_entry.set_dest(current_cpu_id() as u8); + unsafe{IO_APIC.lock().set_table_entry(irq, table_entry)}; +} + /// Registers an IRQ handler for the given IRQ. /// /// It also enables the IRQ if the registration succeeds. It returns `false` if /// the registration failed. #[cfg(feature = "irq")] pub fn register_handler(vector: usize, handler: crate::irq::IrqHandler) -> bool { + if vector < APIC_TIMER_VECTOR as _ { + ioapic_redirect(vector); + } crate::irq::register_handler_common(vector, handler) } diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index ba3ce43630..a3ff90f24e 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -6,6 +6,7 @@ mod uart16550; pub mod mem; pub mod misc; pub mod time; +pub mod acpi; #[cfg(feature = "smp")] pub mod mp; @@ -58,6 +59,7 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); + self::acpi::init(); } /// Initializes the platform devices for secondary CPUs. From 2341d4f2d0dde15b960532e4af0b77b04fc1ceb1 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Thu, 6 Jul 2023 20:48:26 +0800 Subject: [PATCH 02/12] fix CI --- modules/axhal/src/lib.rs | 3 --- modules/axhal/src/platform/pc_x86/mod.rs | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index b1afa6d5af..3f533c3a1d 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -31,13 +31,10 @@ #![feature(naked_functions)] #![feature(const_maybe_uninit_zeroed)] #![feature(doc_auto_cfg)] -#![feature(allocator_api)] -#![feature(alloc_layout_extra)] #[allow(unused_imports)] #[macro_use] extern crate log; -extern crate alloc; pub mod platform; diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index a3ff90f24e..959357cc03 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -6,6 +6,7 @@ mod uart16550; pub mod mem; pub mod misc; pub mod time; +#[cfg(feature = "alloc")] pub mod acpi; #[cfg(feature = "smp")] @@ -59,6 +60,7 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); + #[cfg(feature = "alloc")] self::acpi::init(); } From 9e22940c0d18562f64b636d382377a87b906ed20 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Thu, 6 Jul 2023 20:59:35 +0800 Subject: [PATCH 03/12] fix clippy --- modules/axhal/src/arch/x86_64/mod.rs | 2 +- modules/axhal/src/arch/x86_64/trap.rs | 6 +-- modules/axhal/src/platform/pc_x86/acpi.rs | 46 +++++++++++++++++------ modules/axhal/src/platform/pc_x86/apic.rs | 10 ++--- modules/axhal/src/platform/pc_x86/mod.rs | 4 +- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index 92fde501e1..5f1c64faeb 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -14,8 +14,8 @@ use x86_64::instructions::interrupts; pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame}; pub use self::gdt::GdtStruct; pub use self::idt::IdtStruct; +pub use self::trap::{irq_to_vector, vector_to_irq}; pub use x86_64::structures::tss::TaskStateSegment; -pub use self::trap::{irq_to_vector,vector_to_irq}; /// Allows the current CPU to respond to interrupts. #[inline] diff --git a/modules/axhal/src/arch/x86_64/trap.rs b/modules/axhal/src/arch/x86_64/trap.rs index 60df0658a6..d38bcae0b6 100644 --- a/modules/axhal/src/arch/x86_64/trap.rs +++ b/modules/axhal/src/arch/x86_64/trap.rs @@ -46,10 +46,10 @@ fn x86_trap_handler(tf: &mut TrapFrame) { } /// map external IRQ to vector -pub fn irq_to_vector(irq:u8)->usize{ - (irq + IRQ_VECTOR_START )as usize +pub fn irq_to_vector(irq: u8) -> usize { + (irq + IRQ_VECTOR_START) as usize } /// map vector to external IRQ -pub fn vector_to_irq(vector:usize)->u8{ +pub fn vector_to_irq(vector: usize) -> u8 { vector as u8 - IRQ_VECTOR_START } diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index b34e73b99b..02693c787e 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -6,13 +6,13 @@ use core::alloc::{AllocError, Layout}; use core::ptr::NonNull; use acpi::{AcpiTables, PhysicalMapping}; -use aml::{AmlContext, AmlName, DebugVerbosity}; use aml::pci_routing::{IrqDescriptor, PciRoutingTable, Pin}; +use aml::{AmlContext, AmlName, DebugVerbosity}; +use crate::mem::phys_to_virt; use axalloc::global_allocator; use lazy_init::LazyInit; use memory_addr::PhysAddr; -use crate::mem::phys_to_virt; use crate::arch::irq_to_vector; @@ -140,7 +140,15 @@ impl aml::Handler for LocalAmlHandler { unsafe { address.read_volatile() } } - fn write_pci_u8(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u8) { + fn write_pci_u8( + &self, + segment: u16, + bus: u8, + device: u8, + function: u8, + offset: u16, + value: u8, + ) { let paddr = unsafe { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() @@ -150,7 +158,15 @@ impl aml::Handler for LocalAmlHandler { unsafe { address.write_volatile(value) } } - fn write_pci_u16(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u16) { + fn write_pci_u16( + &self, + segment: u16, + bus: u8, + device: u8, + function: u8, + offset: u16, + value: u16, + ) { let paddr = unsafe { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() @@ -160,7 +176,15 @@ impl aml::Handler for LocalAmlHandler { unsafe { address.write_volatile(value) } } - fn write_pci_u32(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u32) { + fn write_pci_u32( + &self, + segment: u16, + bus: u8, + device: u8, + function: u8, + offset: u16, + value: u32, + ) { let paddr = unsafe { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() @@ -220,9 +244,8 @@ impl Acpi { let dsdt = self.rsdp.dsdt.as_ref().unwrap(); let paddr = PhysAddr::from(dsdt.address); let vaddr = phys_to_virt(paddr).as_ptr(); - let slice = unsafe { - core::slice::from_raw_parts_mut(vaddr as *mut u8, dsdt.length as usize) - }; + let slice = + unsafe { core::slice::from_raw_parts_mut(vaddr as *mut u8, dsdt.length as usize) }; if self.aml_context.parse_table(slice).is_err() { return false; } @@ -289,7 +312,7 @@ impl Acpi { /// space address directly. This method get configuration space address of bdf(0:0:0) instead. fn get_ecam_address(&mut self) -> Option { if let Ok(config) = acpi::mcfg::PciConfigRegions::new(&self.rsdp) { - return Some(config.physical_address(0, 0, 0, 0).unwrap() ); + return Some(config.physical_address(0, 0, 0, 0).unwrap()); } None } @@ -321,10 +344,11 @@ pub(crate) fn init() { /// Get PCI IRQ and map it to vector used in OS. pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { - unsafe { ACPI.get_pci_irq_desc(bus, device, function) }.map(|irq_desc| irq_to_vector(irq_desc.irq as u8)) + unsafe { ACPI.get_pci_irq_desc(bus, device, function) } + .map(|irq_desc| irq_to_vector(irq_desc.irq as u8)) } /// Get PCIe ECAM space physical address. pub fn get_ecam_address() -> Option { unsafe { ACPI.get_ecam_address() } -} \ No newline at end of file +} diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index 76ce63ca83..6187e2e7e1 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -10,12 +10,12 @@ use x86_64::instructions::port::Port; use self::vectors::*; use crate::mem::phys_to_virt; +#[cfg(feature = "irq")] +use crate::arch::vector_to_irq; #[cfg(feature = "irq")] use crate::platform::pc_x86::current_cpu_id; #[cfg(feature = "irq")] use x2apic::ioapic::{IrqFlags, IrqMode}; -#[cfg(feature = "irq")] -use crate::arch::{vector_to_irq}; pub(super) mod vectors { pub const APIC_TIMER_VECTOR: u8 = 0xf0; @@ -52,15 +52,15 @@ pub fn set_enable(vector: usize, enabled: bool) { /// Program IO_APIC in order to route IO_APIC IRQ to vector. #[cfg(feature = "irq")] -fn ioapic_redirect(vector:usize){ +fn ioapic_redirect(vector: usize) { let irq = vector_to_irq(vector); - let mut table_entry = unsafe{IO_APIC.lock().table_entry(irq)}; + let mut table_entry = unsafe { IO_APIC.lock().table_entry(irq) }; table_entry.set_vector(vector as u8); table_entry.set_mode(IrqMode::Fixed); let irq_flag = table_entry.flags() - IrqFlags::MASKED; table_entry.set_flags(irq_flag); table_entry.set_dest(current_cpu_id() as u8); - unsafe{IO_APIC.lock().set_table_entry(irq, table_entry)}; + unsafe { IO_APIC.lock().set_table_entry(irq, table_entry) }; } /// Registers an IRQ handler for the given IRQ. diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index 959357cc03..3b8ca1ac5f 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -3,11 +3,11 @@ mod boot; mod dtables; mod uart16550; +#[cfg(feature = "alloc")] +pub mod acpi; pub mod mem; pub mod misc; pub mod time; -#[cfg(feature = "alloc")] -pub mod acpi; #[cfg(feature = "smp")] pub mod mp; From cf9ac39586efa6f9ffd6d034f901d3ed4d2763ff Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Thu, 6 Jul 2023 21:08:01 +0800 Subject: [PATCH 04/12] fix doc --- modules/axhal/src/platform/pc_x86/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index 3b8ca1ac5f..832ac95360 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -3,20 +3,27 @@ mod boot; mod dtables; mod uart16550; +/// acpi module #[cfg(feature = "alloc")] pub mod acpi; +/// mem module pub mod mem; +/// misc module pub mod misc; +/// time module pub mod time; +/// mp module #[cfg(feature = "smp")] pub mod mp; +/// irq module #[cfg(feature = "irq")] pub mod irq { pub use super::apic::*; } +/// console module pub mod console { pub use super::uart16550::*; } From 3f9683fb70bf35ed13153e3838304af5b0d729d0 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Tue, 11 Jul 2023 21:51:04 +0800 Subject: [PATCH 05/12] modify according to review --- modules/axhal/src/arch/x86_64/mod.rs | 2 +- modules/axhal/src/arch/x86_64/trap.rs | 12 ++----- modules/axhal/src/lib.rs | 2 +- modules/axhal/src/platform/pc_x86/acpi.rs | 44 +++++++---------------- modules/axhal/src/platform/pc_x86/apic.rs | 15 ++++++-- modules/axhal/src/platform/pc_x86/mod.rs | 4 +-- 6 files changed, 31 insertions(+), 48 deletions(-) diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index 5f1c64faeb..cd1914dc6d 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -14,7 +14,7 @@ use x86_64::instructions::interrupts; pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame}; pub use self::gdt::GdtStruct; pub use self::idt::IdtStruct; -pub use self::trap::{irq_to_vector, vector_to_irq}; +pub use self::trap::{IRQ_VECTOR_START, IRQ_VECTOR_END}; pub use x86_64::structures::tss::TaskStateSegment; /// Allows the current CPU to respond to interrupts. diff --git a/modules/axhal/src/arch/x86_64/trap.rs b/modules/axhal/src/arch/x86_64/trap.rs index d38bcae0b6..0d31a179fa 100644 --- a/modules/axhal/src/arch/x86_64/trap.rs +++ b/modules/axhal/src/arch/x86_64/trap.rs @@ -4,8 +4,8 @@ use super::context::TrapFrame; core::arch::global_asm!(include_str!("trap.S")); -const IRQ_VECTOR_START: u8 = 0x20; -const IRQ_VECTOR_END: u8 = 0xff; +pub const IRQ_VECTOR_START: u8 = 0x20; +pub const IRQ_VECTOR_END: u8 = 0xff; #[no_mangle] fn x86_trap_handler(tf: &mut TrapFrame) { @@ -45,11 +45,3 @@ fn x86_trap_handler(tf: &mut TrapFrame) { } } -/// map external IRQ to vector -pub fn irq_to_vector(irq: u8) -> usize { - (irq + IRQ_VECTOR_START) as usize -} -/// map vector to external IRQ -pub fn vector_to_irq(vector: usize) -> u8 { - vector as u8 - IRQ_VECTOR_START -} diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index 3f533c3a1d..f8201362fd 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -36,7 +36,7 @@ #[macro_use] extern crate log; -pub mod platform; +mod platform; pub mod arch; pub mod cpu; diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index 02693c787e..4312e9add1 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -2,7 +2,6 @@ extern crate alloc; use alloc::boxed::Box; use alloc::format; -use core::alloc::{AllocError, Layout}; use core::ptr::NonNull; use acpi::{AcpiTables, PhysicalMapping}; @@ -10,11 +9,11 @@ use aml::pci_routing::{IrqDescriptor, PciRoutingTable, Pin}; use aml::{AmlContext, AmlName, DebugVerbosity}; use crate::mem::phys_to_virt; -use axalloc::global_allocator; use lazy_init::LazyInit; use memory_addr::PhysAddr; -use crate::arch::irq_to_vector; +#[cfg(feature = "irq")] +use crate::platform::irq::irq_to_vector; #[derive(Clone)] struct LocalAcpiHandler; @@ -115,7 +114,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u8; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_mut_ptr(); let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.read_volatile() } } @@ -153,7 +152,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u8; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_mut_ptr(); let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.write_volatile(value) } } @@ -195,37 +194,14 @@ impl aml::Handler for LocalAmlHandler { } } -#[derive(Clone, Debug)] -struct LocalAllocator; - -unsafe impl core::alloc::Allocator for LocalAllocator { - fn allocate(&self, layout: Layout) -> Result, AllocError> { - match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), - size => { - let raw_ptr = global_allocator() - .alloc(layout.size(), layout.align()) - .unwrap() as *mut u8; - let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; - Ok(NonNull::slice_from_raw_parts(ptr, size)) - } - } - } - - unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - if layout.size() != 0 { - global_allocator().dealloc(ptr.as_ptr() as usize, layout.size(), layout.align()) - } - } -} - struct Acpi { rsdp: AcpiTables, aml_context: AmlContext, } /// irq model used in ACPI -pub enum X86IrqModel { +#[allow(dead_code)] +enum X86IrqModel { /// PIC model PIC, /// APIC model @@ -243,9 +219,9 @@ impl Acpi { fn init(&mut self) -> bool { let dsdt = self.rsdp.dsdt.as_ref().unwrap(); let paddr = PhysAddr::from(dsdt.address); - let vaddr = phys_to_virt(paddr).as_ptr(); + let vaddr = phys_to_virt(paddr).as_mut_ptr(); let slice = - unsafe { core::slice::from_raw_parts_mut(vaddr as *mut u8, dsdt.length as usize) }; + unsafe { core::slice::from_raw_parts_mut(vaddr, dsdt.length as usize) }; if self.aml_context.parse_table(slice).is_err() { return false; } @@ -343,12 +319,16 @@ pub(crate) fn init() { } /// Get PCI IRQ and map it to vector used in OS. +/// Temporarily allow unused here because irq support for virtio hasn't ready yet. +#[allow(dead_code)] +#[cfg(feature = "irq")] pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { unsafe { ACPI.get_pci_irq_desc(bus, device, function) } .map(|irq_desc| irq_to_vector(irq_desc.irq as u8)) } /// Get PCIe ECAM space physical address. +#[allow(dead_code)] pub fn get_ecam_address() -> Option { unsafe { ACPI.get_ecam_address() } } diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index 6187e2e7e1..e1c31e156a 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -10,13 +10,24 @@ use x86_64::instructions::port::Port; use self::vectors::*; use crate::mem::phys_to_virt; -#[cfg(feature = "irq")] -use crate::arch::vector_to_irq; #[cfg(feature = "irq")] use crate::platform::pc_x86::current_cpu_id; #[cfg(feature = "irq")] use x2apic::ioapic::{IrqFlags, IrqMode}; +#[cfg(feature = "irq")] +use crate::arch::{IRQ_VECTOR_START}; +/// map external IRQ to vector +#[cfg(feature = "irq")] +pub fn irq_to_vector(irq: u8) -> usize { + (irq + IRQ_VECTOR_START) as usize +} +/// map vector to external IRQ +#[cfg(feature = "irq")] +pub fn vector_to_irq(vector: usize) -> u8 { + vector as u8 - IRQ_VECTOR_START +} + pub(super) mod vectors { pub const APIC_TIMER_VECTOR: u8 = 0xf0; pub const APIC_SPURIOUS_VECTOR: u8 = 0xf1; diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index 832ac95360..c7a5834ffd 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -4,7 +4,7 @@ mod dtables; mod uart16550; /// acpi module -#[cfg(feature = "alloc")] +#[cfg(feature = "irq")] pub mod acpi; /// mem module pub mod mem; @@ -67,7 +67,7 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); - #[cfg(feature = "alloc")] + #[cfg(feature = "irq")] self::acpi::init(); } From 4ece66bbb58df1bcfd4af53afee57c970eb6f832 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Tue, 11 Jul 2023 21:56:13 +0800 Subject: [PATCH 06/12] fix doc --- modules/axhal/src/arch/x86_64/trap.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/axhal/src/arch/x86_64/trap.rs b/modules/axhal/src/arch/x86_64/trap.rs index 0d31a179fa..9b159ae111 100644 --- a/modules/axhal/src/arch/x86_64/trap.rs +++ b/modules/axhal/src/arch/x86_64/trap.rs @@ -4,7 +4,9 @@ use super::context::TrapFrame; core::arch::global_asm!(include_str!("trap.S")); +/// start value of irq vector pub const IRQ_VECTOR_START: u8 = 0x20; +/// end value of irq vector pub const IRQ_VECTOR_END: u8 = 0xff; #[no_mangle] From 9f3756ff1dc6dedaaf5b197718ef6a0a9a5ceda6 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Tue, 11 Jul 2023 22:06:36 +0800 Subject: [PATCH 07/12] fix clippy --- modules/axhal/src/arch/x86_64/mod.rs | 2 +- modules/axhal/src/arch/x86_64/trap.rs | 1 - modules/axhal/src/platform/pc_x86/acpi.rs | 3 +-- modules/axhal/src/platform/pc_x86/apic.rs | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index cd1914dc6d..ebbf794d29 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -14,7 +14,7 @@ use x86_64::instructions::interrupts; pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame}; pub use self::gdt::GdtStruct; pub use self::idt::IdtStruct; -pub use self::trap::{IRQ_VECTOR_START, IRQ_VECTOR_END}; +pub use self::trap::{IRQ_VECTOR_END, IRQ_VECTOR_START}; pub use x86_64::structures::tss::TaskStateSegment; /// Allows the current CPU to respond to interrupts. diff --git a/modules/axhal/src/arch/x86_64/trap.rs b/modules/axhal/src/arch/x86_64/trap.rs index 9b159ae111..5c35add6b3 100644 --- a/modules/axhal/src/arch/x86_64/trap.rs +++ b/modules/axhal/src/arch/x86_64/trap.rs @@ -46,4 +46,3 @@ fn x86_trap_handler(tf: &mut TrapFrame) { } } } - diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index 4312e9add1..6f6e9707af 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -220,8 +220,7 @@ impl Acpi { let dsdt = self.rsdp.dsdt.as_ref().unwrap(); let paddr = PhysAddr::from(dsdt.address); let vaddr = phys_to_virt(paddr).as_mut_ptr(); - let slice = - unsafe { core::slice::from_raw_parts_mut(vaddr, dsdt.length as usize) }; + let slice = unsafe { core::slice::from_raw_parts_mut(vaddr, dsdt.length as usize) }; if self.aml_context.parse_table(slice).is_err() { return false; } diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index e1c31e156a..7b51434e66 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -16,7 +16,7 @@ use crate::platform::pc_x86::current_cpu_id; use x2apic::ioapic::{IrqFlags, IrqMode}; #[cfg(feature = "irq")] -use crate::arch::{IRQ_VECTOR_START}; +use crate::arch::IRQ_VECTOR_START; /// map external IRQ to vector #[cfg(feature = "irq")] pub fn irq_to_vector(irq: u8) -> usize { From eeee32d523f0233e81b346a7b479114f8fcea1ec Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Fri, 14 Jul 2023 22:37:22 +0800 Subject: [PATCH 08/12] modify according to review --- modules/axconfig/src/platform/pc-x86.toml | 4 +--- modules/axdriver/src/bus/pci.rs | 11 +++++++++-- modules/axhal/src/arch/x86_64/mod.rs | 2 +- modules/axhal/src/lib.rs | 3 +++ modules/axhal/src/platform/pc_x86/acpi.rs | 16 ++++++++-------- modules/axhal/src/platform/pc_x86/apic.rs | 7 ++++--- modules/axhal/src/platform/pc_x86/mod.rs | 9 --------- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/modules/axconfig/src/platform/pc-x86.toml b/modules/axconfig/src/platform/pc-x86.toml index 24561fef36..89d059122e 100644 --- a/modules/axconfig/src/platform/pc-x86.toml +++ b/modules/axconfig/src/platform/pc-x86.toml @@ -21,12 +21,10 @@ mmio-regions = [ ["0xfec0_0000", "0x1000"], # IO APIC ["0xfed0_0000", "0x1000"], # HPET ["0xfee0_0000", "0x1000"], # Local APIC - ["0xe_0000", "0x2_0000"], #ACPI + ["0xe_0000", "0x2_0000"], # ACPI ] # VirtIO MMIO regions with format (`base_paddr`, `size`). virtio-mmio-regions = [] -# Base physical address of the PCIe ECAM space (should read from ACPI 'MCFG' table). -pci-ecam-base = "0xb000_0000" # End PCI bus number. pci-bus-end = "0xff" # PCI device memory ranges (not used on x86). diff --git a/modules/axdriver/src/bus/pci.rs b/modules/axdriver/src/bus/pci.rs index f47b2757e6..be8ecc9d79 100644 --- a/modules/axdriver/src/bus/pci.rs +++ b/modules/axdriver/src/bus/pci.rs @@ -1,5 +1,5 @@ use crate::{prelude::*, AllDevices}; -use axhal::mem::phys_to_virt; +use axhal::mem::{phys_to_virt, PhysAddr}; use driver_pci::{ BarInfo, Cam, Command, DeviceFunction, HeaderType, MemoryBarType, PciRangeAllocator, PciRoot, }; @@ -84,7 +84,14 @@ fn config_pci_device( impl AllDevices { pub(crate) fn probe_bus_devices(&mut self) { - let base_vaddr = phys_to_virt(axconfig::PCI_ECAM_BASE.into()); + cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + let pci_ecam_base = PhysAddr::from(axhal::get_ecam_address().unwrap() as usize); + } else { + let pci_ecam_base = axconfig::PCI_ECAM_BASE.into(); + } + } + let base_vaddr = phys_to_virt(pci_ecam_base); let mut root = unsafe { PciRoot::new(base_vaddr.as_mut_ptr(), Cam::Ecam) }; // PCI 32-bit MMIO space diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index ebbf794d29..af3cbff42a 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -2,7 +2,7 @@ mod context; mod gdt; mod idt; -// #[cfg(target_os = "none")] +#[cfg(target_os = "none")] mod trap; use core::arch::asm; diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index f8201362fd..39a5a817d7 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -77,3 +77,6 @@ pub use self::platform::platform_init; #[cfg(feature = "smp")] pub use self::platform::platform_init_secondary; + +#[cfg(target_arch = "x86_64")] +pub use self::platform::acpi::get_ecam_address; diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index 6f6e9707af..796d088bd1 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -24,10 +24,10 @@ impl acpi::AcpiHandler for LocalAcpiHandler { physical_address: usize, size: usize, ) -> PhysicalMapping { - let vaddr = phys_to_virt(PhysAddr::from(physical_address)).as_usize(); + let vaddr = phys_to_virt(PhysAddr::from(physical_address)).as_mut_ptr(); PhysicalMapping::new( physical_address, - NonNull::new_unchecked(vaddr as *mut i32 as *mut _), + NonNull::new_unchecked(vaddr as *mut T), size, size, self.clone(), @@ -114,7 +114,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_mut_ptr(); + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_ptr(); let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.read_volatile() } } @@ -124,7 +124,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u16; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_ptr() as *const u16; let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.read_volatile() } } @@ -134,7 +134,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u32; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_ptr() as *const u32; let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.read_volatile() } } @@ -170,7 +170,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u16; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_mut_ptr() as *mut u16; let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.write_volatile(value) } } @@ -188,7 +188,7 @@ impl aml::Handler for LocalAmlHandler { ACPI.get_pci_config_regions_addr(segment, bus, device, function) .unwrap() }; - let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_usize() as *mut u32; + let vaddr = phys_to_virt(PhysAddr::from(paddr as usize)).as_mut_ptr() as *mut u32; let address = unsafe { vaddr.add(offset as usize) }; unsafe { address.write_volatile(value) } } @@ -258,6 +258,7 @@ impl Acpi { /// in the ACPI namespace. /// Each of these devices contains a _PRT method that returns an array of objects describing /// the interrupt routing for slots on that PCI bus. + #[allow(dead_code)] fn get_pci_irq_desc(&mut self, bus: u8, device: u8, function: u8) -> Option { match AmlName::from_str(format!("\\_SB.PCI{bus_id}._PRT", bus_id = bus).as_str()) { Ok(prt_path) => { @@ -327,7 +328,6 @@ pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { } /// Get PCIe ECAM space physical address. -#[allow(dead_code)] pub fn get_ecam_address() -> Option { unsafe { ACPI.get_ecam_address() } } diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index 7b51434e66..7fbf0874a7 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -64,14 +64,15 @@ pub fn set_enable(vector: usize, enabled: bool) { /// Program IO_APIC in order to route IO_APIC IRQ to vector. #[cfg(feature = "irq")] fn ioapic_redirect(vector: usize) { + let mut ioapic = IO_APIC.lock(); let irq = vector_to_irq(vector); - let mut table_entry = unsafe { IO_APIC.lock().table_entry(irq) }; + let mut table_entry = unsafe { ioapic.table_entry(irq) }; table_entry.set_vector(vector as u8); table_entry.set_mode(IrqMode::Fixed); let irq_flag = table_entry.flags() - IrqFlags::MASKED; table_entry.set_flags(irq_flag); table_entry.set_dest(current_cpu_id() as u8); - unsafe { IO_APIC.lock().set_table_entry(irq, table_entry) }; + unsafe { ioapic.set_table_entry(irq, table_entry) }; } /// Registers an IRQ handler for the given IRQ. @@ -80,7 +81,7 @@ fn ioapic_redirect(vector: usize) { /// the registration failed. #[cfg(feature = "irq")] pub fn register_handler(vector: usize, handler: crate::irq::IrqHandler) -> bool { - if vector < APIC_TIMER_VECTOR as _ { + if vector < APIC_TIMER_VECTOR as usize && vector >= IRQ_VECTOR_START as usize { ioapic_redirect(vector); } crate::irq::register_handler_common(vector, handler) diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index c7a5834ffd..439aaf8889 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -3,27 +3,19 @@ mod boot; mod dtables; mod uart16550; -/// acpi module -#[cfg(feature = "irq")] pub mod acpi; -/// mem module pub mod mem; -/// misc module pub mod misc; -/// time module pub mod time; -/// mp module #[cfg(feature = "smp")] pub mod mp; -/// irq module #[cfg(feature = "irq")] pub mod irq { pub use super::apic::*; } -/// console module pub mod console { pub use super::uart16550::*; } @@ -67,7 +59,6 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); - #[cfg(feature = "irq")] self::acpi::init(); } From 3b92a0b08f44543d0e9a1c087aa915c2d9dab8c8 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Fri, 14 Jul 2023 23:35:42 +0800 Subject: [PATCH 09/12] fix error:crate acpi need to dependent on feature alloc --- modules/axconfig/src/platform/pc-x86.toml | 2 ++ modules/axdriver/src/bus/pci.rs | 6 +++--- modules/axhal/src/lib.rs | 2 +- modules/axhal/src/platform/pc_x86/acpi.rs | 4 ++-- modules/axhal/src/platform/pc_x86/mod.rs | 5 ++++- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/axconfig/src/platform/pc-x86.toml b/modules/axconfig/src/platform/pc-x86.toml index 89d059122e..b3886c7b89 100644 --- a/modules/axconfig/src/platform/pc-x86.toml +++ b/modules/axconfig/src/platform/pc-x86.toml @@ -25,6 +25,8 @@ mmio-regions = [ ] # VirtIO MMIO regions with format (`base_paddr`, `size`). virtio-mmio-regions = [] +# Base physical address of the PCIe ECAM space (should read from ACPI 'MCFG' table). +pci-ecam-base = "0xb000_0000" # End PCI bus number. pci-bus-end = "0xff" # PCI device memory ranges (not used on x86). diff --git a/modules/axdriver/src/bus/pci.rs b/modules/axdriver/src/bus/pci.rs index be8ecc9d79..11480496ba 100644 --- a/modules/axdriver/src/bus/pci.rs +++ b/modules/axdriver/src/bus/pci.rs @@ -1,5 +1,5 @@ use crate::{prelude::*, AllDevices}; -use axhal::mem::{phys_to_virt, PhysAddr}; +use axhal::mem::phys_to_virt; use driver_pci::{ BarInfo, Cam, Command, DeviceFunction, HeaderType, MemoryBarType, PciRangeAllocator, PciRoot, }; @@ -85,8 +85,8 @@ fn config_pci_device( impl AllDevices { pub(crate) fn probe_bus_devices(&mut self) { cfg_if::cfg_if! { - if #[cfg(target_arch = "x86_64")] { - let pci_ecam_base = PhysAddr::from(axhal::get_ecam_address().unwrap() as usize); + if #[cfg(all(target_arch = "x86_64",feature="alloc"))] { + let pci_ecam_base = axhal::get_ecam_address().unwrap(); } else { let pci_ecam_base = axconfig::PCI_ECAM_BASE.into(); } diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index 39a5a817d7..959f8da018 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -78,5 +78,5 @@ pub use self::platform::platform_init; #[cfg(feature = "smp")] pub use self::platform::platform_init_secondary; -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", frature = "alloc"))] pub use self::platform::acpi::get_ecam_address; diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index 796d088bd1..7a582b6d3c 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -328,6 +328,6 @@ pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { } /// Get PCIe ECAM space physical address. -pub fn get_ecam_address() -> Option { - unsafe { ACPI.get_ecam_address() } +pub fn get_ecam_address() -> Option { + unsafe { ACPI.get_ecam_address() }.map(|ecam_addr| PhysAddr::from(ecam_addr)) } diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index 439aaf8889..1d34d95ccd 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -3,7 +3,6 @@ mod boot; mod dtables; mod uart16550; -pub mod acpi; pub mod mem; pub mod misc; pub mod time; @@ -16,6 +15,9 @@ pub mod irq { pub use super::apic::*; } +#[cfg(feature = "alloc")] +pub mod acpi; + pub mod console { pub use super::uart16550::*; } @@ -59,6 +61,7 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); + #[cfg(feature = "alloc")] self::acpi::init(); } From 0b8498473cc2e777e449e11d145f8414cc8c3e64 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Fri, 14 Jul 2023 23:43:44 +0800 Subject: [PATCH 10/12] fix ci --- modules/axhal/src/arch/x86_64/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index af3cbff42a..ebbf794d29 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -2,7 +2,7 @@ mod context; mod gdt; mod idt; -#[cfg(target_os = "none")] +// #[cfg(target_os = "none")] mod trap; use core::arch::asm; From 54d43dd566ab1d52857fec40f58d7f3f0b428334 Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Sun, 16 Jul 2023 23:57:36 +0800 Subject: [PATCH 11/12] modify according to review --- modules/axdriver/src/bus/pci.rs | 4 ++-- modules/axhal/src/lib.rs | 8 ++++++-- modules/axhal/src/platform/dummy/mod.rs | 13 +++++++++++++ modules/axhal/src/platform/pc_x86/acpi.rs | 13 ++++++------- modules/axhal/src/platform/pc_x86/apic.rs | 5 +++-- modules/axhal/src/platform/pc_x86/mod.rs | 4 ++-- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/modules/axdriver/src/bus/pci.rs b/modules/axdriver/src/bus/pci.rs index 11480496ba..78f057c858 100644 --- a/modules/axdriver/src/bus/pci.rs +++ b/modules/axdriver/src/bus/pci.rs @@ -85,8 +85,8 @@ fn config_pci_device( impl AllDevices { pub(crate) fn probe_bus_devices(&mut self) { cfg_if::cfg_if! { - if #[cfg(all(target_arch = "x86_64",feature="alloc"))] { - let pci_ecam_base = axhal::get_ecam_address().unwrap(); + if #[cfg(all(target_arch = "x86_64",feature = "virtio"))] { + let pci_ecam_base = axhal::pci::get_ecam_address().unwrap(); } else { let pci_ecam_base = axconfig::PCI_ECAM_BASE.into(); } diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index 959f8da018..abadda1fb2 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -78,5 +78,9 @@ pub use self::platform::platform_init; #[cfg(feature = "smp")] pub use self::platform::platform_init_secondary; -#[cfg(all(target_arch = "x86_64", frature = "alloc"))] -pub use self::platform::acpi::get_ecam_address; +pub mod pci { + #[cfg(all(target_arch = "x86_64", feature = "axalloc"))] + pub use super::platform::acpi::get_ecam_address; + #[cfg(all(target_arch = "x86_64", feature = "irq", feature = "axalloc"))] + pub use super::platform::acpi::get_pci_irq_vector; +} diff --git a/modules/axhal/src/platform/dummy/mod.rs b/modules/axhal/src/platform/dummy/mod.rs index 6b19c097d8..f43dcdc6f5 100644 --- a/modules/axhal/src/platform/dummy/mod.rs +++ b/modules/axhal/src/platform/dummy/mod.rs @@ -91,3 +91,16 @@ pub fn platform_init() {} /// Initializes the platform devices for secondary CPUs. #[cfg(feature = "smp")] pub fn platform_init_secondary() {} + +pub mod acpi { + #[cfg(feature = "irq")] + pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { + None + } + + use crate::mem::PhysAddr; + /// Get PCIe ECAM space physical address. + pub fn get_ecam_address() -> Option { + None + } +} diff --git a/modules/axhal/src/platform/pc_x86/acpi.rs b/modules/axhal/src/platform/pc_x86/acpi.rs index 7a582b6d3c..1b2241e132 100644 --- a/modules/axhal/src/platform/pc_x86/acpi.rs +++ b/modules/axhal/src/platform/pc_x86/acpi.rs @@ -203,9 +203,9 @@ struct Acpi { #[allow(dead_code)] enum X86IrqModel { /// PIC model - PIC, + Pic, /// APIC model - APIC, + Apic, } impl Acpi { @@ -224,7 +224,7 @@ impl Acpi { if self.aml_context.parse_table(slice).is_err() { return false; } - self.set_irq_model(X86IrqModel::APIC) + self.set_irq_model(X86IrqModel::Apic) } /// Set IRQ model that ACPI uses by invoking ACPI global method _PIC. @@ -235,8 +235,8 @@ impl Acpi { /// We may need a lock for ACPI in the future as more ACPI state altering method implemented. fn set_irq_model(&mut self, irq_model: X86IrqModel) -> bool { let value = match irq_model { - X86IrqModel::PIC => 0, - X86IrqModel::APIC => 1, + X86IrqModel::Pic => 0, + X86IrqModel::Apic => 1, }; let mut arg = aml::value::Args::EMPTY; if arg.store_arg(0, aml::AmlValue::Integer(value)).is_err() { @@ -320,7 +320,6 @@ pub(crate) fn init() { /// Get PCI IRQ and map it to vector used in OS. /// Temporarily allow unused here because irq support for virtio hasn't ready yet. -#[allow(dead_code)] #[cfg(feature = "irq")] pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { unsafe { ACPI.get_pci_irq_desc(bus, device, function) } @@ -329,5 +328,5 @@ pub fn get_pci_irq_vector(bus: u8, device: u8, function: u8) -> Option { /// Get PCIe ECAM space physical address. pub fn get_ecam_address() -> Option { - unsafe { ACPI.get_ecam_address() }.map(|ecam_addr| PhysAddr::from(ecam_addr)) + unsafe { ACPI.get_ecam_address() }.map(|ecam_addr| PhysAddr::from(ecam_addr as usize)) } diff --git a/modules/axhal/src/platform/pc_x86/apic.rs b/modules/axhal/src/platform/pc_x86/apic.rs index 7fbf0874a7..45c595066b 100644 --- a/modules/axhal/src/platform/pc_x86/apic.rs +++ b/modules/axhal/src/platform/pc_x86/apic.rs @@ -51,11 +51,12 @@ static IO_APIC: LazyInit> = LazyInit::new(); pub fn set_enable(vector: usize, enabled: bool) { // should not affect LAPIC interrupts if vector < APIC_TIMER_VECTOR as _ { + let irq = vector_to_irq(vector); unsafe { if enabled { - IO_APIC.lock().enable_irq(vector as u8); + IO_APIC.lock().enable_irq(irq as u8); } else { - IO_APIC.lock().disable_irq(vector as u8); + IO_APIC.lock().disable_irq(irq as u8); } } } diff --git a/modules/axhal/src/platform/pc_x86/mod.rs b/modules/axhal/src/platform/pc_x86/mod.rs index 1d34d95ccd..640b6290c8 100644 --- a/modules/axhal/src/platform/pc_x86/mod.rs +++ b/modules/axhal/src/platform/pc_x86/mod.rs @@ -15,7 +15,7 @@ pub mod irq { pub use super::apic::*; } -#[cfg(feature = "alloc")] +#[cfg(feature = "axalloc")] pub mod acpi; pub mod console { @@ -61,7 +61,7 @@ unsafe extern "C" fn rust_entry_secondary(magic: usize) { pub fn platform_init() { self::apic::init_primary(); self::time::init_primary(); - #[cfg(feature = "alloc")] + #[cfg(feature = "axalloc")] self::acpi::init(); } From 16aee821dbf6d7970362a8a01dac6fc77c892cab Mon Sep 17 00:00:00 2001 From: yuanchaoxun Date: Mon, 17 Jul 2023 00:55:49 +0800 Subject: [PATCH 12/12] fix doc --- modules/axhal/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/axhal/src/lib.rs b/modules/axhal/src/lib.rs index abadda1fb2..31aecff098 100644 --- a/modules/axhal/src/lib.rs +++ b/modules/axhal/src/lib.rs @@ -78,6 +78,7 @@ pub use self::platform::platform_init; #[cfg(feature = "smp")] pub use self::platform::platform_init_secondary; +/// PCI related operations pub mod pci { #[cfg(all(target_arch = "x86_64", feature = "axalloc"))] pub use super::platform::acpi::get_ecam_address;