Compare commits

...

2 Commits

Author SHA1 Message Date
Drew Galbraith f26fd73116 [Zion][Denali] Move to MSI for AHCI devices.
This will allow us to properly do interrupts for XHCI devices in the
future.

Also move PCI device header parsing to a shared library.

Get rid of the old irq register format which supplied an irq number and
instead pass the appropriate irq number back out to the caller.
2025-05-05 23:14:01 -07:00
Drew Galbraith c645405ca8 Fix build after removing a bunch of stuff. 2025-05-05 21:04:42 -07:00
28 changed files with 426 additions and 130 deletions

View File

@ -17,7 +17,6 @@ target_include_directories(mammoth
target_link_libraries(mammoth
glacier
victoriafalls_yunq
yellowstone_yunq
voyageurs_yunq
zion_stub

9
rust/Cargo.lock generated
View File

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

View File

@ -2,7 +2,7 @@
members = [
"lib/client/denali_client", "lib/fs/ext2",
"lib/mammoth",
"lib/mammoth", "lib/pci",
"lib/voyageurs",
"lib/yellowstone",
"lib/yunq",

View File

@ -1,7 +1,7 @@
use std::fs;
fn main() {
let input_file = "../../../../sys/denali/lib/denali/denali.yunq";
let input_file = "../../../sys/denali/denali.yunq";
println!("cargo::rerun-if-changed={input_file}");

View File

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

View File

@ -120,6 +120,12 @@ impl<T> AsRef<T> for MemoryRegion {
}
}
impl<T> AsMut<T> 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.

View File

@ -310,16 +310,17 @@ pub fn port_poll(
Ok((num_bytes, num_caps))
}
pub fn register_irq(irq_num: u64) -> Result<Capability, ZError> {
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<Capability, ZError> {

8
rust/lib/pci/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "pci"
version = "0.1.0"
edition = "2024"
[dependencies]
bitfield-struct = "0.8.0"
mammoth = {path = "../mammoth/"}

View File

@ -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<Self, ZError> {
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, ZError> {
Self::from(MemoryRegion::from_cap(capability)?)
}
pub fn header(&self) -> &PciDeviceHeader {
self.memory_region.as_ref()
}
pub fn get_capability_list(&self) -> Result<Vec<&PciCapabilityPointer>, 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::<PciCapabilityPointer>(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<Capability, ZError> {
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)
}
}

180
rust/lib/pci/src/header.rs Normal file
View File

@ -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::<HeaderShared>() == 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::<PciDeviceHeader>() == 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<PciHeaderType, ZError> {
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)
}
}
}

8
rust/lib/pci/src/lib.rs Normal file
View File

@ -0,0 +1,8 @@
#![no_std]
extern crate alloc;
mod device;
mod header;
pub use device::PciDevice;

View File

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

View File

@ -1,7 +1,7 @@
use std::fs;
fn main() {
let input_file = "../../../sys/denali/lib/denali/denali.yunq";
let input_file = "denali.yunq";
println!("cargo::rerun-if-changed={input_file}");

View File

@ -0,0 +1,28 @@
interface Denali {
method Read(ReadRequest) -> (ReadResponse);
method ReadMany(ReadManyRequest) -> (ReadResponse);
}
message DiskBlock {
u64 lba;
u64 size;
}
message ReadRequest {
u64 device_id;
DiskBlock block;
}
message ReadManyRequest {
u64 device_id;
repeated DiskBlock blocks;
}
message ReadResponse {
u64 device_id;
u64 size;
capability memory;
}

View File

@ -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<PciDevice>,
hba: Mutex<&'static mut AhciHba>,
ports: [Option<PortController>; 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<Capability, ZError> {
self.pci_device.lock().register_msi()
}
fn handle_irq(&self) {
@ -184,9 +148,8 @@ impl AhciController {
pub fn spawn_irq_thread(controller: Arc<AhciController>) -> 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);
});

View File

@ -1,7 +1,7 @@
use std::fs;
fn main() {
let input_file = "../../../sys/victoriafalls/lib/victoriafalls/victoriafalls.yunq";
let input_file = "victoriafalls.yunq";
println!("cargo::rerun-if-changed={input_file}");

View File

@ -0,0 +1,24 @@
interface VFS {
method OpenFile(OpenFileRequest) -> (OpenFileResponse);
method GetDirectory(GetDirectoryRequest) -> (Directory);
}
message OpenFileRequest {
string path;
}
message OpenFileResponse {
string path;
u64 size;
capability memory;
}
message GetDirectoryRequest {
string path;
}
message Directory {
// , separated list of filenames until we have repeated strings.
string filenames;
}

View File

@ -1,7 +1,5 @@
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
add_subdirectory(denali)
add_subdirectory(victoriafalls)
add_subdirectory(voyageurs)
add_subdirectory(yellowstone)

View File

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

View File

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

View File

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

View File

@ -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> port) {
if (driver_map_.Contains(irq_num)) {
return glcr::ALREADY_EXISTS;
glcr::ErrorOr<uint8_t> DriverManager::RegisterListener(
glcr::RefPtr<Port> 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;
}

View File

@ -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> port);
[[nodiscard]] glcr::ErrorOr<uint8_t> RegisterListener(
glcr::RefPtr<Port> port);
private:
glcr::HashMap<uint64_t, glcr::RefPtr<Port>> driver_map_;
const uint64_t IRQ_OFFSET = 0x60;
glcr::Vector<glcr::RefPtr<Port>> driver_list_;
};

View File

@ -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<uint8_t> 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),

View File

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

View File

@ -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> port = glcr::MakeRefCounted<Port>();
*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) {

View File

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

View File

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