20 #include "InterruptManager.h" 21 #include "pedigree/kernel/LockGuard.h" 22 #include "pedigree/kernel/panic.h" 23 #include "pedigree/kernel/utilities/StaticString.h" 25 #include "pedigree/kernel/debugger/Debugger.h" 29 #include "pedigree/kernel/Subsystem.h" 30 #include "pedigree/kernel/process/Process.h" 61 if (
UNLIKELY(nInterruptNumber >= MAX_SIGNAL))
63 if (
UNLIKELY(pHandler != 0 && m_pHandler[nInterruptNumber] != 0))
65 if (
UNLIKELY(pHandler == 0 && m_pHandler[nInterruptNumber] == 0))
69 m_pHandler[nInterruptNumber] = pHandler;
83 if (
UNLIKELY(nInterruptNumber >= MAX_SIGNAL))
85 if (
UNLIKELY(pHandler != 0 && m_pDbgHandler[nInterruptNumber] != 0))
87 if (
UNLIKELY(pHandler == 0 && m_pDbgHandler[nInterruptNumber] == 0))
91 m_pDbgHandler[nInterruptNumber] = pHandler;
108 size_t nIntNumber = interruptState.getInterruptNumber();
110 #if defined(DEBUGGER) 117 pHandler = m_Instance.m_pDbgHandler[nIntNumber];
123 pHandler->
interrupt(nIntNumber, interruptState);
133 pHandler = m_Instance.m_pHandler[nIntNumber];
137 if (
LIKELY(pHandler != 0))
139 pHandler->
interrupt(nIntNumber, interruptState);
143 if (
UNLIKELY(nIntNumber == SIGINT || nIntNumber == SIGTERM))
148 panic(
"shutdown failed");
156 Subsystem *pSubsystem = pProcess->getSubsystem();
164 else if (
UNLIKELY(nIntNumber == SIGFPE))
173 if (
LIKELY(nIntNumber != SIGTRAP))
182 e.append(
"Signal #0x");
183 e.append(nIntNumber, 16);
184 #if defined(DEBUGGER) 196 static void handler(
int which, siginfo_t *info,
void *ptr)
205 if (which == SIGUSR1 || which == SIGUSR2)
207 FATAL_NOLOCK(
"interrupts disabled but interrupts are firing");
211 siginfo_t *info =
reinterpret_cast<siginfo_t *
>(siginfo);
213 InterruptState state;
215 state.extra =
reinterpret_cast<uint64_t
>(info);
216 state.state =
reinterpret_cast<uint64_t
>(info->si_value.sival_ptr);
217 state.meta =
reinterpret_cast<uint64_t
>(meta);
221 ucontext_t *ctx =
reinterpret_cast<ucontext_t *
>(meta);
222 sigprocmask(0, 0, &ctx->uc_sigmask);
228 for (
int i = 1; i < MAX_SIGNAL; ++i)
230 struct sigaction act;
231 ByteSet(&act, 0,
sizeof(act));
232 act.sa_sigaction = handler;
233 sigemptyset(&act.sa_mask);
234 act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER;
236 sigaction(i, &act, 0);
243 for (
size_t i = 0; i < MAX_SIGNAL; i++)
static bool getInterrupts()
static HostedInterruptManager & instance()
void signalShim(int which, void *siginfo, void *meta)
static void initialiseProcessor() INITIALISATION_ONLY
static Debugger & instance()
Handles interrupts and interrupt registrations from kernel components.
virtual void threadException(Thread *pThread, ExceptionType eType)
static ProcessorInformation & information()
virtual bool registerInterruptHandler(size_t nInterruptNumber, InterruptHandler *pHandler)
virtual bool registerInterruptHandlerDebugger(size_t nInterruptNumber, InterruptHandler *pHandler)
virtual size_t getDebugInterruptNumber() PURE
void start(InterruptState &state, LargeStaticString &description)
virtual size_t getBreakpointInterruptNumber() PURE
virtual void interrupt(size_t nInterruptNumber, InterruptState &state)=0
virtual ~HostedInterruptManager()
InterruptHandler * m_pHandler[MAX_SIGNAL]
static HostedInterruptManager m_Instance
Process * getParent() const
InterruptHandler * m_pDbgHandler[MAX_SIGNAL]
Abstract base class for interrupt-handlers.
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
static InterruptManager & instance()
static void interrupt(InterruptState &interruptState)
HostedInterruptManager() INITIALISATION_ONLY