diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 982c6db..f20f302 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -34,6 +34,7 @@ version = "0.1.0" dependencies = [ "bitfield-struct", "mammoth", + "pci", "yellowstone-yunq", "yunq", "yunqc", @@ -83,6 +84,14 @@ dependencies = [ "linked_list_allocator", ] +[[package]] +name = "pci" +version = "0.1.0" +dependencies = [ + "bitfield-struct", + "mammoth", +] + [[package]] name = "prettyplease" version = "0.2.20" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 1e43df4..f1886f6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -2,7 +2,7 @@ members = [ "lib/client/denali_client", "lib/fs/ext2", - "lib/mammoth", + "lib/mammoth", "lib/pci", "lib/voyageurs", "lib/yellowstone", "lib/yunq", diff --git a/rust/lib/mammoth/src/bindings.rs b/rust/lib/mammoth/src/bindings.rs index 16309b3..c26dba3 100644 --- a/rust/lib/mammoth/src/bindings.rs +++ b/rust/lib/mammoth/src/bindings.rs @@ -258,6 +258,7 @@ pub const kZionPortSend: u64 = 81; pub const kZionPortRecv: u64 = 82; pub const kZionPortPoll: u64 = 83; pub const kZionIrqRegister: u64 = 88; +pub const kZionMsiIrqRegister: u64 = 89; pub const kZionEndpointCreate: u64 = 96; pub const kZionEndpointSend: u64 = 97; pub const kZionEndpointRecv: u64 = 98; @@ -478,6 +479,12 @@ pub struct ZIrqRegisterReq { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct ZMsiIrqRegisterReq { + pub irq_num: *mut u64, + pub port_cap: *mut z_cap_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct ZEndpointCreateReq { pub endpoint_cap: *mut z_cap_t, } diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 4b6d674..8d5af40 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -120,6 +120,12 @@ impl AsRef for MemoryRegion { } } +impl AsMut for MemoryRegion { + fn as_mut(&mut self) -> &mut T { + unsafe { (self.virt_addr as *mut T).as_mut().unwrap() } + } +} + impl Drop for MemoryRegion { fn drop(&mut self) { // FIXME: We shouldn't have to do this manual adjustment. diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 31acd94..2691458 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -310,16 +310,17 @@ pub fn port_poll( Ok((num_bytes, num_caps)) } -pub fn register_irq(irq_num: u64) -> Result { +pub fn register_msi_irq() -> Result<(Capability, u64), ZError> { + let mut irq_num: u64 = 0; let mut port_cap: z_cap_t = 0; syscall( - zion::kZionIrqRegister, - &zion::ZIrqRegisterReq { - irq_num, + zion::kZionMsiIrqRegister, + &zion::ZMsiIrqRegisterReq { + irq_num: &mut irq_num as *mut u64, port_cap: &mut port_cap, }, )?; - Ok(Capability::take(port_cap)) + Ok((Capability::take(port_cap), irq_num)) } pub fn endpoint_create() -> Result { diff --git a/rust/lib/pci/Cargo.toml b/rust/lib/pci/Cargo.toml new file mode 100644 index 0000000..f47f8b1 --- /dev/null +++ b/rust/lib/pci/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "pci" +version = "0.1.0" +edition = "2024" + +[dependencies] +bitfield-struct = "0.8.0" +mammoth = {path = "../mammoth/"} diff --git a/rust/lib/pci/src/device.rs b/rust/lib/pci/src/device.rs new file mode 100644 index 0000000..a00eb7e --- /dev/null +++ b/rust/lib/pci/src/device.rs @@ -0,0 +1,89 @@ +use alloc::vec::Vec; +use mammoth::{cap::Capability, mem::MemoryRegion, syscall, zion::ZError}; + +use crate::header::{ + PciCapabilityPointer, PciDeviceHeader, PciHeaderType, PciMsiCapability, PciMsiControl, + get_header_type, +}; + +pub struct PciDevice { + memory_region: MemoryRegion, +} + +impl PciDevice { + pub fn from(mut memory_region: MemoryRegion) -> Result { + match get_header_type(&memory_region)? { + PciHeaderType::Device => {} + t => { + mammoth::debug!("Invalid header type: {:?}", t); + return Err(ZError::INVALID_ARGUMENT); + } + } + Ok(Self { memory_region }) + } + + pub fn from_cap(capability: Capability) -> Result { + Self::from(MemoryRegion::from_cap(capability)?) + } + + pub fn header(&self) -> &PciDeviceHeader { + self.memory_region.as_ref() + } + + pub fn get_capability_list(&self) -> Result, ZError> { + let status = self.header().status; + if !status.capability_list() { + return Err(ZError::NOT_FOUND); + } + + let mut cap_offset = self.header().capability_ptr; + + let mut cap_vec = Vec::new(); + while cap_offset != 0 { + let cap_ptr: &PciCapabilityPointer = unsafe { + self.memory_region + .raw_ptr_at_offset::(cap_offset as u64) + .as_ref() + .unwrap() + }; + cap_vec.push(cap_ptr); + cap_offset = cap_ptr.next_cap_offset; + } + + Ok(cap_vec) + } + + pub fn register_msi(&mut self) -> Result { + let caps = self.get_capability_list()?; + const MSI_CAP_ID: u8 = 0x05; + let msi_cap: &PciCapabilityPointer = caps + .iter() + .find(|cp| cp.cap_id == MSI_CAP_ID) + .ok_or(ZError::NOT_FOUND)?; + + let msi_cap = unsafe { + ((msi_cap as *const PciCapabilityPointer) as *mut PciMsiCapability) + .as_mut() + .unwrap() + }; + + mammoth::debug!("MSI Cap: {:#x?}", msi_cap); + + let control = msi_cap.msi_control; + assert!(control.capable_address_64()); + assert!(control.multi_message_capable() == 0); + + // FIXME: These probably need to be volatile writes. + let header: &mut PciDeviceHeader = self.memory_region.as_mut(); + header.command = header.command.with_interrupt_disable(true); + msi_cap.msi_control = control.with_msi_enable(true); + msi_cap.msi_addr_lower = 0xFEE00000; + msi_cap.msi_addr_upper_or_data = 0x0; + + let (cap, irq_num) = syscall::register_msi_irq()?; + + msi_cap.msi_data_if_64 = irq_num as u32; + + Ok(cap) + } +} diff --git a/rust/lib/pci/src/header.rs b/rust/lib/pci/src/header.rs new file mode 100644 index 0000000..ff2a144 --- /dev/null +++ b/rust/lib/pci/src/header.rs @@ -0,0 +1,180 @@ +use bitfield_struct::bitfield; +use mammoth::{mem::MemoryRegion, zion::ZError}; + +#[bitfield(u16)] +pub struct PciCommand { + io_space_enable: bool, + memory_space_enable: bool, + bus_master_enable: bool, + + #[bits(access=RO)] + special_cycles_enable: bool, + + #[bits(access=RO)] + memory_write_and_invalidate_enable: bool, + + #[bits(access=RO)] + vga_pallette_snoop_enable: bool, + + parity_error_response_enable: bool, + + #[bits(access=RO)] + wait_cycle_enable: bool, + + serr_enable: bool, + + fast_back_to_back_enable: bool, + + /// Parity is reversed here, set to true to disable. + /// Does not affect MSI. + pub interrupt_disable: bool, + + #[bits(5)] + __: u8, +} + +#[bitfield(u16)] +pub struct PciStatus { + #[bits(3)] + __: u8, + + #[bits(access=RO)] + pub interrupt_status: bool, + #[bits(access=RO)] + pub capability_list: bool, + #[bits(access=RO)] + pub capable_of_66mhz: bool, + + ___: bool, + + #[bits(access=RO)] + pub fast_back_to_back_capabale: bool, + + /// Write 1 to clear + pub master_data_parity_error: bool, + + #[bits(2, access=RO)] + pub devsel_timing: u8, + + /// Write 1 to clear + pub signaled_target_abort: bool, + /// Write 1 to clear + pub received_target_abort: bool, + /// Write 1 to clear + pub received_master_abort: bool, + /// Write 1 to clear + pub signaled_system_erro: bool, + /// Write 1 to clear + pub detected_parity_error: bool, +} + +/// Header definitions from https://wiki.osdev.org/PCI +#[repr(C, packed)] +#[derive(Debug)] +pub struct HeaderShared { + pub vendor_id: u16, + pub device_id: u16, + pub command: PciCommand, + pub status: PciStatus, + pub revision_id: u8, + pub prog_if: u8, + pub subclass: u8, + pub class_code: u8, + pub cache_line_size: u8, + pub latency_timer: u8, + pub header_type: u8, + bist: u8, +} + +const _: () = assert!(size_of::() == 16); + +#[repr(C, packed)] +#[derive(Debug)] +pub struct PciDeviceHeader { + pub vendor_id: u16, + pub device_id: u16, + pub command: PciCommand, + pub status: PciStatus, + pub revision_id: u8, + pub prog_if: u8, + pub subclass: u8, + pub class_code: u8, + pub cache_line_size: u8, + pub latency_timer: u8, + pub header_type: u8, + bist: u8, + pub bars: [u32; 6], + pub cardbus_cis_ptr: u32, + pub subsystem_vendor_id: u16, + pub subsystem_id: u16, + pub expansion_rom_address: u32, + pub capability_ptr: u8, + __: [u8; 7], + pub interrupt_line: u8, + pub interrupt_pin: u8, + pub min_grant: u8, + pub max_latency: u8, +} + +const _: () = assert!(size_of::() == 0x40); + +#[repr(C, packed)] +#[derive(Debug)] +pub struct PciCapabilityPointer { + pub cap_id: u8, + pub next_cap_offset: u8, +} + +#[bitfield(u16)] +pub struct PciMsiControl { + pub msi_enable: bool, + #[bits(3, access=RO)] + pub multi_message_capable: u8, + #[bits(3)] + pub multi_message_enable: u8, + + #[bits(access=RO)] + pub capable_address_64: bool, + + #[bits(access=RO)] + pub per_vector_masking: bool, + + #[bits(7)] + __: u8, +} + +#[repr(C, packed)] +#[derive(Debug)] +pub struct PciMsiCapability { + pub cap_id: u8, + pub next_cap_offset: u8, + pub msi_control: PciMsiControl, + pub msi_addr_lower: u32, + pub msi_addr_upper_or_data: u32, + pub msi_data_if_64: u32, + pub mask: u32, + pub pending: u32, +} + +#[derive(Debug)] +pub enum PciHeaderType { + Device, + PciBridge, + CardBusBridge, +} + +pub fn get_header_type(memory_region: &MemoryRegion) -> Result { + let shared: &HeaderShared = memory_region.as_ref(); + // The only reference I can find to the high bit here is at + // https://www.khoury.northeastern.edu/~pjd/cs7680/homework/pci-enumeration.html + // > Header Type: bit 7 (0x80) indicates whether it is a multi-function device, + match shared.header_type & (!0x80) { + 0x0 => Ok(PciHeaderType::Device), + 0x1 => Ok(PciHeaderType::PciBridge), + 0x2 => Ok(PciHeaderType::CardBusBridge), + _ => { + mammoth::debug!("Unknown pci header type: {:#x}", shared.header_type); + Err(ZError::INVALID_ARGUMENT) + } + } +} diff --git a/rust/lib/pci/src/lib.rs b/rust/lib/pci/src/lib.rs new file mode 100644 index 0000000..44e141a --- /dev/null +++ b/rust/lib/pci/src/lib.rs @@ -0,0 +1,8 @@ +#![no_std] + +extern crate alloc; + +mod device; +mod header; + +pub use device::PciDevice; diff --git a/rust/sys/denali/Cargo.toml b/rust/sys/denali/Cargo.toml index dcb3cd0..ad19780 100644 --- a/rust/sys/denali/Cargo.toml +++ b/rust/sys/denali/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] bitfield-struct = "0.8.0" mammoth = { path = "../../lib/mammoth" } +pci = { path = "../../lib/pci" } yunq = { path = "../../lib/yunq" } yellowstone-yunq = { path = "../../lib/yellowstone" } diff --git a/rust/sys/denali/src/ahci/controller.rs b/rust/sys/denali/src/ahci/controller.rs index f62645d..2a402f0 100644 --- a/rust/sys/denali/src/ahci/controller.rs +++ b/rust/sys/denali/src/ahci/controller.rs @@ -6,6 +6,7 @@ use mammoth::{ thread, zion::ZError, }; +use pci::PciDevice; use crate::ahci::{ port::{AhciDeviceDetection, AhciInterfacePowerManagement}, @@ -14,36 +15,8 @@ use crate::ahci::{ use super::{hba::AhciHba, port::AhciPortHba, port_controller::PortController}; -#[derive(Debug)] -#[repr(C, packed)] -pub struct PciDeviceHeader { - pub vendor_id: u16, - pub device_id: u16, - pub command_reg: u16, - pub status_reg: u16, - pub revision: u8, - pub prog_interface: u8, - pub subclass: u8, - pub class_code: u8, - pub cache_line_size: u8, - pub latency_timer: u8, - pub header_type: u8, - pub bist: u8, - pub bars: [u32; 5], - pub abar: u32, - __: u32, - pub subsystem_id: u32, - pub expansion_rom: u32, - pub cap_ptr: u8, - ___: [u8; 7], - pub interrupt_line: u8, - pub interrupt_pin: u8, - pub min_grant: u8, - pub max_latency: u8, -} - pub struct AhciController { - pci_header: &'static mut PciDeviceHeader, + pci_device: Mutex, hba: Mutex<&'static mut AhciHba>, ports: [Option; 32], hba_vaddr: u64, @@ -51,13 +24,13 @@ pub struct AhciController { impl AhciController { pub fn new(pci_memory: Capability) -> Self { - let pci_vaddr = mem::map_cap_and_leak(pci_memory); - let pci_header = unsafe { (pci_vaddr as *mut PciDeviceHeader).as_mut().unwrap() }; + let pci_device = PciDevice::from_cap(pci_memory).unwrap(); - let hba_vaddr = mem::map_direct_physical_and_leak(pci_header.abar as u64, 0x1100); + let hba_vaddr = + mem::map_direct_physical_and_leak(pci_device.header().bars[5] as u64, 0x1100); let hba = unsafe { (hba_vaddr as *mut AhciHba).as_mut().unwrap() }; let mut controller = Self { - pci_header, + pci_device: Mutex::new(pci_device), hba: Mutex::new(hba), ports: [const { None }; 32], hba_vaddr, @@ -100,17 +73,8 @@ impl AhciController { } } - fn irq_num(&self) -> u64 { - match self.pci_header.interrupt_pin { - 1 => mammoth::zion::kZIrqPci1, - 2 => mammoth::zion::kZIrqPci2, - 3 => mammoth::zion::kZIrqPci3, - 4 => mammoth::zion::kZIrqPci4, - _ => panic!( - "Unrecognized pci interrupt pin {}", - self.pci_header.interrupt_pin - ), - } + fn register_irq(&self) -> Result { + self.pci_device.lock().register_msi() } fn handle_irq(&self) { @@ -184,9 +148,8 @@ impl AhciController { pub fn spawn_irq_thread(controller: Arc) -> thread::JoinHandle { let irq_thread = move || { - let irq_num = controller.irq_num(); - let irq_port = - mammoth::port::PortServer::from_cap(mammoth::syscall::register_irq(irq_num).unwrap()); + let irq_port_cap = controller.register_irq().unwrap(); + let irq_port = mammoth::port::PortServer::from_cap(irq_port_cap); controller.hba.lock().global_host_control.update(|ghc| { ghc.set_interrupt_enable(true); }); diff --git a/zion/include/zcall.h b/zion/include/zcall.h index 31e45df..6092037 100644 --- a/zion/include/zcall.h +++ b/zion/include/zcall.h @@ -48,7 +48,7 @@ SYS5(PortRecv, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*, SYS5(PortPoll, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*, num_caps, z_cap_t*, caps); -SYS2(IrqRegister, uint64_t, irq_num, z_cap_t*, port_cap); +SYS2(MsiIrqRegister, uint64_t*, irq_num, z_cap_t*, port_cap); SYS1(EndpointCreate, z_cap_t*, endpoint_cap); SYS6(EndpointSend, z_cap_t, endpoint_cap, uint64_t, num_bytes, const void*, diff --git a/zion/include/ztypes.h b/zion/include/ztypes.h index 490e0d7..b60db9c 100644 --- a/zion/include/ztypes.h +++ b/zion/include/ztypes.h @@ -43,7 +43,7 @@ const uint64_t kZionPortSend = 0x51; const uint64_t kZionPortRecv = 0x52; const uint64_t kZionPortPoll = 0x53; -const uint64_t kZionIrqRegister = 0x58; +const uint64_t kZionMsiIrqRegister = 0x59; const uint64_t kZionEndpointCreate = 0x60; const uint64_t kZionEndpointSend = 0x61; diff --git a/zion/interrupt/apic.cpp b/zion/interrupt/apic.cpp index 927edfd..66d7e0c 100644 --- a/zion/interrupt/apic.cpp +++ b/zion/interrupt/apic.cpp @@ -136,23 +136,6 @@ Apic::Apic(const ApicConfiguration& config) // FIXME: Get this offset from ACPI. SetIoDoubleReg(0x14, 0x20 | APIC_MASK); - // Map Keyboard - SetIoDoubleReg(0x12, 0x22); - - // For now set these based on the presets in the following spec. - // http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf - // FIXME: However in the future we should likely use the MADT for legacy - // interrupts and AML for PCI etc. - // PCI Line 1-4 - // FIXME: These should be level triggered according to spec I believe - // but because we handle the interrupt outside of the kernel it is tricky - // to wait to send the end of interrupt message. - // Because of this leave them as edge triggered and send EOI immediately. - SetIoDoubleReg(0x30, 0x30); - SetIoDoubleReg(0x32, 0x31); - SetIoDoubleReg(0x34, 0x32); - SetIoDoubleReg(0x36, 0x33); - DumpInfo(); } diff --git a/zion/interrupt/driver_manager.cpp b/zion/interrupt/driver_manager.cpp index 67e78fc..3aa2bc5 100644 --- a/zion/interrupt/driver_manager.cpp +++ b/zion/interrupt/driver_manager.cpp @@ -9,18 +9,24 @@ DriverManager& DriverManager::Get() { return *gDriverManager; } DriverManager::DriverManager() { gDriverManager = this; } void DriverManager::WriteMessage(uint64_t irq_num, IpcMessage&& message) { - if (!driver_map_.Contains(irq_num)) { + if (irq_num < IRQ_OFFSET) { + dbgln("WARN IRQ {x} below min offset {x}", irq_num, IRQ_OFFSET); + } + uint64_t offset = irq_num - IRQ_OFFSET; + if (offset >= driver_list_.size()) { dbgln("WARN IRQ for {x} with no registered driver", irq_num); return; } - driver_map_.at(irq_num)->Send(glcr::Move(message)); + driver_list_[offset]->Send(glcr::Move(message)); } -glcr::ErrorCode DriverManager::RegisterListener(uint64_t irq_num, - glcr::RefPtr port) { - if (driver_map_.Contains(irq_num)) { - return glcr::ALREADY_EXISTS; +glcr::ErrorOr DriverManager::RegisterListener( + glcr::RefPtr port) { + if (driver_list_.size() + IRQ_OFFSET >= 0xFF) { + return glcr::EXHAUSTED; } - return driver_map_.Insert(irq_num, port); + uint8_t offset = (driver_list_.size() + IRQ_OFFSET); + driver_list_.PushBack(port); + return offset; } diff --git a/zion/interrupt/driver_manager.h b/zion/interrupt/driver_manager.h index db205c8..3fb897f 100644 --- a/zion/interrupt/driver_manager.h +++ b/zion/interrupt/driver_manager.h @@ -15,9 +15,10 @@ class DriverManager { void WriteMessage(uint64_t irq_num, IpcMessage&& message); - [[nodiscard]] glcr::ErrorCode RegisterListener(uint64_t irq_num, - glcr::RefPtr port); + [[nodiscard]] glcr::ErrorOr RegisterListener( + glcr::RefPtr port); private: - glcr::HashMap> driver_map_; + const uint64_t IRQ_OFFSET = 0x60; + glcr::Vector> driver_list_; }; diff --git a/zion/interrupt/interrupt.cpp b/zion/interrupt/interrupt.cpp index 2c3692d..7858e88 100644 --- a/zion/interrupt/interrupt.cpp +++ b/zion/interrupt/interrupt.cpp @@ -109,7 +109,7 @@ extern "C" void interrupt_protection_fault(InterruptFrame* frame) { } else { dbgln("GDT"); } - dbgln("Index: {}", err >> 3); + dbgln("Index: {} ({x})", err >> 3, err >> 3); dbgln("RIP: {x}", frame->rip); dbgln("RAX: {x}, RBX: {x}, RCX: {x}, RDX: {x}", frame->rax, frame->rbx, frame->rcx, frame->rdx); @@ -197,40 +197,27 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) { gScheduler->Preempt(); } -extern "C" void isr_keyboard(); -extern "C" void interrupt_keyboard(InterruptFrame*) { - glcr::Array data(1); - data[0] = inb(0x60); - IpcMessage msg{.data = glcr::Move(data)}; - DriverManager::Get().WriteMessage(kZIrqKbd, glcr::Move(msg)); - +extern "C" void isr_60(); +extern "C" void interrupt_60(InterruptFrame*) { + DriverManager::Get().WriteMessage(0x60, {}); gApic->SignalEOI(); } -extern "C" void isr_pci1(); -extern "C" void interrupt_pci1(InterruptFrame*) { - DriverManager::Get().WriteMessage(kZIrqPci1, {}); +extern "C" void isr_61(); +extern "C" void interrupt_61(InterruptFrame*) { + DriverManager::Get().WriteMessage(0x61, {}); gApic->SignalEOI(); } -extern "C" void isr_pci2(); -extern "C" void interrupt_pci2(InterruptFrame*) { - DriverManager::Get().WriteMessage(kZIrqPci2, {}); - dbgln("Interrupt PCI line 2"); +extern "C" void isr_62(); +extern "C" void interrupt_62(InterruptFrame*) { + DriverManager::Get().WriteMessage(0x62, {}); gApic->SignalEOI(); } -extern "C" void isr_pci3(); -extern "C" void interrupt_pci3(InterruptFrame*) { - DriverManager::Get().WriteMessage(kZIrqPci3, {}); - dbgln("Interrupt PCI line 3"); - gApic->SignalEOI(); -} - -extern "C" void isr_pci4(); -extern "C" void interrupt_pci4(InterruptFrame*) { - DriverManager::Get().WriteMessage(kZIrqPci4, {}); - dbgln("Interrupt PCI line 4"); +extern "C" void isr_63(); +extern "C" void interrupt_63(InterruptFrame*) { + DriverManager::Get().WriteMessage(0x63, {}); gApic->SignalEOI(); } @@ -243,12 +230,11 @@ void InitIdt() { gIdt[0x20] = CreateDescriptor(isr_timer); gIdt[0x21] = CreateDescriptor(isr_apic_timer); - gIdt[0x22] = CreateDescriptor(isr_keyboard); - gIdt[0x30] = CreateDescriptor(isr_pci1); - gIdt[0x31] = CreateDescriptor(isr_pci2); - gIdt[0x32] = CreateDescriptor(isr_pci3); - gIdt[0x33] = CreateDescriptor(isr_pci4); + gIdt[0x60] = CreateDescriptor(isr_60); + gIdt[0x61] = CreateDescriptor(isr_61); + gIdt[0x62] = CreateDescriptor(isr_62); + gIdt[0x63] = CreateDescriptor(isr_63); InterruptDescriptorTablePointer idtp{ .size = sizeof(gIdt), diff --git a/zion/interrupt/interrupt_enter.s b/zion/interrupt/interrupt_enter.s index db02a22..167d631 100644 --- a/zion/interrupt/interrupt_enter.s +++ b/zion/interrupt/interrupt_enter.s @@ -63,10 +63,8 @@ isr_handler fpe_fault isr_handler timer isr_handler apic_timer -isr_handler keyboard - -isr_handler pci1 -isr_handler pci2 -isr_handler pci3 -isr_handler pci4 +isr_handler 60 +isr_handler 61 +isr_handler 62 +isr_handler 63 diff --git a/zion/syscall/ipc.cpp b/zion/syscall/ipc.cpp index 021695c..55c0799 100644 --- a/zion/syscall/ipc.cpp +++ b/zion/syscall/ipc.cpp @@ -156,13 +156,14 @@ glcr::ErrorCode PortPoll(ZPortPollReq* req) { return TranslateIpcMessageToResponse(msg, req); } -glcr::ErrorCode IrqRegister(ZIrqRegisterReq* req) { +glcr::ErrorCode MsiIrqRegister(ZMsiIrqRegisterReq* req) { auto& proc = gScheduler->CurrentProcess(); - glcr::RefPtr port = glcr::MakeRefCounted(); *req->port_cap = proc.AddNewCapability(port); - return DriverManager::Get().RegisterListener(req->irq_num, port); + ASSIGN_OR_RETURN(*req->irq_num, DriverManager::Get().RegisterListener(port)); + + return glcr::OK; } glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req) { diff --git a/zion/syscall/ipc.h b/zion/syscall/ipc.h index 4a3ae97..9b0f072 100644 --- a/zion/syscall/ipc.h +++ b/zion/syscall/ipc.h @@ -12,7 +12,7 @@ glcr::ErrorCode PortCreate(ZPortCreateReq* req); glcr::ErrorCode PortSend(ZPortSendReq* req); glcr::ErrorCode PortRecv(ZPortRecvReq* req); glcr::ErrorCode PortPoll(ZPortPollReq* req); -glcr::ErrorCode IrqRegister(ZIrqRegisterReq* req); +glcr::ErrorCode MsiIrqRegister(ZMsiIrqRegisterReq* req); glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req); glcr::ErrorCode EndpointSend(ZEndpointSendReq* req); diff --git a/zion/syscall/syscall.cpp b/zion/syscall/syscall.cpp index 70e9677..096c931 100644 --- a/zion/syscall/syscall.cpp +++ b/zion/syscall/syscall.cpp @@ -77,7 +77,7 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req) { CASE(PortSend); CASE(PortRecv); CASE(PortPoll); - CASE(IrqRegister); + CASE(MsiIrqRegister); CASE(EndpointCreate); CASE(EndpointSend); CASE(EndpointRecv);