📄 ppctrap.s
字号:
// Initialize the TLB.
//
// r3 - address of the a physical to virtual table (if applicable)
//
bl TLBInit
//
// Enable relocation & internal interrupts.
//
li r1, KStack // (r1) = kernel stack
mfmsr r3 // Get current MSR
ori r3, r3, (MSR_IR | MSR_DR)
mtspr SRR1, r3
li r4, kMSR // Store default kernel MSR in KPage
ori r3, r3, (MSR_EE | MSR_ME) // Default kernel MSR has EE & ME on
stw r3, 0(r4)
lis r4, [hia]KernelContinue // (virtual) continuation addr
addi r4, r4, [lo]KernelContinue
mtspr SRR0, r4
rfi // switch modes
//
// Relocate kernel data from ROM to RAM.
//
// (r4) = virtual address of KernelContinue
KernelContinue:
#if 0 // SAVEGP
lis r2, [hia]_gp // set the GP value in R2
addi r2, r2, [lo]_gp
#else
li r2, 0
#endif
stw r2, NKGp(0) // save virtual address of Global Pointer
lis r3, [hia]pTOC // (r3) = ptr to ROM Table of contents
lwz r3, [lo]pTOC(r3)
bl KernelRelocate
bl OEMInitDebugSerial
lis r3, [hia]NKSignon
addi r3, r3, [lo]NKSignon
bl OEMWriteDebugString
li r3, APICallReturn
stw r3, PtrAPIRet(0)
li r3, -1
stw r3, CurAKey(0)
bl OEMInit
bl KernelFindMemory
bl KernelInit
bl CPUIdentify // Returns with (r3) = processor type
lis r4, [hia]CEProcessorType
stw r3, [lo]CEProcessorType(r4)
mfspr r3, PVR
rlwinm r5, r3, 16, 0xFFFF // ProcessorLevel = PVR[0:15]
lis r4, [hia]ProcessorLevel
sth r5, [lo]ProcessorLevel(r4)
rlwinm r5, r3, 0, 0xFFFF // ProcessorLevel = PVR[16:31]
lis r4, [hia]ProcessorRevision
sth r5, [lo]ProcessorRevision(r4)
li r14, 0 // no current thread
li r4, ID_RESCHEDULE // fake interrupt id for rescheduling
b Reschedule
DUMMY_EXIT(KernelStart)
//
// Exception Handling support routines:
//
.struct 0
CfBackChain: .space 4 // chain to previous call frame
.space 4 // Unused (align args at eight bytes)
.space 8*4 // 8 words space for call args
CfDispContext: .space 4 // space to save the incoming
// Dispatcher Context ptr
CfCstk: .space CstkSizeof // CALLSTACK struct (if needed) for mode switch.
CfRegs: .space 19 * 4 // Save permanent registers around funclet calls.
.align 3 // force frame length to multiple of
CfEnd: // eight bytes
#define CfFrameSize (CfEnd - CfDispContext)
#define SAVE_REGS(_base, reg)\
stw r13, _base+0(reg);\
stw r14, _base+4(reg);\
stw r15, _base+8(reg);\
stw r16, _base+12(reg);\
stw r17, _base+16(reg);\
stw r18, _base+20(reg);\
stw r19, _base+24(reg);\
stw r20, _base+28(reg);\
stw r21, _base+32(reg);\
stw r22, _base+36(reg);\
stw r23, _base+40(reg);\
stw r24, _base+44(reg);\
stw r25, _base+48(reg);\
stw r26, _base+52(reg);\
stw r27, _base+56(reg);\
stw r28, _base+60(reg);\
stw r29, _base+64(reg);\
stw r30, _base+68(reg);\
stw r31, _base+72(reg);
#define RESTORE_REGS(_base, reg)\
lwz r13, _base+0(reg);\
lwz r14, _base+4(reg);\
lwz r15, _base+8(reg);\
lwz r16, _base+12(reg);\
lwz r17, _base+16(reg);\
lwz r18, _base+20(reg);\
lwz r19, _base+24(reg);\
lwz r20, _base+28(reg);\
lwz r21, _base+32(reg);\
lwz r22, _base+36(reg);\
lwz r23, _base+40(reg);\
lwz r24, _base+44(reg);\
lwz r25, _base+48(reg);\
lwz r26, _base+52(reg);\
lwz r27, _base+56(reg);\
lwz r28, _base+60(reg);\
lwz r29, _base+64(reg);\
lwz r30, _base+68(reg);\
lwz r31, _base+72(reg);
//++
// EXCEPTION_DISPOSITION
// RtlpExecuteHandlerForException (
// IN PEXCEPTION_RECORD ExceptionRecord,
// IN ULONG EstablisherFrame,
// IN OUT PCONTEXT ContextRecord,
// IN OUT PDISPATCHER_CONTEXT DispatcherContext,
// IN PEXCEPTION_ROUTINE ExceptionRoutine
// )
//
// Routine Description:
// This function allocates a call frame, stores the establisher frame
// pointer in the frame, establishes an exception handler, and then calls
// the specified exception handler as an exception handler. If a nested
// exception occurs, then the exception handler of this function is called
// and the establisher frame pointer is returned to the exception dispatcher
// via the dispatcher context parameter. If control is returned to this
// routine, then the frame is deallocated and the disposition status is
// returned to the exception dispatcher.
//
// Arguments:
// ExceptionRecord (r3) - Supplies a pointer to an exception record.
//
// EstablisherFrame (r4) - Supplies the frame pointer of the establisher
// of the exception handler that is to be called.
//
// ContextRecord (r5) - Supplies a pointer to a context record.
//
// DispatcherContext (r6) - Supplies a pointer to the dispatcher context
// record.
//
// ExceptionRoutine (r7) - supplies a pointer to the function descriptor
// for the exception handler that is to be called.
//
// ExceptionMode (r8) - PSR value for running ExceptionRoutine
//
// Return Value:
// The disposition value returned by the specified exception handler is
// returned as the function value.
//--
NESTED_ENTRY_EX (RtlpExecuteHandlerForException,CfFrameSize,0,0,RtlpExceptionHandler,0)
SAVE_REGS(CfRegs, r1)
PROLOGUE_END (RtlpExecuteHandlerForException)
mtctr r7 // CTR <- entry point addr
stw r6, CfDispContext(r1) // save Dispatcher Context where
// RtlpExectionHandler can find it
andi. r0, r8, (1 << (31-MSR_BIT_PR))
bnela KPageJumpSwitch // mode switch & call handler
bctrl // call the exception handler
RESTORE_REGS(CfRegs, r1)
NESTED_EXIT (RtlpExecuteHandlerForException,CfFrameSize,0,0)
//++
// EXCEPTION_DISPOSITION
// RtlpExceptionHandler (
// IN PEXCEPTION_RECORD ExceptionRecord,
// IN ULONG EstablisherFrame,
// IN OUT PCONTEXT ContextRecord,
// IN OUT PDISPATCHER_CONTEXT DispatcherContext
// )
//
// Routine Description:
// This function is called when a nested exception occurs. Its function
// is to retrieve the establisher frame pointer from its establisher's
// call frame, store this information in the dispatcher context record,
// and return a disposition value of nested exception.
//
// Arguments:
// ExceptionRecord (r3) - Supplies a pointer to an exception record.
//
// EstablisherFrame (r4) - Supplies the frame pointer of the establisher
// of this exception handler.
//
// ContextRecord (r5) - Supplies a pointer to a context record.
//
// DispatcherContext (r6) - Supplies a pointer to the dispatcher context
// record.
//
// Return Value:
// A disposition value ExceptionNestedException is returned if an unwind
// is not in progress. Otherwise a value of ExceptionContinueSearch is
// returned.
//--
LEAF_ENTRY (RtlpExceptionHandler)
lwz r0, ErExceptionFlags (r3) // get exception flags
li r3, ExceptionContinueSearch // set usual disposition value
andi. r0, r0, EXCEPTION_UNWIND // check if unwind in progress
bnelr // if neq, unwind in progress
// return continue search disposition
//
// Unwind is not in progress - return nested exception disposition.
//
lwz r7,CfDispContext-CfEnd(r4) // get dispatcher context address
li r3, ExceptionNestedException // set disposition value
lwz r0, DcEstablisherFrame(r7) // copy the establisher environment
stw r0, DcEstablisherFrame (r6) // to current dispatcher context
LEAF_EXIT (RtlpExceptionHandler)
//++
// EXCEPTION_DISPOSITION
// RtlpExecuteHandlerForUnwind (
// IN PEXCEPTION_RECORD ExceptionRecord,
// IN PVOID EstablisherFrame,
// IN OUT PCONTEXT ContextRecord,
// IN OUT PVOID DispatcherContext,
// IN PEXCEPTION_ROUTINE ExceptionRoutine
// )
//
// Routine Description:
// This function allocates a call frame, stores the establisher frame
// pointer and the context record address in the frame, establishes an
// exception handler, and then calls the specified exception handler as
// an unwind handler. If a collided unwind occurs, then the exception
// handler of of this function is called and the establisher frame pointer
// and context record address are returned to the unwind dispatcher via
// the dispatcher context parameter. If control is returned to this routine,
// then the frame is deallocated and the disposition status is returned to
// the unwind dispatcher.
//
// Arguments:
// ExceptionRecord (r3) - Supplies a pointer to an exception record.
//
// EstablisherFrame (r4) - Supplies the frame pointer of the establisher
// of the exception handler that is to be called.
//
// ContextRecord (r5) - Supplies a pointer to a context record.
//
// DispatcherContext (r6) - Supplies a pointer to the dispatcher context
// record.
//
// ExceptionRoutine (r7) - supplies a pointer to the exception handler
// that is to be called.
//
// Return Value:
// The disposition value returned by the specified exception handler is
// returned as the function value.
//--
NESTED_ENTRY_EX (RtlpExecuteHandlerForUnwind,CfFrameSize,0,0,RtlpUnwindHandler,0)
SAVE_REGS(CfRegs, r1)
PROLOGUE_END (RtlpExecuteHandlerForUnwind)
lwz r8, CxMsr(r5) // (r8) = mode to dispatch function in
mtctr r7 // CTR <- entry point addr
stw r6, CfDispContext(r1) // save Dispatcher Context where
// RtlpExectionHandler can find it
andi. r0, r8, (1 << (31-MSR_BIT_PR))
bnela KPageJumpSwitch // mode switch & call handler
bctrl // call the exception handler
RESTORE_REGS(CfRegs, r1)
NESTED_EXIT (RtlpExecuteHandlerForUnwind,CfFrameSize,0,0)
//++
// EXCEPTION_DISPOSITION
// RtlpUnwindHandler (
// IN PEXCEPTION_RECORD ExceptionRecord,
// IN PVOID EstablisherFrame,
// IN OUT PCONTEXT ContextRecord,
// IN OUT PVOID DispatcherContext
// )
//
// Routine Description:
// This function is called when a collided unwind occurs. Its function
// is to retrieve the establisher dispatcher context, copy it to the
// current dispatcher context, and return a disposition value of nested
// unwind.
//
// Arguments:
// ExceptionRecord (r3) - Supplies a pointer to an exception record.
//
// EstablisherFrame (r4) - Supplies the frame pointer of the establisher
// of this exception handler.
//
// ContextRecord (r5) - Supplies a pointer to a context record.
//
// DispatcherContext (r6) - Supplies a pointer to the dispatcher context
// record.
//
// Return Value:
// A disposition value ExceptionCollidedUnwind is returned if an unwind is
// in progress. Otherwise, a value of ExceptionContinueSearch is returned.
//--
LEAF_ENTRY (RtlpUnwindHandler)
lwz r0, ErExceptionFlags(r3) // get exception flags
li r3, ExceptionContinueSearch // set usual disposition value
andi. r0, r0, EXCEPTION_UNWIND // check if unwind in progress
beqlr // if eq, unwind not in progress
// return continue search disposition
//
// Unwind is in progress - return collided exception disposition.
//
lwz r7, CfDispContext-CfEnd(r4) // get dispatcher context address
lwz r0, DcControlPc(r7) // copy the establisher frame's
lwz r3, DcFunctionEntry(r7) // dispatcher context to the
lwz r4, DcEstablisherFrame(r7) // current dispatcher context
lwz r5, DcContextRecord(r7)
stw r0, DcControlPc(r6)
stw r3, DcFunctionEntry(r6)
stw r4, DcEstablisherFrame(r6)
stw r5, DcContextRecord(r6)
li r3, ExceptionCollidedUnwind // return collided unwind disposition
LEAF_EXIT (RtlpUnwindHandler)
//++
//
// ULONG
// __C_ExecuteExceptionFilter (
// PEXCEPTION_POINTERS ExceptionPointers,
// EXCEPTION_FILTER ExceptionFilter,
// ULONG EstablisherFrame
// )
//
// Routine Description:
//
// This function calls the specified exception filter routine with the
// establisher frame passed in r12
//
// Arguments:
//
// ExceptionPointers (r.3) - Supplies a pointer to the exception pointers
// structure.
//
// ExceptionFilter (r.4) - Supplies the address of the excep
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -