The Pedigree Project 0.1
SplitIrqHandler.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 PEDIGREE_KERNEL_MACHINE_SPLITIRQHANDLER_H
9#define PEDIGREE_KERNEL_MACHINE_SPLITIRQHANDLER_H
10#include "pedigree/kernel/Atomic.h"
11#include "pedigree/kernel/Spinlock.h"
12#include "pedigree/kernel/compiler.h"
13#include "pedigree/kernel/machine/IrqHandler.h"
14#include "pedigree/kernel/machine/ThreadedIrqDispatcher.h"
15#include "pedigree/kernel/machine/types.h"
16#include "pedigree/kernel/processor/state_forward.h"
17#include "pedigree/kernel/processor/types.h"
18
19#include <config.h>
20
21class Device;
22class IrqManager;
23class IrqPolicy;
24class String;
25
41class EXPORTED_PUBLIC SplitIrqHandler : private HardIrqHandler {
42 public:
43 enum class HardStageDisposition : size_t {
44 NotHandled,
45 Handled,
46 Deferred,
47 };
48
49 protected:
50 explicit SplitIrqHandler(const String& name);
51 virtual ~SplitIrqHandler();
52
54 bool initialiseSplitIrq();
55
57 irq_id_t registerIsaSplitIrq(IrqManager& manager, uint8_t irq, const IrqPolicy& policy);
58 irq_id_t registerPciSplitIrq(IrqManager& manager, Device& device, const IrqPolicy& policy);
59
68 bool shutdownSplitIrq();
69
71 virtual HardStageDisposition hardIrq(irq_id_t number, InterruptState& state, size_t& work) = 0;
72
79 virtual void threadedIrq(size_t work) = 0;
80
85 virtual bool quiesceIrqSources() = 0;
86
93 virtual void rearmIrqSources(size_t work) = 0;
94
95#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
96 using RegistrationPublishedHook = void (*)(SplitIrqHandler*);
97
98 HardIrqHandler* hardHandlerForTest();
99 void setRegistrationPublishedHookForTest(RegistrationPublishedHook hook);
100 size_t publicationFailuresForTest() const;
101 size_t pendingWorkForTest() const;
102 size_t deferredIrqsForTest() const;
103 size_t completedBatchesForTest() const;
104 bool publishWorkForTest(size_t work);
105 void rejectNextPublicationForTest();
106#endif
107
108 private:
109 static constexpr size_t MaxRegistrations = 16;
110
112 IrqManager* manager = nullptr;
113 irq_id_t id = 0;
114 };
115
116 ::HardIrqDisposition irq(irq_id_t number, InterruptState& state) final;
117 static void dispatchThreaded(void* context, uint8_t line, size_t cookie);
118 void dispatchThreaded();
119
120 bool publishWork(size_t work);
121
122 Registration m_Registrations[MaxRegistrations];
123 size_t m_RegistrationCount;
124 Atomic<size_t> m_LifecycleBusy;
125 Atomic<size_t> m_AcceptingRegistrations;
126 ThreadedIrqDispatcher m_Dispatcher;
127 Spinlock m_StateLock;
128 bool m_Quiescing;
129 Atomic<size_t> m_Stopping;
130 Atomic<size_t> m_PublicationFailures;
131 Atomic<size_t> m_DeferredIrqs;
132 Atomic<size_t> m_CompletedBatches;
133 size_t m_PendingWork;
134 bool m_Started;
135#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
136 RegistrationPublishedHook m_RegistrationPublishedHook;
137#endif
138
139 SplitIrqHandler(const SplitIrqHandler&) = delete;
140 SplitIrqHandler& operator=(const SplitIrqHandler&) = delete;
141};
142
143#endif
virtual HardIrqDisposition irq(irq_id_t number, InterruptState &state)=0
virtual void rearmIrqSources(size_t work)=0
virtual bool quiesceIrqSources()=0
virtual HardStageDisposition hardIrq(irq_id_t number, InterruptState &state, size_t &work)=0
virtual void threadedIrq(size_t work)=0
HardIrqDisposition
Definition IrqHandler.h:44