Skip to content

Commit

Permalink
spin Mutex rewrite to reduce unsafe block count
Browse files Browse the repository at this point in the history
  • Loading branch information
wuyukai0403 committed Jan 18, 2025
1 parent 769af06 commit 12264e1
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 92 deletions.
44 changes: 38 additions & 6 deletions kernel/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ edition = "2021"
limine = "0.3.1"
noto-sans-mono-bitmap = "0.3.1"
raw-cpuid = "11.3.0"
spin = "0.9.8"
x2apic = "0.4.3"
x86_64 = "0.15.2"
160 changes: 110 additions & 50 deletions kernel/src/acpi.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::mm::phys_to_virt;
use crate::println;
use limine::response::RsdpResponse;
use spin::Mutex;

#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
pub struct RSDP {
signature: [u8; 8],
Expand Down Expand Up @@ -30,19 +31,20 @@ pub struct ACPI_table_header {
creator_revison: u32,
}

#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
pub struct XSDT {
header: ACPI_table_header,
pointers: [u64; 16], // TODO
}

#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
pub struct MADT {
header: ACPI_table_header,
local_apic_addr: u32,
flags: u32,
var_marker: [u8; 128], // to clone the rest of the MADT
}

#[derive(Debug, Copy, Clone)]
Expand All @@ -55,67 +57,125 @@ pub struct PCIE_CFG_ALLOC {
pub reserved: u32,
}

#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
#[repr(packed)]
pub struct MCFG {
header: ACPI_table_header,
reserved: u64,
pub alloc: PCIE_CFG_ALLOC,
}

pub static mut rsdp: *const RSDP = 0 as *const RSDP;
pub static mut xsdt: *const XSDT = 0 as *const XSDT;
pub static mut madt: *const MADT = 0 as *const MADT;
pub static mut mcfg: *const MCFG = 0 as *const MCFG;
pub static rsdp: Mutex<RSDP> = Mutex::new(RSDP {
signature: [0; 8],
checksum: 0,
OEMID: [0; 6],
revision: 0,
rsdt_addr: 0,
length: 0,
xsdt_addr: 0,
ext_checksum: 0,
reserved: [0; 3],
});

pub fn init(res: &RsdpResponse) {
unsafe {
rsdp = res.address() as *const RSDP;
// println!("{:?}", *rsdp);
xsdt = phys_to_virt((*rsdp).xsdt_addr) as *const XSDT;
// println!("{:?}", *xsdt);
for i in 0..16 {
if (*xsdt).pointers[i] == 0 {
break;
}
let head = phys_to_virt((*xsdt).pointers[i]) as *const ACPI_table_header;
if (*head).signature == [65, 80, 73, 67] {
// "APIC"
madt = head as *const MADT;
// println!("{:?}", *madt);
} else if (*head).signature == [77, 67, 70, 71] {
// "MCFG"
mcfg = head as *const MCFG;
}
pub static xsdt: Mutex<XSDT> = Mutex::new(XSDT {
header: ACPI_table_header {
signature: [0; 4],
length: 0,
revision: 0,
checksum: 0,
OEMID: [0; 6],
OEMTableID: [0; 8],
OEMRevision: 0,
creator_id: 0,
creator_revison: 0,
},
pointers: [0; 16],
});

pub static madt: Mutex<MADT> = Mutex::new(MADT {
header: ACPI_table_header {
signature: [0; 4],
length: 0,
revision: 0,
checksum: 0,
OEMID: [0; 6],
OEMTableID: [0; 8],
OEMRevision: 0,
creator_id: 0,
creator_revison: 0,
},
local_apic_addr: 0,
flags: 0,
var_marker: [0; 128],
});

pub static mcfg: Mutex<MCFG> = Mutex::new(MCFG {
header: ACPI_table_header {
signature: [0; 4],
length: 0,
revision: 0,
checksum: 0,
OEMID: [0; 6],
OEMTableID: [0; 8],
OEMRevision: 0,
creator_id: 0,
creator_revison: 0,
},
reserved: 0,
alloc: PCIE_CFG_ALLOC {
base_addr: 0,
pci_segment_group_number: 0,
start_pci_bus_number: 0,
end_pci_bus_number: 0,
reserved: 0,
},
});

pub unsafe fn init(res: &RsdpResponse) {
let mut rsdp_lock = rsdp.lock();
let mut xsdt_lock = xsdt.lock();
*rsdp_lock = *(res.address() as *const RSDP);
*xsdt_lock = *(phys_to_virt((*rsdp_lock).xsdt_addr) as *const XSDT);
for i in 0..16 {
if (*xsdt_lock).pointers[i] == 0 {
break;
}
let head = &*(phys_to_virt((*xsdt_lock).pointers[i]) as *const ACPI_table_header);
if head.signature == [65, 80, 73, 67] {
// "APIC"
*madt.lock() = *(head as *const ACPI_table_header as *const MADT);
} else if head.signature == [77, 67, 70, 71] {
// "MCFG"
*mcfg.lock() = *(head as *const ACPI_table_header as *const MCFG);
}
}
}

pub fn parse_madt() -> u64 {
pub unsafe fn parse_madt() -> u64 {
let mut res: u64 = 0;
unsafe {
let mut p = madt.offset(1) as *const u8;
let edge = (madt as *const u8).offset((*madt).header.length as isize);
while p < edge {
let entry_type = *p;
// println!("Entry type {}: {}", entry_type, ["Processor Local APIC", "I/O APIC",
// "I/O APIC Interrupt Source Override",
// "I/O APIC Non-maskable interrupt source",
// "Local APIC Non-maskable interrupts",
// "Local APIC Address Override",
// "Processor Local x2APIC"
// ][entry_type as usize]);
if entry_type == 1 {
let res_addr = p.offset(4) as *const u32;
res = *res_addr as u64;
println!(
"DoglinkOS_2nd::acpi::parse_madt() will return {:?}",
res as *const ()
);
}
let entry_length = *(p.offset(1));
p = p.offset((entry_length) as isize);
let mut madt_lock = madt.lock();
let mut p = &((*madt_lock).var_marker) as *const u8;
let edge = (&(*madt_lock) as * const MADT as *const u8).offset((*madt_lock).header.length as isize);
// println!("{p:?} {edge:?}");
while p < edge {
let entry_type = *p;
// println!("Entry type {}: {}", entry_type, ["Processor Local APIC", "I/O APIC",
// "I/O APIC Interrupt Source Override",
// "I/O APIC Non-maskable interrupt source",
// "Local APIC Non-maskable interrupts",
// "Local APIC Address Override",
// "Processor Local x2APIC"
// ][entry_type as usize]);
if entry_type == 1 {
let res_addr = p.offset(4) as *const u32;
res = *res_addr as u64;
println!(
"DoglinkOS_2nd::acpi::parse_madt() will return {:?}",
res as *const ()
);
}
let entry_length = *(p.offset(1));
p = p.offset((entry_length) as isize);
}
res
}
24 changes: 10 additions & 14 deletions kernel/src/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,22 @@ use crate::println;
use x86_64::structures::idt::HandlerFunc;
use x86_64::structures::idt::InterruptDescriptorTable;
use x86_64::structures::idt::InterruptStackFrame;
use spin::{Lazy, Mutex};

pub static mut IDT: InterruptDescriptorTable = InterruptDescriptorTable::new();
pub static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
let mut temp = InterruptDescriptorTable::new();
temp[32].set_handler_fn(handler1);
temp[33].set_handler_fn(handler2);
temp[34].set_handler_fn(handler3);
temp[36].set_handler_fn(handler4);
temp
});

pub fn init() {
unsafe {
IDT.load();
}
register(32, handler1);
register(33, handler2);
register(34, handler3);
register(36, handler4);
IDT.load();
x86_64::instructions::interrupts::enable();
}

pub fn register(n: u8, handler: HandlerFunc) {
unsafe {
IDT[n].set_handler_fn(handler);
}
}

pub extern "x86-interrupt" fn handler1(_: InterruptStackFrame) {
putchar('.');
crate::apic::local::eoi();
Expand Down
9 changes: 5 additions & 4 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use DoglinkOS_2nd::acpi::{init as init_acpi, parse_madt};
use DoglinkOS_2nd::apic::{io::init as init_ioapic, local::init as init_lapic};
use DoglinkOS_2nd::console::{clear as clear_console, init as init_console, puts as console_puts};
use DoglinkOS_2nd::cpu::show_cpu_info;
use DoglinkOS_2nd::int::{init as init_interrupt, register as register_interrupt_handler};
use DoglinkOS_2nd::int::init as init_interrupt;
use DoglinkOS_2nd::mm::init as init_mm;
use DoglinkOS_2nd::pcie::enumrate::doit;
use DoglinkOS_2nd::println;
Expand Down Expand Up @@ -57,9 +57,10 @@ extern "C" fn kmain() -> ! {
init_interrupt();
init_lapic();
let rsdp_response = RSDP_REQUEST.get_response().unwrap();
init_acpi(&rsdp_response);
let ioapic_phys_addr = parse_madt();
init_ioapic(ioapic_phys_addr);
init_ioapic(unsafe {
init_acpi(&rsdp_response);
parse_madt()
});
show_cpu_info();
doit();
hang();
Expand Down
10 changes: 4 additions & 6 deletions kernel/src/mm.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use crate::println;
use limine::response::HhdmResponse;
use spin::Mutex;

pub static mut offset: u64 = 0;
pub static offset: Mutex<u64> = Mutex::new(0);

pub fn init(res: &HhdmResponse) {
unsafe {
offset = res.offset();
// println!("{offset}");
}
*offset.lock() = res.offset();
}

pub fn phys_to_virt(addr: u64) -> u64 {
unsafe { addr + offset }
addr + *offset.lock()
}
Loading

0 comments on commit 12264e1

Please sign in to comment.