Kernel: Implement MSI, MSI-X and interrupt reservation

This commit is contained in:
2024-01-13 17:11:26 +02:00
parent 56a29dc176
commit c6130f33d7
14 changed files with 310 additions and 40 deletions

View File

@@ -14,6 +14,9 @@ namespace Kernel
virtual void enable_irq(uint8_t) override;
virtual bool is_in_service(uint8_t) override;
virtual BAN::ErrorOr<void> reserve_irq(uint8_t irq) override;
virtual BAN::Optional<uint8_t> get_free_irq() override;
private:
uint32_t read_from_local_apic(ptrdiff_t);
void write_to_local_apic(ptrdiff_t, uint32_t);
@@ -54,6 +57,7 @@ namespace Kernel
Kernel::vaddr_t m_local_apic_vaddr = 0;
BAN::Vector<IOAPIC> m_io_apics;
uint8_t m_irq_overrides[0x100] {};
uint8_t m_reserved_gsis[0x100 / 8] {};
};
}

View File

@@ -1,5 +1,8 @@
#pragma once
#include <BAN/Optional.h>
#include <BAN/Errors.h>
#include <stdint.h>
#define DISABLE_INTERRUPTS() asm volatile("cli")
@@ -37,6 +40,9 @@ namespace Kernel
static void initialize(bool force_pic);
static InterruptController& get();
virtual BAN::ErrorOr<void> reserve_irq(uint8_t irq) = 0;
virtual BAN::Optional<uint8_t> get_free_irq() = 0;
bool is_using_apic() const { return m_using_apic; }
void enter_acpi_mode();

View File

@@ -79,7 +79,8 @@ namespace Kernel::PCI
uint16_t vendor_id() const { return m_vendor_id; }
uint16_t device_id() const { return m_device_id; }
BAN::ErrorOr<uint8_t> get_irq();
BAN::ErrorOr<void> reserve_irqs(uint8_t count);
uint8_t get_irq(uint8_t index);
BAN::ErrorOr<BAN::UniqPtr<BarRegion>> allocate_bar_region(uint8_t bar_num);
@@ -92,15 +93,15 @@ namespace Kernel::PCI
void enable_io_space();
void disable_io_space();
void enable_pin_interrupts();
void disable_pin_interrupts();
private:
void enumerate_capabilites();
void set_command_bits(uint16_t mask);
void unset_command_bits(uint16_t mask);
void enable_pin_interrupts();
void disable_pin_interrupts();
private:
const uint8_t m_bus;
const uint8_t m_dev;
@@ -114,6 +115,9 @@ namespace Kernel::PCI
uint16_t m_vendor_id;
uint16_t m_device_id;
uint32_t m_reserved_irqs { 0 };
uint8_t m_reserved_irq_count { 0 };
BAN::Optional<uint8_t> m_offset_msi;
BAN::Optional<uint8_t> m_offset_msi_x;
};

View File

@@ -12,12 +12,16 @@ namespace Kernel
virtual void enable_irq(uint8_t) override;
virtual bool is_in_service(uint8_t) override;
virtual BAN::ErrorOr<void> reserve_irq(uint8_t irq) override;
virtual BAN::Optional<uint8_t> get_free_irq() override;
static void remap();
static void mask_all();
private:
static PIC* create();
friend class InterruptController;
uint16_t m_reserved_irqs { 0 };
};
}