Enable AHCI interrupts.
* Implement MSI style interrupts * Move interrupt handling to device_manager for IRQs * Give device_manager the ability to allocate IRQs * Move achi::port to an interrupt-based scheme
This commit is contained in:
@@ -10,6 +10,8 @@ struct acpi_mcfg;
|
||||
class lapic;
|
||||
class ioapic;
|
||||
|
||||
using irq_callback = void (*)(void *);
|
||||
|
||||
|
||||
/// Manager for all system hardware devices
|
||||
class device_manager
|
||||
@@ -19,6 +21,10 @@ public:
|
||||
/// \arg root_table Pointer to the ACPI RSDP
|
||||
device_manager(const void *root_table);
|
||||
|
||||
/// Get the system global device manager.
|
||||
/// \returns A reference to the system device manager
|
||||
static device_manager & get() { return s_instance; }
|
||||
|
||||
/// Get the LAPIC
|
||||
/// \returns An object representing the local APIC
|
||||
lapic * get_lapic() { return m_lapic; }
|
||||
@@ -32,6 +38,33 @@ public:
|
||||
/// Intialize drivers for the current device list.
|
||||
void init_drivers();
|
||||
|
||||
/// Allocate an MSI IRQ for a device
|
||||
/// \arg name Name of the interrupt, for display to user
|
||||
/// \arg device Device this MSI is being allocated for
|
||||
/// \arg cb Callback to call when the interrupt is received
|
||||
/// \arg data Data to pass to the callback
|
||||
/// \returns True if an interrupt was allocated successfully
|
||||
bool allocate_msi(
|
||||
const char *name,
|
||||
pci_device &device,
|
||||
irq_callback cb,
|
||||
void *data);
|
||||
|
||||
/// Dispatch an IRQ interrupt
|
||||
/// \arg irq The irq number of the interrupt
|
||||
/// \returns True if the interrupt was handled
|
||||
inline bool dispatch_irq(uint8_t irq)
|
||||
{
|
||||
if (irq < m_irqs.count()) {
|
||||
irq_allocation &cba = m_irqs[irq];
|
||||
if (cba.callback) {
|
||||
cba.callback(cba.data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Parse the ACPI XSDT and load relevant sub-tables.
|
||||
/// \arg xsdt Pointer to the XSDT from the firmware
|
||||
@@ -49,12 +82,27 @@ private:
|
||||
/// device list. The device list is destroyed and rebuilt.
|
||||
void probe_pci();
|
||||
|
||||
/// Handle a bad IRQ. Called when an interrupt is dispatched
|
||||
/// that has no callback.
|
||||
void bad_irq(uint8_t irq);
|
||||
|
||||
lapic *m_lapic;
|
||||
kutil::vector<ioapic *> m_ioapics;
|
||||
|
||||
kutil::vector<pci_group> m_pci;
|
||||
kutil::vector<pci_device> m_devices;
|
||||
|
||||
struct irq_allocation
|
||||
{
|
||||
const char *name;
|
||||
irq_callback callback;
|
||||
void *data;
|
||||
};
|
||||
kutil::vector<irq_allocation> m_irqs;
|
||||
|
||||
static device_manager s_instance;
|
||||
|
||||
device_manager() = delete;
|
||||
device_manager(const device_manager &) = delete;
|
||||
device_manager operator=(const device_manager &) = delete;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user