The Pedigree Project 0.1
kernel/machine/mach_virt/IrqManager.h
1/*
2 * Copyright (c) 2026, Pedigree Developers
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted.
6 */
7
8#ifndef KERNEL_MACHINE_VIRT_IRQMANAGER_H
9#define KERNEL_MACHINE_VIRT_IRQMANAGER_H
10
11#include "pedigree/kernel/Spinlock.h"
12#include "pedigree/kernel/machine/IrqHandlerRegistry.h"
13#include "pedigree/kernel/machine/IrqManager.h"
14#include "pedigree/kernel/machine/ThreadedIrqDispatcher.h"
15#include "pedigree/kernel/processor/state_forward.h"
16
17#include "GicIts.h"
18
19class VirtIrqManager : public IrqManager {
20 public:
21 static VirtIrqManager& instance();
22
23 bool initialise();
24 bool initialiseThreaded();
25 bool shutdownThreaded();
26 void handle(InterruptState& state);
27
28 irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler* handler,
29 const IrqPolicy& policy) override;
30 irq_id_t registerPciIrqHandler(IrqHandler* handler, Device* device,
31 const IrqPolicy& policy) override;
32 irq_id_t registerPciMessageIrqHandler(IrqHandler* handler, Device* device,
33 const IrqPolicy& intxFallbackPolicy) override;
34 bool registerPciMsixIrqHandlers(Device* device, IrqHandler* const* handlers, size_t count,
35 irq_id_t* ids, bool& fallbackSafe,
36 const size_t* processors = nullptr) override;
37 irq_id_t registerHardIsaIrqHandler(uint8_t irq, HardIrqHandler* handler,
38 const IrqPolicy& policy) override;
39 irq_id_t registerHardPciIrqHandler(HardIrqHandler* handler, Device* device,
40 const IrqPolicy& policy) override;
42 const IrqPolicy& intxFallbackPolicy) override;
43 irq_id_t registerSchedulerIrqHandler(uint8_t irq, SchedulerIrqHandler* handler,
44 const IrqPolicy& policy) override;
45 bool unregisterSchedulerIrqHandler(irq_id_t id, SchedulerIrqHandler* handler) override;
46 bool unregisterHandler(irq_id_t id, IrqHandlerBase* handler) override;
47 void enable(uint8_t irq, bool enabled) override;
48
49 private:
50 static constexpr size_t MaxIrqs = 256;
51 static constexpr size_t MaxPciLines = 16;
52
53 struct PciLine {
54 uint32_t irq;
55 size_t cookie;
56 size_t handlers;
57 bool inFlight;
58 bool removing;
59 bool quarantined;
60 bool hard;
61 bool reserved;
62 bool message;
63 bool spuriousSafe;
64 bool msix;
65 bool lpi;
66 uint8_t msixIndex;
67 uint32_t deviceId;
68 Device* device;
69 };
70
72 static void dispatchPciLine(void* context, uint8_t line, size_t cookie);
73 irq_id_t registerPciHandler(IrqHandlerBase* handler, Device* device, const IrqPolicy& policy,
74 bool hard);
75 irq_id_t registerPciMessageHandler(IrqHandlerBase* handler, Device* device, bool hard,
76 bool& allowFallback);
77 size_t pciLine(uint32_t irq) const;
78 uint8_t pciRegistryLine(size_t slot) const;
79 uint32_t acknowledge();
80 void complete(uint32_t acknowledgeValue);
81 bool setEnabled(uint32_t irq, bool enabled);
82 void setLevel(uint32_t irq);
83 void setEdge(uint32_t irq);
84 bool initialiseMsi();
85 bool initialiseV2();
86 bool initialiseV3();
87
88 HardIrqHandler* m_Hard[MaxIrqs];
89 SchedulerIrqHandler* m_Scheduler[MaxIrqs];
90 IrqHandlerRegistry m_PciHandlers;
91 ThreadedIrqDispatcher m_PciDispatcher;
92 Spinlock m_PciLock;
93 PciLine m_PciLines[MaxPciLines];
94 GicIts m_Its;
95 uint32_t m_Version;
96 uint32_t m_IrqCount;
97 uint32_t m_MsiFirst;
98 uint32_t m_MsiLast;
99 uint64_t m_MsiAddress;
100 bool m_MsiReady;
101 bool m_Initialised;
102
103 static VirtIrqManager m_Instance;
104};
105
106extern "C" void virtHandleIrq(InterruptState& state);
107
108#endif
irq_id_t registerHardPciIrqHandler(HardIrqHandler *handler, Device *device, const IrqPolicy &policy) override
irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, const IrqPolicy &policy) override
irq_id_t registerPciMessageIrqHandler(IrqHandler *handler, Device *device, const IrqPolicy &intxFallbackPolicy) override
bool unregisterHandler(irq_id_t id, IrqHandlerBase *handler) override
bool registerPciMsixIrqHandlers(Device *device, IrqHandler *const *handlers, size_t count, irq_id_t *ids, bool &fallbackSafe, const size_t *processors=nullptr) override
bool unregisterSchedulerIrqHandler(irq_id_t id, SchedulerIrqHandler *handler) override
irq_id_t registerHardPciMessageIrqHandler(HardIrqHandler *handler, Device *device, const IrqPolicy &intxFallbackPolicy) override
irq_id_t registerHardIsaIrqHandler(uint8_t irq, HardIrqHandler *handler, const IrqPolicy &policy) override
irq_id_t registerSchedulerIrqHandler(uint8_t irq, SchedulerIrqHandler *handler, const IrqPolicy &policy) override
irq_id_t registerPciIrqHandler(IrqHandler *handler, Device *device, const IrqPolicy &policy) override