Kernel: Implement MSI, MSI-X and interrupt reservation
This commit is contained in:
@@ -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] {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user