The Pedigree Project 0.1
include/pedigree/kernel/machine/IrqManager.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_MACHINE_IRQMANAGER_H
21#define KERNEL_MACHINE_IRQMANAGER_H
22
23#include "pedigree/kernel/machine/types.h"
24#include "pedigree/kernel/processor/types.h"
25
26class Device;
27class HardIrqHandler;
28class IrqHandler;
29class IrqHandlerBase;
31
40enum class IrqTrigger : uint8_t {
41 Edge,
42 Level,
43 Synthetic,
44};
45
47enum class IrqControllerAck : uint8_t {
48 None,
49 BeforeHardStage,
50 AfterHardStage,
51};
52
54enum class IrqLineRelease : uint8_t {
55 AfterHardStage,
56 AfterThreadedCompletion,
57};
58
68class IrqPolicy {
69 public:
70 constexpr IrqPolicy(IrqTrigger trigger, IrqControllerAck controllerAck,
71 IrqLineRelease lineRelease)
72 : m_Trigger(trigger), m_ControllerAck(controllerAck), m_LineRelease(lineRelease) {}
73
74 static constexpr IrqPolicy edgeHard() {
75 return IrqPolicy(IrqTrigger::Edge, IrqControllerAck::BeforeHardStage,
76 IrqLineRelease::AfterHardStage);
77 }
78
79 static constexpr IrqPolicy edgeThreaded() {
80 return IrqPolicy(IrqTrigger::Edge, IrqControllerAck::AfterHardStage,
81 IrqLineRelease::AfterHardStage);
82 }
83
84 static constexpr IrqPolicy levelHard() {
85 return IrqPolicy(IrqTrigger::Level, IrqControllerAck::AfterHardStage,
86 IrqLineRelease::AfterHardStage);
87 }
88
89 static constexpr IrqPolicy levelThreaded() {
90 return IrqPolicy(IrqTrigger::Level, IrqControllerAck::AfterHardStage,
91 IrqLineRelease::AfterThreadedCompletion);
92 }
93
94 static constexpr IrqPolicy pciIntxHard() {
95 return levelHard();
96 }
97
98 static constexpr IrqPolicy pciIntxThreaded() {
99 return levelThreaded();
100 }
101
102 static constexpr IrqPolicy syntheticHard() {
103 return IrqPolicy(IrqTrigger::Synthetic, IrqControllerAck::None, IrqLineRelease::AfterHardStage);
104 }
105
106 static constexpr IrqPolicy syntheticThreaded() {
107 return IrqPolicy(IrqTrigger::Synthetic, IrqControllerAck::None, IrqLineRelease::AfterHardStage);
108 }
109
110 constexpr IrqTrigger trigger() const {
111 return m_Trigger;
112 }
113
114 constexpr IrqControllerAck controllerAck() const {
115 return m_ControllerAck;
116 }
117
118 constexpr IrqLineRelease lineRelease() const {
119 return m_LineRelease;
120 }
121
122 constexpr bool validForHard() const {
123 return valid() && m_LineRelease == IrqLineRelease::AfterHardStage &&
124 !(m_Trigger == IrqTrigger::Level &&
125 m_ControllerAck == IrqControllerAck::BeforeHardStage);
126 }
127
128 constexpr bool validForThreaded() const {
129 return valid() &&
130 ((m_Trigger == IrqTrigger::Level &&
131 m_LineRelease == IrqLineRelease::AfterThreadedCompletion) ||
132 (m_Trigger != IrqTrigger::Level && m_LineRelease == IrqLineRelease::AfterHardStage));
133 }
134
135 constexpr bool operator==(const IrqPolicy& other) const {
136 return m_Trigger == other.m_Trigger && m_ControllerAck == other.m_ControllerAck &&
137 m_LineRelease == other.m_LineRelease;
138 }
139
140 constexpr bool operator!=(const IrqPolicy& other) const {
141 return !(*this == other);
142 }
143
144 private:
145 constexpr bool valid() const {
146 const bool synthetic = m_Trigger == IrqTrigger::Synthetic;
147 if (synthetic != (m_ControllerAck == IrqControllerAck::None)) {
148 return false;
149 }
150
151 return m_LineRelease != IrqLineRelease::AfterThreadedCompletion ||
152 m_Trigger == IrqTrigger::Level;
153 }
154
155 IrqTrigger m_Trigger;
156 IrqControllerAck m_ControllerAck;
157 IrqLineRelease m_LineRelease;
158};
159
161enum class IrqDelivery : uint8_t {
162 None,
163 Hard,
164 Threaded,
165 Mixed,
166};
167
169enum IrqMaskReason : uint16_t {
170 IrqMaskNone = 0,
171 IrqMaskNoHandler = 1U << 0,
172 IrqMaskAdministrativelyDisabled = 1U << 1,
173 IrqMaskAwaitingAcknowledgement = 1U << 2,
174 IrqMaskAwaitingThreadedCompletion = 1U << 3,
175 IrqMaskMitigated = 1U << 4,
176 IrqMaskShuttingDown = 1U << 5,
177 IrqMaskControllerContention = 1U << 6,
178};
179
181enum class IrqWorkerDebugState : uint8_t {
182 Unavailable,
183 None,
184 SemaphoreWait,
185 ConditionWait,
186 Joining,
187 FutexWait,
188 EventWait,
189 ProcessWait,
190 CallbackDrain,
191};
192
194enum class IrqWorkerWaitReason : uint8_t {
195 Unavailable,
196 Waiting,
197 Signalled,
198 Event,
199 Unwinding,
200 Terminating,
201 Spurious,
202};
203
205enum class IrqControllerPromptState : uint8_t {
206 NotRequired,
207 Submitted,
208 Failed,
209};
210
221 size_t snapshotGeneration;
222 size_t observationTimestamp;
223 size_t dispatchGeneration;
224 size_t acknowledgedGeneration;
225 size_t activeHardDispatchCount;
226 size_t activeHardDispatchGeneration;
227 size_t activeThreadedDispatchCount;
228 size_t publicationCookie;
229 size_t pendingCookie;
230 size_t activeCookie;
231 size_t completedCookie;
232 size_t completedBatches;
235 size_t activeCallbackStartedTimestamp;
236 size_t lastWakeLatency;
237 size_t maximumWakeLatency;
238 size_t lastCallbackRuntime;
239 size_t maximumCallbackRuntime;
240 size_t interruptCount;
241 size_t spuriousCount;
242 size_t unhandledCount;
243 size_t publicationFailures;
244 size_t removalRejections;
245 size_t controllerContentions;
246 size_t controllerPromptAttempts;
247 size_t controllerPromptFailures;
248 size_t controllerPromptDestination;
249 size_t diagnosticPublicationFailures;
250 uintptr_t workerIdentity;
251 uintptr_t activeThreadedHandlerIdentity;
252 uintptr_t workerDebugAddress;
253 uintptr_t workerWaitQueue;
254 uintptr_t workerWaitChannelOwner;
255 uintptr_t workerWaitChannelValue;
256 size_t workerWaitStateLevel;
257 size_t handlerCount;
258 uint16_t maskReasons;
259 uint8_t line;
260 IrqDelivery delivery;
261 IrqTrigger trigger;
262 IrqControllerAck controllerAck;
263 IrqLineRelease lineRelease;
264 IrqWorkerDebugState workerDebugState;
265 IrqWorkerWaitReason workerWaitReason;
266 IrqControllerPromptState controllerPromptState;
267 bool configured;
268 bool effectiveMasked;
269 bool requestedEnabled;
270 bool acknowledgementPending;
271 bool threadedPending;
272 bool dispatcherInitialised;
273 bool dispatcherActive;
274 bool dispatcherClosed;
275 bool hardStageActive;
276 bool workerDiagnosticAvailable;
277 bool workerWaitActive;
278 bool workerWaitQueued;
279};
280
283 public:
286 MitigationThreshold,
289 };
290
296 virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler* handler,
297 const IrqPolicy& policy) = 0;
299 virtual irq_id_t registerPciIrqHandler(IrqHandler* handler, Device* pDevice,
300 const IrqPolicy& policy) = 0;
301
303 virtual irq_id_t registerPciMessageIrqHandler(IrqHandler* handler, Device* pDevice,
304 const IrqPolicy& intxFallbackPolicy);
305
309 virtual bool registerPciMsixIrqHandlers(Device* device, IrqHandler* const* handlers, size_t count,
310 irq_id_t* ids, bool& fallbackSafe,
311 const size_t* processors = nullptr);
312
314 virtual irq_id_t registerHardIsaIrqHandler(uint8_t irq, HardIrqHandler* handler,
315 const IrqPolicy& policy) = 0;
316
318 virtual irq_id_t registerHardPciIrqHandler(HardIrqHandler* handler, Device* pDevice,
319 const IrqPolicy& policy) = 0;
320
322 virtual irq_id_t registerHardPciMessageIrqHandler(HardIrqHandler* handler, Device* pDevice,
323 const IrqPolicy& intxFallbackPolicy);
324
332 virtual irq_id_t registerSchedulerIrqHandler(uint8_t irq, SchedulerIrqHandler* handler,
333 const IrqPolicy& policy);
334
341 virtual bool unregisterSchedulerIrqHandler(irq_id_t Id, SchedulerIrqHandler* handler);
353 virtual bool unregisterHandler(irq_id_t Id, IrqHandlerBase* handler) = 0;
354
355 virtual void enable(uint8_t irq, bool enable) = 0;
356
361 virtual size_t snapshotIrqLines(IrqLineDiagnosticSnapshot* out, size_t capacity) const;
362
364 virtual void tick();
365
367 virtual bool control(uint8_t irq, ControlCode code, size_t argument);
368
369 protected:
373 virtual ~IrqManager();
374
375 private:
382};
383
386#endif
Definition Event.h:49
virtual irq_id_t registerHardPciIrqHandler(HardIrqHandler *handler, Device *pDevice, const IrqPolicy &policy)=0
virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, const IrqPolicy &policy)=0
virtual bool unregisterHandler(irq_id_t Id, IrqHandlerBase *handler)=0
virtual irq_id_t registerPciIrqHandler(IrqHandler *handler, Device *pDevice, const IrqPolicy &policy)=0
virtual irq_id_t registerPciMessageIrqHandler(IrqHandler *handler, Device *pDevice, const IrqPolicy &intxFallbackPolicy)
Definition IrqManager.cc:25
virtual bool control(uint8_t irq, ControlCode code, size_t argument)
Definition IrqManager.cc:55
virtual irq_id_t registerSchedulerIrqHandler(uint8_t irq, SchedulerIrqHandler *handler, const IrqPolicy &policy)
Definition IrqManager.cc:41
virtual bool registerPciMsixIrqHandlers(Device *device, IrqHandler *const *handlers, size_t count, irq_id_t *ids, bool &fallbackSafe, const size_t *processors=nullptr)
Definition IrqManager.cc:30
virtual void tick()
Definition IrqManager.cc:53
virtual ~IrqManager()
virtual irq_id_t registerHardPciMessageIrqHandler(HardIrqHandler *handler, Device *pDevice, const IrqPolicy &intxFallbackPolicy)
Definition IrqManager.cc:36
virtual irq_id_t registerHardIsaIrqHandler(uint8_t irq, HardIrqHandler *handler, const IrqPolicy &policy)=0
IrqManager(const IrqManager &)
virtual size_t snapshotIrqLines(IrqLineDiagnosticSnapshot *out, size_t capacity) const
Definition IrqManager.cc:49
IrqManager & operator=(const IrqManager &)
virtual bool unregisterSchedulerIrqHandler(irq_id_t Id, SchedulerIrqHandler *handler)
Definition IrqManager.cc:45