The Pedigree Project 0.1
PciIoApicInterrupts.h
1/* Copyright (c) 2026, Pedigree Developers. SPDX-License-Identifier: ISC */
2#ifndef PEDIGREE_PC_PCI_IOAPIC_INTERRUPTS_H
3#define PEDIGREE_PC_PCI_IOAPIC_INTERRUPTS_H
4
5#include <config.h>
6
7#if MULTIPROCESSOR && ACPI
8
9#include "pedigree/kernel/Spinlock.h"
10#include "pedigree/kernel/machine/IrqHandlerRegistry.h"
11#include "pedigree/kernel/machine/ThreadedIrqDispatcher.h"
12#include "pedigree/kernel/processor/InterruptHandler.h"
13
14#include "IoApic.h"
15
16class Device;
17class HardIrqHandler;
18class IrqHandler;
19class IrqHandlerBase;
20
22class PciIoApicInterrupts : private InterruptHandler {
23 public:
24 static constexpr uint8_t FirstVector = 0x80;
25 static constexpr size_t VectorCount = 16;
26
27 PciIoApicInterrupts();
28 bool initialise();
29 bool containsGsi(uint32_t gsi) const;
30 bool reserveGsi(uint32_t gsi, bool activeLow);
31 bool initialiseThreaded();
32 bool shutdownThreaded();
33 irq_id_t registerThreaded(Device* device, IrqHandler* handler, const IrqPolicy& policy,
34 bool& routed);
35 irq_id_t registerHard(Device* device, HardIrqHandler* handler, const IrqPolicy& policy,
36 bool& routed);
37 bool unregisterHandler(irq_id_t id, IrqHandlerBase* handler);
38 void enable(irq_id_t id, bool enabled);
39
40 static bool contains(irq_id_t id) {
41 return id >= FirstVector && id < FirstVector + VectorCount;
42 }
43
44 private:
45 enum class Mode : uint8_t { None, Threaded, Hard };
46 struct Line {
47 IoApic* controller = nullptr;
48 uint32_t gsi = 0;
49 size_t handlers = 0;
50 size_t cookie = 0;
51 Mode mode = Mode::None;
52 bool activeLow = false;
53 bool used = false;
54 bool enabled = false;
55 bool removing = false;
56 bool inFlight = false;
57 bool quarantined = false;
58 };
59
60 irq_id_t registerHandler(Device* device, IrqHandlerBase* handler, const IrqPolicy& policy,
61 Mode mode, bool& routed);
62 static bool findRoute(Device* device, uint32_t& gsi, bool& activeLow);
63 void interrupt(size_t interruptNumber, InterruptState& state) override;
64 static void dispatchThreaded(void* context, uint8_t slot, size_t cookie);
65
66 Spinlock m_Lock;
67 IrqHandlerRegistry m_Handlers;
68 ThreadedIrqDispatcher m_Dispatcher;
69 IoApic m_Controllers[4];
70 size_t m_ControllerCount;
71 Line m_Lines[VectorCount];
72 uint8_t m_DestinationApicId;
73 bool m_Ready;
74 bool m_ShuttingDown;
75};
76
77#endif
78
79#endif
Abstract base class for interrupt-handlers.