Mask all GSIs

This commit is contained in:
Mathieu Strypsteen 2024-10-09 18:32:08 +02:00
parent 843c4ba466
commit 8d859654f4
6 changed files with 71 additions and 31 deletions

29
kernel/Cargo.lock generated
View file

@ -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",

View file

@ -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"

View file

@ -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 {

View file

@ -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);
}
}

View file

@ -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;

6
loader/Cargo.lock generated
View file

@ -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]]