20 #include "InterruptManager.h" 21 #include "pedigree/kernel/LockGuard.h" 22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/debugger/Debugger.h" 24 #include "pedigree/kernel/machine/Machine.h" 25 #include "pedigree/kernel/machine/openfirmware/Device.h" 26 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h" 27 #include "pedigree/kernel/machine/types.h" 28 #include "pedigree/kernel/panic.h" 29 #include "pedigree/kernel/processor/Processor.h" 30 #include "pedigree/kernel/utilities/utility.h" 32 extern "C" int isr_reset;
33 extern "C" int isr_machine_check;
34 extern "C" int isr_dsi;
35 extern "C" int isr_isi;
36 extern "C" int isr_interrupt;
37 extern "C" int isr_alignment;
38 extern "C" int isr_program;
39 extern "C" int isr_fpu;
40 extern "C" int isr_decrementer;
41 extern "C" int isr_sc;
42 extern "C" int isr_trace;
43 extern "C" int isr_perf_mon;
44 extern "C" int isr_instr_breakpoint;
45 extern "C" int isr_system_management;
46 extern "C" int isr_thermal_management;
48 const char *g_pExceptions[] = {
"System reset",
55 "Floating-point unavailable",
59 "Performance monitor",
60 "Instruction address breakpoint",
61 "System management interrupt",
62 "Thermal management interrupt"};
81 interruptNumber >= 256 ||
82 interruptNumber == SYSCALL_INTERRUPT_NUMBER))
84 if (
UNLIKELY(pHandler != 0 && m_pHandler[interruptNumber] != 0))
86 if (
UNLIKELY(pHandler == 0 && m_pHandler[interruptNumber] == 0))
89 m_pHandler[interruptNumber] = pHandler;
100 interruptNumber >= 256 ||
101 interruptNumber == SYSCALL_INTERRUPT_NUMBER))
103 if (
UNLIKELY(pHandler != 0 && m_pDbgHandler[interruptNumber] != 0))
105 if (
UNLIKELY(pHandler == 0 && m_pDbgHandler[interruptNumber] == 0))
108 m_pDbgHandler[interruptNumber] = pHandler;
113 return TRAP_INTERRUPT_NUMBER;
117 return TRACE_INTERRUPT_NUMBER;
126 if (
UNLIKELY(Service >= serviceEnd))
128 if (
UNLIKELY(pHandler != 0 && m_pSyscallHandler[Service] != 0))
130 if (
UNLIKELY(pHandler == 0 && m_pSyscallHandler[Service] == 0))
133 m_pSyscallHandler[Service] = pHandler;
138 Service_t service, uintptr_t
function, uintptr_t p1, uintptr_t p2,
139 uintptr_t p3, uintptr_t p4, uintptr_t p5)
141 register uint32_t r3 __asm__(
"r3") =
142 ((service & 0xFFFF) << 16) | (
function & 0xFFFF);
143 register uint32_t r4 __asm__(
"r6") = p1;
144 register uint32_t r5 __asm__(
"r7") = p2;
145 register uint32_t r6 __asm__(
"r8") = p3;
146 register uint32_t r7 __asm__(
"r9") = p4;
147 register uint32_t r8 __asm__(
"r10") = p5;
151 :
"r"(r3),
"r"(r4),
"r"(r5),
"r"(r6),
"r"(r7),
"r"(r8));
161 OFDevice mmu(chosen.getProperty(
"mmu"));
165 "map", 4, reinterpret_cast<OFParam>(-1),
166 reinterpret_cast<OFParam>(0x3000), reinterpret_cast<OFParam>(0x0),
167 reinterpret_cast<OFParam>(0x0));
169 MemoryCopy(reinterpret_cast<void *>(0x0100), &isr_reset, 0x100);
170 MemoryCopy(reinterpret_cast<void *>(0x0200), &isr_machine_check, 0x100);
171 MemoryCopy(reinterpret_cast<void *>(0x0300), &isr_dsi, 0x100);
172 MemoryCopy(reinterpret_cast<void *>(0x0400), &isr_isi, 0x100);
173 MemoryCopy(reinterpret_cast<void *>(0x0500), &isr_interrupt, 0x100);
174 MemoryCopy(reinterpret_cast<void *>(0x0600), &isr_alignment, 0x100);
175 MemoryCopy(reinterpret_cast<void *>(0x0700), &isr_program, 0x100);
176 MemoryCopy(reinterpret_cast<void *>(0x0800), &isr_fpu, 0x100);
177 MemoryCopy(reinterpret_cast<void *>(0x0900), &isr_decrementer, 0x100);
178 MemoryCopy(reinterpret_cast<void *>(0x0C00), &isr_sc, 0x100);
179 MemoryCopy(reinterpret_cast<void *>(0x0D00), &isr_trace, 0x100);
180 MemoryCopy(reinterpret_cast<void *>(0x0F00), &isr_perf_mon, 0x100);
181 MemoryCopy(reinterpret_cast<void *>(0x1300), &isr_instr_breakpoint, 0x100);
182 MemoryCopy(reinterpret_cast<void *>(0x1400), &isr_system_management, 0x100);
184 reinterpret_cast<void *>(0x1700), &isr_thermal_management, 0x100);
186 for (uintptr_t i = 0x0; i < 0x1800; i += 4)
187 Processor::flushDCache(i);
189 asm volatile(
"sync");
191 for (uintptr_t i = 0; i < 0x1800; i += 4)
192 Processor::invalidateICache(i);
194 asm volatile(
"sync");
195 asm volatile(
"isync");
201 size_t intNumber = interruptState.getInterruptNumber();
205 if (m_Instance.m_pDbgHandler[intNumber] != 0)
207 m_Instance.m_pDbgHandler[intNumber]->interrupt(
208 intNumber, interruptState);
213 if (intNumber == SYSCALL_INTERRUPT_NUMBER)
215 size_t serviceNumber = interruptState.getSyscallService();
217 serviceNumber < serviceEnd &&
218 m_Instance.m_pSyscallHandler[serviceNumber] != 0))
219 interruptState.m_R3 =
220 m_Instance.m_pSyscallHandler[serviceNumber]->syscall(
223 else if (m_Instance.m_pHandler[intNumber] != 0)
224 m_Instance.m_pHandler[intNumber]->interrupt(intNumber, interruptState);
225 else if (intNumber != 6 && intNumber != 10)
230 e.append(
"Exception #");
231 e.append(interruptState.m_IntNumber, 10);
233 e.append(g_pExceptions[intNumber]);
239 "SRR0: " <<
Hex << interruptState.m_Srr0
240 <<
", SRR1: " << interruptState.m_Srr1);
242 "DAR: " << interruptState.m_Dar
243 <<
", DSISR: " << interruptState.m_Dsisr);
250 if (intNumber == TRAP_INTERRUPT_NUMBER)
252 interruptState.m_Srr0 += 4;
virtual size_t getDebugInterruptNumber() PURE
virtual bool registerInterruptHandlerDebugger(size_t interruptNumber, InterruptHandler *handler)
static OpenFirmware & instance()
static EXPORTED_PUBLIC SyscallManager & instance()
static Debugger & instance()
virtual bool registerSyscallHandler(Service_t Service, SyscallHandler *handler)
static void initialiseProcessor()
Handles interrupts and interrupt registrations from kernel components.
static PPC32InterruptManager m_Instance
static PPC32InterruptManager & instance()
void start(InterruptState &state, LargeStaticString &description)
static void interrupt(InterruptState &interruptState)
Abstract base class for interrupt-handlers.
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
static InterruptManager & instance()
virtual bool registerInterruptHandler(size_t interruptNumber, InterruptHandler *handler)
virtual ~PPC32InterruptManager()
virtual uintptr_t syscall(Service_t service, uintptr_t function, uintptr_t p1=0, uintptr_t p2=0, uintptr_t p3=0, uintptr_t p4=0, uintptr_t p5=0)
virtual size_t getBreakpointInterruptNumber() PURE