⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppctrap.s

📁 可用于嵌入式编程学习
💻 S
📖 第 1 页 / 共 5 页
字号:
// 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 + -