20#include "pedigree/kernel/process/Thread.h"
21#include "pedigree/kernel/processor/Processor.h"
22#include "pedigree/kernel/utilities/Vector.h"
23#include "pedigree/kernel/utilities/assert.h"
24#include "pedigree/kernel/utilities/new"
26#include "system/kernel/core/processor/DeviceHardIrqContext.h"
37size_t ProcessorBase::m_nProcessors = 1;
56 case DeviceHardIrqOperation::Schedule:
57 return "Device hard-IRQ callback attempted to schedule.";
58 case DeviceHardIrqOperation::SemaphoreAcquire:
59 return "Device hard-IRQ callback attempted semaphore acquire.";
60 case DeviceHardIrqOperation::SemaphoreRelease:
61 return "Device hard-IRQ callback attempted semaphore release.";
62 case DeviceHardIrqOperation::WaitQueueAccess:
63 return "Device hard-IRQ callback attempted wait-queue access.";
64 case DeviceHardIrqOperation::HeapAllocate:
65 return "Device hard-IRQ callback attempted heap allocation.";
66 case DeviceHardIrqOperation::HeapFree:
67 return "Device hard-IRQ callback attempted heap free.";
69 return "Device hard-IRQ callback attempted a forbidden operation.";
75volatile size_t g_DeviceHardIrqTerminalViolation = 0;
79 __atomic_store_n(&g_DeviceHardIrqTerminalViolation,
static_cast<size_t>(operation) + 1,
83 const char*
message = deviceHardIrqViolationMessage(operation);
88 (void)write(STDERR_FILENO,
message, length);
89 (void)write(STDERR_FILENO,
"\n", 1);
99#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
100ProcessorBase::DeviceHardIrqOperationHook g_DeviceHardIrqOperationHook =
nullptr;
101size_t g_DeviceHardIrqOperationDenials = 0;
112 return ExecutionContext::AtomicThread;
116 if (explicitContext != ExecutionContext::WaitableThread) {
117 return explicitContext;
120 return getInterrupts() ? ExecutionContext::WaitableThread : ExecutionContext::AtomicThread;
124#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
125 DeviceHardIrqOperationHook hook =
126 __atomic_load_n(&g_DeviceHardIrqOperationHook, __ATOMIC_ACQUIRE);
127 if (hook && hook(operation)) {
128 __atomic_add_fetch(&g_DeviceHardIrqOperationDenials,
static_cast<size_t>(1), __ATOMIC_RELAXED);
134 terminateDeviceHardIrqViolation(operation);
137#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
138size_t ProcessorBase::deviceHardIrqDepthForTest() {
142void ProcessorBase::setDeviceHardIrqOperationHookForTest(DeviceHardIrqOperationHook hook) {
143 __atomic_store_n(&g_DeviceHardIrqOperationHook, hook, __ATOMIC_RELEASE);
146size_t ProcessorBase::deviceHardIrqOperationDenialsForTest() {
147 return __atomic_load_n(&g_DeviceHardIrqOperationDenials, __ATOMIC_RELAXED);
151DeviceHardIrqContext::DeviceHardIrqContext(
size_t& previousDepth,
bool& restorationArmed)
152 : m_Information(
Processor::information()),
153 m_RestorationArmed(restorationArmed),
154 m_PreviousDepth(m_Information.m_DeviceHardIrqDepth),
155 m_ExecutionContext(ExecutionContext::HardDeviceIrq) {
156 assert(!m_RestorationArmed);
157 previousDepth = m_PreviousDepth;
158 m_RestorationArmed =
true;
159 ++m_Information.m_DeviceHardIrqDepth;
162DeviceHardIrqContext::~DeviceHardIrqContext() {
164 assert(m_RestorationArmed);
166 m_RestorationArmed =
false;
173SuspendDeviceHardIrqContext::SuspendDeviceHardIrqContext()
174 : m_Information(
Processor::information()) {
175 assert(m_Information.m_DeviceHardIrqDepth == 1);
176 m_Information.m_DeviceHardIrqDepth = 0;
179SuspendDeviceHardIrqContext::~SuspendDeviceHardIrqContext() {
181 assert(m_Information.m_DeviceHardIrqDepth == 0);
182 m_Information.m_DeviceHardIrqDepth = 1;
185EnsureInterrupts::EnsureInterrupts(
bool desired) {
192EnsureInterrupts::~EnsureInterrupts() {
static void restoreDepth(size_t previousDepth)
static bool getInterrupts()
static ProcessorInformation & information()
static size_t m_Initialised
static bool inDeviceHardIrq()
static Vector< ProcessorInformation * > m_ProcessorInformation
static bool guardDeviceHardIrqOperation(DeviceHardIrqOperation operation)
static ExecutionContext executionContext()
static ProcessorInformation m_SafeBspProcessorInformation
static ProcessorInformation * informationAt(size_t cpu)
static void setInterrupts(bool bEnable)
static size_t isInitialised()
ExecutionContext executionContext() const
A vector / dynamic array.