Skip to content

Commit

Permalink
Properly handle the interrupt pin situation
Browse files Browse the repository at this point in the history
  • Loading branch information
kennystrawnmusic committed Aug 11, 2022
1 parent 0c513e8 commit b5abbb6
Showing 1 changed file with 93 additions and 69 deletions.
162 changes: 93 additions & 69 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ use aml::{
pci_routing::PciRoutingTable, resource::IrqDescriptor, value::Args, AmlContext, AmlName,
AmlValue, NamespaceLevel,
};
use pcics::header::HeaderType;
use pcics::header::{HeaderType, InterruptPin};
use spin::RwLock;
pub use syscall;
use syscall::Mmio;
Expand Down Expand Up @@ -163,70 +163,7 @@ pub fn mcfg_brute_force() -> impl Iterator<Item = Option<u64>> {
})
}

entry_point!(maink);

pub static ALL_DISKS: OnceCell<RwLock<Vec<Box<dyn Disk + Send + Sync>>>> = OnceCell::uninit();

fn maink(boot_info: &'static mut BootInfo) -> ! {
// set up heap allocation ASAP
let offset = VirtAddr::new(
boot_info
.physical_memory_offset
.clone()
.into_option()
.unwrap(),
);
let map = unsafe { map_memory(offset) };
let falloc = unsafe { Falloc::new(&boot_info.memory_regions) };

MAPPER.get_or_init(move || Mutex::new(map));
FRAME_ALLOCATOR.get_or_init(move || Mutex::new(falloc));

heap_init(
&mut *MAPPER.get().unwrap().lock(),
&mut *FRAME_ALLOCATOR.get().unwrap().lock(),
)
.unwrap_or_else(|e| panic!("Failed to initialize heap: {:#?}", e));

// clone the physical memory offset into a static ASAP
// so it doesn't need to be hardcoded everywhere it's needed
let cloned_offset = boot_info
.physical_memory_offset
.clone()
.into_option()
.unwrap();
PHYS_OFFSET.get_or_init(move || cloned_offset);

let buffer_optional = &mut boot_info.framebuffer;
let buffer_option = buffer_optional.as_mut();
let buffer = buffer_option.unwrap();
let bi = buffer.info().clone();
let raw_buffer = buffer.buffer_mut();

let rsdp = boot_info.rsdp_addr.clone().into_option().unwrap();
printk_init(raw_buffer, bi);
info!(
"Using version {}.{}.{} of crates.io/crates/bootloader",
boot_info.version_major, boot_info.version_minor, boot_info.version_patch
);

info!("RSDP address: {:#x}", rsdp.clone());
info!(
"Memory region start address: {:#x}",
&boot_info.memory_regions.first().unwrap() as *const _ as usize
);

let tables = unsafe { AcpiTables::from_rsdp(KernelAcpi, rsdp.clone() as usize).unwrap() };
let mcfg = match PciConfigRegions::new(&tables) {
Ok(mcfg) => Some(mcfg),
Err(_) => None,
};

let interrupts = tables.platform_info().unwrap().interrupt_model; // satisfy the borrow checker before moving

INTERRUPT_MODEL.get_or_init(move || interrupts);
PCI_CONFIG.get_or_init(move || mcfg.clone());

pub fn aml_init(tables: &mut AcpiTables<KernelAcpi>) -> Option<[(u32, InterruptPin); 4]> {
let mut aml_ctx = AmlContext::new(Box::new(KernelAcpi), aml::DebugVerbosity::Scopes);

let fadt = unsafe { &mut tables.get_sdt::<Fadt>(Signature::FADT).unwrap().unwrap() };
Expand Down Expand Up @@ -275,25 +212,100 @@ fn maink(boot_info: &'static mut BootInfo) -> ! {
&AmlName::from_str("\\_SB.PCI0._PRT").unwrap(),
&mut aml_ctx,
) {
let mut a: [(u32, InterruptPin); 4] = [
(0, InterruptPin::IntA),
(0, InterruptPin::IntB),
(0, InterruptPin::IntC),
(0, InterruptPin::IntD)
];
if let Ok(desc) = prt.route(0x1, 0x6, Pin::IntA, &mut aml_ctx) {
info!("IRQ descriptor A: {:#?}", desc);
IDT.lock()[(desc.irq + 32) as usize].set_handler_fn(interrupts::ahci);
a[0] = (desc.irq, InterruptPin::IntA);
}
if let Ok(desc) = prt.route(0x1, 0x6, Pin::IntB, &mut aml_ctx) {
debug!("IRQ descriptor B: {:#?}", desc);
IDT.lock()[(desc.irq + 32) as usize].set_handler_fn(interrupts::ahci);
a[1] = (desc.irq, InterruptPin::IntB);
}
if let Ok(desc) = prt.route(0x1, 0x6, Pin::IntC, &mut aml_ctx) {
debug!("IRQ descriptor C: {:#?}", desc);
IDT.lock()[(desc.irq + 32) as usize].set_handler_fn(interrupts::ahci);
a[2] = (desc.irq, InterruptPin::IntC);
}
if let Ok(desc) = prt.route(0x1, 0x6, Pin::IntD, &mut aml_ctx) {
debug!("IRQ descriptor D: {:#?}", desc);
IDT.lock()[(desc.irq + 32) as usize].set_handler_fn(interrupts::ahci);
a[3] = (desc.irq, InterruptPin::IntD);
}
return Some(a);
}
return None;
}
return None;
}
None
}

entry_point!(maink);

pub static ALL_DISKS: OnceCell<RwLock<Vec<Box<dyn Disk + Send + Sync>>>> = OnceCell::uninit();

fn maink(boot_info: &'static mut BootInfo) -> ! {
// set up heap allocation ASAP
let offset = VirtAddr::new(
boot_info
.physical_memory_offset
.clone()
.into_option()
.unwrap(),
);
let map = unsafe { map_memory(offset) };
let falloc = unsafe { Falloc::new(&boot_info.memory_regions) };

MAPPER.get_or_init(move || Mutex::new(map));
FRAME_ALLOCATOR.get_or_init(move || Mutex::new(falloc));

heap_init(
&mut *MAPPER.get().unwrap().lock(),
&mut *FRAME_ALLOCATOR.get().unwrap().lock(),
)
.unwrap_or_else(|e| panic!("Failed to initialize heap: {:#?}", e));

// clone the physical memory offset into a static ASAP
// so it doesn't need to be hardcoded everywhere it's needed
let cloned_offset = boot_info
.physical_memory_offset
.clone()
.into_option()
.unwrap();
PHYS_OFFSET.get_or_init(move || cloned_offset);

let buffer_optional = &mut boot_info.framebuffer;
let buffer_option = buffer_optional.as_mut();
let buffer = buffer_option.unwrap();
let bi = buffer.info().clone();
let raw_buffer = buffer.buffer_mut();

let rsdp = boot_info.rsdp_addr.clone().into_option().unwrap();
printk_init(raw_buffer, bi);
info!(
"Using version {}.{}.{} of crates.io/crates/bootloader",
boot_info.version_major, boot_info.version_minor, boot_info.version_patch
);

info!("RSDP address: {:#x}", rsdp.clone());
info!(
"Memory region start address: {:#x}",
&boot_info.memory_regions.first().unwrap() as *const _ as usize
);

let mut tables = unsafe { AcpiTables::from_rsdp(KernelAcpi, rsdp.clone() as usize).unwrap() };
let mcfg = match PciConfigRegions::new(&tables) {
Ok(mcfg) => Some(mcfg),
Err(_) => None,
};

let interrupts = tables.platform_info().unwrap().interrupt_model; // satisfy the borrow checker before moving

INTERRUPT_MODEL.get_or_init(move || interrupts);
PCI_CONFIG.get_or_init(move || mcfg.clone());

crate::interrupts::init();

Expand Down Expand Up @@ -327,6 +339,18 @@ fn maink(boot_info: &'static mut BootInfo) -> ! {
);
info!("Class Code: {:#x?}", header.class_code);

let arr = aml_init(&mut tables);

if arr.is_some() {
match header.interrupt_pin {
InterruptPin::IntA => IDT.lock()[32 + arr.unwrap()[0].0 as usize].set_handler_fn(interrupts::ahci),
InterruptPin::IntB => IDT.lock()[32 + arr.unwrap()[1].0 as usize].set_handler_fn(interrupts::ahci),
InterruptPin::IntC => IDT.lock()[32 + arr.unwrap()[2].0 as usize].set_handler_fn(interrupts::ahci),
InterruptPin::IntD => IDT.lock()[32 + arr.unwrap()[3].0 as usize].set_handler_fn(interrupts::ahci),
_ => panic!("Invalid interrupt pin"),
};
}

info!("Interrupt pin: {:#?}", header.interrupt_pin);

if let HeaderType::Normal(normal_header) = header.header_type {
Expand Down

0 comments on commit b5abbb6

Please sign in to comment.