diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 7f5d580..ab86769 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bindgen" @@ -119,6 +119,7 @@ name = "kernel" version = "0.0.1" dependencies = [ "bindgen", + "bitfield", "bitvec", "kernel-common", "linked_list_allocator", @@ -136,9 +137,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" @@ -209,9 +210,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -233,9 +234,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -245,9 +246,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -256,9 +257,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-hash" @@ -298,9 +299,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 02ddc11..37d864b 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.1" edition = "2021" [dependencies] +bitfield = "0.17.0" bitvec = {version = "1.0.1", default-features = false, features = ["alloc", "atomic"]} kernel-common = {path = "../lib/kernel-common"} linked_list_allocator = "0.10.5" diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 301f8a7..94c747c 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -48,9 +48,7 @@ extern "C" fn main(temp_loader_struct: *const LoaderStruct) -> ! { RSDP_ADDRESS.call_once(|| loader_struct.rsdp_address); unsafe { let status = AcpiInitializeTables(null_mut(), 16, 0); - if status != AE_OK { - panic!("Failed to initialize ACPI tables"); - } + assert_eq!(status, AE_OK); } parse_madt(); loop { diff --git a/kernel/src/sys/ioapic.rs b/kernel/src/sys/ioapic.rs index a04af96..c1ad8fd 100644 --- a/kernel/src/sys/ioapic.rs +++ b/kernel/src/sys/ioapic.rs @@ -3,6 +3,8 @@ use core::{ sync::atomic::{AtomicPtr, AtomicU32, Ordering}, }; +use bitfield::bitfield; + use crate::cpu::paging::map_physical; struct IOAPIC { @@ -10,30 +12,70 @@ struct IOAPIC { start_gsi: AtomicU32, end_gsi: AtomicU32, } - +bitfield! { + struct RedirectionEntry(u64); + vector, set_vector: 7, 0; + delivery_mode, set_delivery_mode: 10, 8; + destination_mode, set_destination_mode: 11, 11; + delivery_status, set_delivery_status: 12, 12; + pin_polarity, set_pin_polarity: 13, 13; + remote_irr, set_remote_irr: 14, 14; + trigger_mode, set_trigger_mode: 15, 15; + mask, set_mask: 16, 16; + destination, set_destination: 63, 56; +} const EMPTY_IOAPIC: IOAPIC = IOAPIC { address: AtomicPtr::new(null_mut()), start_gsi: AtomicU32::new(0), end_gsi: AtomicU32::new(0), }; const REGISTER_VERSION: u8 = 1; +const REGISTER_REDIRECTION: u8 = 0x10; static IOAPICS: [IOAPIC; 32] = [EMPTY_IOAPIC; 32]; fn read_register(apic_i: usize, reg_i: u8) -> u32 { unsafe { IOAPICS[apic_i].address.load(Ordering::Relaxed).write_volatile(reg_i as u32); - return IOAPICS[apic_i].address.load(Ordering::Relaxed).add(0x10).read_volatile(); + return IOAPICS[apic_i].address.load(Ordering::Relaxed).add(4).read_volatile(); } } -pub fn setup_ioapic(i: u8, phys: u64, gsi_base: u32) { - let i = i as usize; +fn write_register(apic_i: usize, reg_i: u8, val: u32) { + unsafe { + IOAPICS[apic_i].address.load(Ordering::Relaxed).write_volatile(reg_i as u32); + IOAPICS[apic_i].address.load(Ordering::Relaxed).add(4).write_volatile(val); + } +} +fn get_apic_for_gsi(gsi: usize) -> usize { + for i in 0..32 { + if gsi >= IOAPICS[i].start_gsi.load(Ordering::Relaxed) as usize && gsi < IOAPICS[i].end_gsi.load(Ordering::Relaxed) as usize { + return i; + } + } + panic!("Invalid GSI"); +} +fn write_redirection(mut gsi: usize, redirection: RedirectionEntry) { + let apic_i = get_apic_for_gsi(gsi); + gsi -= IOAPICS[apic_i].start_gsi.load(Ordering::Relaxed) as usize; + write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2, redirection.0 as u32); + write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2 + 1, (redirection.0 >> 32) as u32); +} +fn mask_gsi(gsi: usize) { + let mut redirection = RedirectionEntry(0); + redirection.set_mask(1); + write_redirection(gsi, redirection); +} +pub fn setup_ioapic(apic_i: u8, phys: u64, gsi_base: u32) { + let apic_i = apic_i as usize; let address; unsafe { address = map_physical(phys, 0x14) as *mut u32; } - IOAPICS[i].address.store(address, Ordering::Relaxed); - IOAPICS[i].start_gsi.store(gsi_base, Ordering::Relaxed); - let max_ints = (read_register(i, REGISTER_VERSION) >> 16) & 0xff; - IOAPICS[i].end_gsi.store(gsi_base + max_ints, Ordering::Relaxed); + IOAPICS[apic_i].address.store(address, Ordering::Relaxed); + IOAPICS[apic_i].start_gsi.store(gsi_base, Ordering::Relaxed); + let max_ints = (read_register(apic_i, REGISTER_VERSION) >> 16) & 0xff; + IOAPICS[apic_i].end_gsi.store(gsi_base + max_ints, Ordering::Relaxed); + for i in gsi_base..gsi_base + max_ints { + mask_gsi(i as usize); + } } diff --git a/kernel/src/sys/madt.rs b/kernel/src/sys/madt.rs index 5bf09f3..1bd9486 100644 --- a/kernel/src/sys/madt.rs +++ b/kernel/src/sys/madt.rs @@ -14,9 +14,7 @@ pub fn parse_madt() { let mut address: u64 = 0; unsafe { let status = AcpiGetTable(signature as *mut i8, 1, &mut address as *mut u64 as *mut *mut acpi_table_header); - if status != AE_OK { - panic!("Failed to get APIC table"); - } + assert_eq!(status, AE_OK); madt = &*(address as *const acpi_table_madt); } let mut lapic_address: u64 = madt.Address as u64; diff --git a/loader/Cargo.lock b/loader/Cargo.lock index a42abf5..d499a6c 100644 --- a/loader/Cargo.lock +++ b/loader/Cargo.lock @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -165,7 +165,7 @@ checksum = "c19ee3a01d435eda42cb9931269b349d28a1762f91ddf01c68d276f74b957cc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]]