1#include "InterruptManager.h"
2#include "pedigree/kernel/Log.h"
3#include "pedigree/kernel/panic.h"
4#include "pedigree/kernel/process/InterruptTimeAccounting.h"
5#include "pedigree/kernel/process/PerProcessorScheduler.h"
6#include "pedigree/kernel/process/Thread.h"
7#include "pedigree/kernel/processor/InterruptHandler.h"
8#include "pedigree/kernel/processor/Processor.h"
9#include "pedigree/kernel/processor/state.h"
11#include "SyscallManager.h"
13extern "C" void virtHandleIrq(InterruptState& state);
16void finishUserReturn(InterruptState& state) {
17 if (state.kernelMode()) {
25 bool terminal =
false;
34 if (terminal || !waited) {
43 panic(
"ARMv7: terminal user return unexpectedly resumed");
48Armv7InterruptManager::Armv7InterruptManager()
63 return Armv7InterruptManager::instance();
71 if (!expected && !handler) {
74 return __atomic_compare_exchange_n(&m_Handlers[number], &expected, handler,
false,
75 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
85 if (!expected && !handler) {
88 return __atomic_compare_exchange_n(&m_DebugHandlers[number], &expected, handler,
false,
89 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
93void Armv7InterruptManager::dispatch(
size_t number, InterruptState& state) {
95 panic(
"ARMv7: invalid exception number");
98 InterruptHandler* debugger = __atomic_load_n(&m_DebugHandlers[number], __ATOMIC_ACQUIRE);
103 InterruptHandler* handler = __atomic_load_n(&m_Handlers[number], __ATOMIC_ACQUIRE);
108 ERROR(
"ARMv7: unhandled exception " <<
Dec << number <<
" at " <<
Hex << state.pc);
109 panic(
"ARMv7: unhandled exception");
112extern "C" void armv7HandleException(InterruptState* state) {
113 if (!state->kernelMode()) {
117 asm volatile(
"mrc p15, 0, %0, c13, c0, 2" :
"=r"(tls));
121 if (state->vector == 2) {
122 Armv7SyscallManager::handle(*
static_cast<SyscallState*
>(state));
127 if (state->vector == 5) {
128 virtHandleIrq(*state);
129 }
else if (state->vector == 3 || state->vector == 4) {
130 Armv7InterruptManager::instance().dispatch(14, *state);
132 Armv7InterruptManager::instance().dispatch(state->vector, *state);
135 finishUserReturn(*state);
bool registerInterruptHandler(size_t number, InterruptHandler *handler) override
bool registerInterruptHandlerDebugger(size_t number, InterruptHandler *handler) override
Abstract base class for interrupt-handlers.
virtual void interrupt(size_t nInterruptNumber, InterruptState &state)=0
Handles interrupts and interrupt registrations from kernel components.
static EXPORTED_PUBLIC InterruptManager & instance()
static void finishUserReturn(Thread *thread)
void commitUserReturnTerminalState()
MUST_USE_RESULT bool serviceUserReturnWork(InterruptState &state, UserReturnFrame::Origin origin=UserReturnFrame::Origin::Interrupt, bool diagnosticSample=false)
static ProcessorInformation & information()
static void setInterrupts(bool bEnable)
void setTlsBase(uintptr_t base)
AffinityResult completeAffinityAtSafePoint(bool *waited=nullptr)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN