diff --git a/Cargo.lock b/Cargo.lock index 6901c00b..77c73faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", @@ -22,9 +22,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bit_field" @@ -46,9 +46,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "byteorder" @@ -58,18 +58,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.21" +version = "1.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "equivalent" @@ -103,18 +103,18 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", ] [[package]] @@ -123,7 +123,7 @@ version = "0.5.12" dependencies = [ "arrayvec", "bitfield", - "bitflags 2.9.0", + "bitflags 2.9.1", "byteorder", "cc", "fdt", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -183,9 +183,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "once_cell" @@ -235,9 +235,9 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7" [[package]] name = "redox_syscall" version = "0.5.17" -source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=master#a9880ccf50d093e662f3b31c1aa13f0951cc2b4d" +source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=master#aedadf4d5cb915e0c6a22a5c7358fa853354e21d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -255,9 +255,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "sbi-rt" @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -323,12 +323,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "slab_allocator" @@ -379,9 +376,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -410,9 +407,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", @@ -422,18 +419,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.26" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", @@ -445,9 +442,9 @@ dependencies = [ [[package]] name = "toml_write" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "unicode-ident" @@ -463,9 +460,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "winnow" -version = "0.7.9" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] @@ -483,18 +480,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 97151bcf..83476683 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,8 +49,9 @@ sbi-rt = "0.0.3" [features] default = [ "acpi", - #TODO: issues with Alder Lake and newer CPUs: "multi_core", - # This may be because of mismatch between cpu id and apic id + #TODO: issues with Alder Lake and newer CPUs: + #This may be because of mismatch between cpu id and apic id + "multi_core", "graphical_debug", "serial_debug", "self_modifying", diff --git a/src/acpi/madt/arch/x86.rs b/src/acpi/madt/arch/x86.rs index a8121c68..7035e47a 100644 --- a/src/acpi/madt/arch/x86.rs +++ b/src/acpi/madt/arch/x86.rs @@ -15,12 +15,12 @@ static TRAMPOLINE_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/trampo pub(super) fn init(madt: Madt) { let local_apic = unsafe { the_local_apic() }; - let me = local_apic.id() as u8; + let me = local_apic.id(); if local_apic.x2 { - println!(" X2APIC {}", me); + println!(" X2APIC {}", me.get()); } else { - println!(" XAPIC {}: {:>08X}", me, local_apic.address); + println!(" XAPIC {}: {:>08X}", me.get(), local_apic.address); } if cfg!(feature = "multi_core") { @@ -53,7 +53,7 @@ pub(super) fn init(madt: Madt) { println!(" {:x?}", madt_entry); match madt_entry { MadtEntry::LocalApic(ap_local_apic) => { - if ap_local_apic.id == me { + if u32::from(ap_local_apic.id) == me.get() { println!(" This is my local APIC"); } else { if ap_local_apic.flags & 1 == 1 { @@ -98,9 +98,9 @@ pub(super) fn init(madt: Madt) { { let mut icr = 0x4500; if local_apic.x2 { - icr |= (ap_local_apic.id as u64) << 32; + icr |= u64::from(ap_local_apic.id) << 32; } else { - icr |= (ap_local_apic.id as u64) << 56; + icr |= u64::from(ap_local_apic.id) << 56; } print!(" IPI..."); local_apic.set_icr(icr); @@ -113,9 +113,9 @@ pub(super) fn init(madt: Madt) { let mut icr = 0x4600 | ap_segment as u64; if local_apic.x2 { - icr |= (ap_local_apic.id as u64) << 32; + icr |= u64::from(ap_local_apic.id) << 32; } else { - icr |= (ap_local_apic.id as u64) << 56; + icr |= u64::from(ap_local_apic.id) << 56; } print!(" SIPI..."); diff --git a/src/arch/aarch64/ipi.rs b/src/arch/aarch64/ipi.rs index 97905807..b29a7d15 100644 --- a/src/arch/aarch64/ipi.rs +++ b/src/arch/aarch64/ipi.rs @@ -21,8 +21,8 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {} #[cfg(not(feature = "multi_core"))] #[inline(always)] -pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {} +pub fn ipi_single(_kind: IpiKind, _target: crate::percpu::PercpuBlock) {} #[cfg(feature = "multi_core")] #[inline(always)] -pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {} +pub fn ipi_single(_kind: IpiKind, _target: crate::percpu::PercpuBlock) {} diff --git a/src/arch/riscv64/ipi.rs b/src/arch/riscv64/ipi.rs index cc4df342..bfacf8d8 100644 --- a/src/arch/riscv64/ipi.rs +++ b/src/arch/riscv64/ipi.rs @@ -25,8 +25,8 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {} #[cfg(not(feature = "multi_core"))] #[inline(always)] -pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {} +pub fn ipi_single(_kind: IpiKind, _target: crate::percpu::PercpuBlock) {} #[cfg(feature = "multi_core")] #[inline(always)] -pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {} +pub fn ipi_single(_kind: IpiKind, _target: crate::percpu::PercpuBlock) {} diff --git a/src/arch/x86_shared/device/ioapic.rs b/src/arch/x86_shared/device/ioapic.rs index 74fe13be..958f53e5 100644 --- a/src/arch/x86_shared/device/ioapic.rs +++ b/src/arch/x86_shared/device/ioapic.rs @@ -12,7 +12,7 @@ use crate::{ paging::{entry::EntryFlags, Page, PageFlags, PhysicalAddress}, }; -use super::pic; +use super::{local_apic::ApicId, pic}; use crate::arch::cpuid::cpuid; #[cfg(target_arch = "x86_64")] use {crate::memory::RmmA, rmm::Arch}; @@ -112,6 +112,7 @@ impl IoApic { guard.write_ioredtbl(idx, reg); } } + #[repr(u8)] #[derive(Clone, Copy, Debug)] pub enum ApicTriggerMode { @@ -145,7 +146,7 @@ pub enum DeliveryMode { #[derive(Clone, Copy, Debug)] pub struct MapInfo { - pub dest: u8, + pub dest: ApicId, pub mask: bool, pub trigger_mode: ApicTriggerMode, pub polarity: ApicPolarity, @@ -161,7 +162,7 @@ impl MapInfo { // TODO: Check for reserved fields. - (u64::from(self.dest) << 56) + (u64::from(self.dest.get()) << 56) | (u64::from(self.mask) << 16) | ((self.trigger_mode as u64) << 15) | ((self.polarity as u64) << 13) @@ -308,7 +309,7 @@ pub unsafe fn handle_src_override(src_override: &'static MadtIntSrcOverride) { #[allow(dead_code)] pub unsafe fn init(active_table: &mut KernelMapper) { - let bsp_apic_id = cpuid().get_feature_info().unwrap().initial_local_apic_id(); // TODO: remove unwraps + let bsp_apic_id = ApicId::new(u32::from(cpuid().get_feature_info().unwrap().initial_local_apic_id())); // TODO: remove unwraps // search the madt for all IOAPICs. #[cfg(feature = "acpi")] diff --git a/src/arch/x86_shared/device/local_apic.rs b/src/arch/x86_shared/device/local_apic.rs index 3dee3eb9..c3bd2692 100644 --- a/src/arch/x86_shared/device/local_apic.rs +++ b/src/arch/x86_shared/device/local_apic.rs @@ -7,10 +7,24 @@ use x86::msr::*; use crate::{ ipi::IpiKind, paging::{PageFlags, PhysicalAddress}, + percpu::PercpuBlock, }; use crate::{arch::cpuid::cpuid, memory::KernelMapper}; +#[derive(Clone, Copy, Debug)] +pub struct ApicId(u32); + +impl ApicId { + pub fn new(inner: u32) -> Self { + Self(inner) + } + + pub fn get(&self) -> u32 { + self.0 + } +} + static LOCAL_APIC: SyncUnsafeCell = SyncUnsafeCell::new(LocalApic { address: 0, x2: false, @@ -79,6 +93,10 @@ impl LocalApic { } self.setup_error_int(); //self.setup_timer(); + + PercpuBlock::current() + .misc_arch_info + .apic_id_opt.set(Some(self.id())); } unsafe fn read(&self, reg: u32) -> u32 { @@ -89,12 +107,12 @@ impl LocalApic { write_volatile((self.address + reg as usize) as *mut u32, value); } - pub fn id(&self) -> u32 { - if self.x2 { + pub fn id(&self) -> ApicId { + ApicId::new(if self.x2 { unsafe { rdmsr(IA32_X2APIC_APICID) as u32 } } else { unsafe { self.read(0x20) } - } + }) } pub fn version(&self) -> u32 { @@ -133,18 +151,13 @@ impl LocalApic { } } - pub fn ipi(&mut self, apic_id: u32, kind: IpiKind) { - let mut icr = 0x40 | kind as u64; - if self.x2 { - icr |= u64::from(apic_id) << 32; - } else { - icr |= u64::from(apic_id) << 56; - } - self.set_icr(icr); - } - pub fn ipi_nmi(&mut self, apic_id: u32) { + pub fn ipi(&mut self, apic_id: ApicId, kind: IpiKind) { let shift = if self.x2 { 32 } else { 56 }; - self.set_icr((u64::from(apic_id) << shift) | (1 << 14) | (0b100 << 8)); + self.set_icr((u64::from(apic_id.get()) << shift) | (1 << 6) | kind as u64); + } + pub fn ipi_nmi(&mut self, apic_id: ApicId) { + let shift = if self.x2 { 32 } else { 56 }; + self.set_icr((u64::from(apic_id.get()) << shift) | (1 << 14) | (0b100 << 8)); } pub unsafe fn eoi(&mut self) { diff --git a/src/arch/x86_shared/device/mod.rs b/src/arch/x86_shared/device/mod.rs index 5617db38..8a7c6275 100644 --- a/src/arch/x86_shared/device/mod.rs +++ b/src/arch/x86_shared/device/mod.rs @@ -1,3 +1,4 @@ +use core::cell::Cell; use crate::memory::KernelMapper; pub mod cpu; @@ -75,6 +76,7 @@ pub unsafe fn init_ap() { #[derive(Default)] pub struct ArchPercpuMisc { + pub apic_id_opt: Cell>, #[cfg(feature = "x86_kvm_pv")] pub tsc_info: tsc::TscPercpu, } diff --git a/src/arch/x86_shared/ipi.rs b/src/arch/x86_shared/ipi.rs index 440489ed..c1ef1c6c 100644 --- a/src/arch/x86_shared/ipi.rs +++ b/src/arch/x86_shared/ipi.rs @@ -37,19 +37,19 @@ pub fn ipi(kind: IpiKind, target: IpiTarget) { let icr = (target as u64) << 18 | 1 << 14 | (kind as u64); unsafe { the_local_apic().set_icr(icr) }; } -use crate::cpu_set::LogicalCpuId; #[cfg(feature = "multi_core")] #[inline(always)] -pub fn ipi_single(kind: IpiKind, target: LogicalCpuId) { +pub fn ipi_single(kind: IpiKind, target: &crate::percpu::PercpuBlock) { use crate::device::local_apic::the_local_apic; - unsafe { - // TODO: Distinguish between logical and physical CPU IDs - the_local_apic().ipi(target.get(), kind); + if let Some(apic_id) = target.misc_arch_info.apic_id_opt.get() { + unsafe { + the_local_apic().ipi(apic_id, kind); + } } } #[cfg(not(feature = "multi_core"))] #[inline(always)] -pub fn ipi_single(_kind: IpiKind, _target: LogicalCpuId) {} +pub fn ipi_single(_kind: IpiKind, _target: &crate::percpu::PercpuBlock) {} diff --git a/src/percpu.rs b/src/percpu.rs index e89754ef..474e591d 100644 --- a/src/percpu.rs +++ b/src/percpu.rs @@ -106,7 +106,7 @@ pub fn shootdown_tlb_ipi(target: Option) { } } - crate::ipi::ipi_single(crate::ipi::IpiKind::Tlb, target); + crate::ipi::ipi_single(crate::ipi::IpiKind::Tlb, &percpublock); } else { for id in 0..crate::cpu_count() { // TODO: Optimize: use global counter and percpu ack counters, send IPI using