📄 mdppc.c
字号:
/* Copyright (c) 1996-2000 Microsoft Corporation. All rights reserved. *//*+ mdppc.c - PowerPC machine dependent code & data */#include "kernel.h"#include "kxppc.h"#if defined(PPC403)extern void SetPID(int);#elif defined(PPC821)#include "mmu821.h"#define MAX_ASID 15 // Maximum Address Space ID supported by the 821uchar ASIDMap[MAX_PROCESSES] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,}; // map from process number to address space IDint NextASID = 0; // next available address space IDextern void SetCASID(int);#endif// These are filled in by KernelStartDWORD CEProcessorType = 0; // 821, 823, 401, or 403WORD ProcessorLevel = 0; // PVR[0:15]WORD ProcessorRevision = 0; // PVR[16:31]const wchar_t NKSignon[] = TEXT("Windows CE Kernel for PowerPC Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");void NextThread(void);void KCNextThread(void);ulong OEMInterruptHandler(void);ulong OEMDecrementer(void);void OEMIdle(void);void DoPowerOff(void);#define KERNEL_MSR (KData.kMSR) // Default kernel MSR#define USER_MSR (KERNEL_MSR | MSR_PR) // Problem state=1#define SRR1_TRAP 0x20000 // SRR1 bit indicating program trap#define TO_BKP 0x16 // trap BREAKPOINT#define TO_DIV0 0x06 // trap Integer DIV by zero#define TO_DIV0U 0x07 // trap unconditional DIV by 0void DumpDwords(PDWORD pdw, int len) { int lc; lc = 0; NKDbgPrintfW(L"Dumping %d dwords", len); for (lc = 0 ; len ; ++pdw, ++lc, --len) { if (!(lc & 3)) NKDbgPrintfW(L"\r\n%8.8lx -", pdw); NKDbgPrintfW(L" %8.8lx", *pdw); } NKDbgPrintfW(L"\r\n");}void DumpFrame(PTHREAD pth, PCPUCONTEXT pctx, int id, ulong excInfo, int level) { UINT32 addr; NKDbgPrintfW(L"Exception %03x Thread=%8.8lx AKY=%8.8lx PC=%8.8lx excInfo=%8.8lx\r\n", id, pth, pCurThread->aky, pctx->Iar, excInfo); NKDbgPrintfW(L"SR=%8.8lx CR=%8.8lx XER=%8.8lx LR=%8.8lx CTR=%8.8lx\r\n", pctx->Msr, pctx->Cr, pctx->Xer, pctx->Lr, pctx->Ctr); NKDbgPrintfW(L" G0=%8.8lx G1=%8.8lx G2=%8.8lx G3=%8.8lx\r\n", pctx->Gpr0, pctx->Gpr1, pctx->Gpr2, pctx->Gpr3); NKDbgPrintfW(L" G4=%8.8lx G5=%8.8lx G6=%8.8lx G7=%8.8lx\r\n", pctx->Gpr4, pctx->Gpr5, pctx->Gpr6, pctx->Gpr7); NKDbgPrintfW(L" G8=%8.8lx G9=%8.8lx G10=%8.8lx G11=%8.8lx\r\n", pctx->Gpr8, pctx->Gpr9, pctx->Gpr10, pctx->Gpr11); NKDbgPrintfW(L"G12=%8.8lx G13=%8.8lx G14=%8.8lx G15=%8.8lx\r\n", pctx->Gpr12, pctx->Gpr13, pctx->Gpr14, pctx->Gpr15); NKDbgPrintfW(L"G16=%8.8lx G17=%8.8lx G18=%8.8lx G19=%8.8lx\r\n", pctx->Gpr16, pctx->Gpr17, pctx->Gpr18, pctx->Gpr19); NKDbgPrintfW(L"G20=%8.8lx G21=%8.8lx G22=%8.8lx G23=%8.8lx\r\n", pctx->Gpr20, pctx->Gpr21, pctx->Gpr22, pctx->Gpr23); NKDbgPrintfW(L"G24=%8.8lx G25=%8.8lx G26=%8.8lx G27=%8.8lx\r\n", pctx->Gpr24, pctx->Gpr25, pctx->Gpr26, pctx->Gpr27); NKDbgPrintfW(L"G28=%8.8lx G29=%8.8lx G30=%8.8lx G31=%8.8lx\r\n", pctx->Gpr28, pctx->Gpr29, pctx->Gpr30, pctx->Gpr31); if (level > 1) { addr = (pctx->Iar & -4) - 8*4; if (VerifyAccess((PVOID)addr, VERIFY_KERNEL_OK, CurAKey)) DumpDwords((PDWORD)addr, 12); }}typedef struct ExcInfo { DWORD linkage; ULONG oldIar; UINT oldMode; char id; char StoreOp; WORD lowSp; ULONG excInfo;} EXCINFO;typedef EXCINFO *PEXCINFO;ERRFALSE(sizeof(EXCINFO) <= sizeof(CALLSTACK));ERRFALSE(offsetof(EXCINFO,linkage) == offsetof(CALLSTACK,pcstkNext));ERRFALSE(offsetof(EXCINFO,oldIar) == offsetof(CALLSTACK,retAddr));ERRFALSE(offsetof(EXCINFO,oldMode) == offsetof(CALLSTACK,pprcLast));ERRFALSE(1024 >= sizeof(CALLSTACK) + STK_SLACK_SPACE + sizeof(CONTEXT) + 0x28); // 0x28 == StackFrameHeaderLengthBOOL HandleException(PTHREAD pth, int id, ulong addr, uint StoreOp) { PEXCINFO pexi; DWORD stackaddr;#if 0 NKDbgPrintfW(L"Exception %02x00 Thread=%8.8lx Proc=%8.8lx\r\n",id, pth, hCurProc); NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx Lr=%8.8lx DAR=%8.8lx\r\n",pCurThread->aky, pth->ctx.Iar, pth->ctx.Lr, addr);#endif KCALLPROFON(0); pexi = (struct ExcInfo *)((pth->ctx.Gpr1 & ~1023) - ALIGN8(STK_SLACK_SPACE + sizeof(CALLSTACK))); if (!((DWORD)pexi & 0x80000000) && DemandCommit((DWORD)pexi)) { stackaddr = (DWORD)pexi & ~(PAGE_SIZE-1); if ((stackaddr >= pth->dwStackBound) || (stackaddr < pth->dwStackBase) || ((pth->dwStackBound = stackaddr) >= (pth->dwStackBase + MIN_STACK_RESERVE)) || TEST_STACKFAULT(pth)) { KCALLPROFOFF(0); return TRUE; // restart instruction } SET_STACKFAULT(pth); id = ID_STACK_FAULT; // stack fault exception code addr = (DWORD)pexi; } if (pth->ctx.Iar != (ulong)CaptureContext) { pexi->id = id; pexi->lowSp = (WORD)(pth->ctx.Gpr1 & 1023); pexi->oldIar = pth->ctx.Iar; pexi->oldMode = GetThreadMode(pth); pexi->excInfo = (id == ID_PROGRAM) ? pth->ctx.Msr : addr; pexi->StoreOp = StoreOp; pexi->linkage = (DWORD)pCurThread->pcstkTop | 1; pCurThread->pcstkTop = (PCALLSTACK)pexi; pth->ctx.Gpr1 = (DWORD)pexi; SetThreadMode(pth, KERNEL_MODE); pth->ctx.Iar = (ULONG)CaptureContext; KCALLPROFOFF(0); return TRUE; // continue execution } DumpFrame(pth, &pth->ctx, id, addr, 10); RETAILMSG(1, (TEXT("Halting thread %8.8lx\r\n"), pth)); SurrenderCritSecs(); SET_RUNSTATE(pth,RUNSTATE_BLOCKED); RunList.pth = 0; SetReschedule(); KCALLPROFOFF(0); return FALSE;}// SetCPUASID - setup processor specific address space information//// SetCPUASID will update the virtual memory tables so that new current process// is mapped into slot 0 and set the h/w address space ID register for the new// process.//// Entry (pth) = ptr to THREAD structure// Return nothingvoid SetCPUASID(PTHREAD pth) { PPROCESS pprc; int ix; CurAKey = pth->aky; pCurProc = pprc = pth->pProc;#ifdef CELOG if (hCurProc != pprc->hProc) { CELOG_ThreadMigrate(pprc->hProc, 0); }#endif hCurProc = pprc->hProc; SectionTable[0] = SectionTable[pprc->dwVMBase>>VA_SECTION]; ix = pprc->procnum;#if defined(PPC821) INTERRUPTS_OFF(); if (ASIDMap[ix] == 0xFF) { // Assign an address space ID to this process if (NextASID > MAX_ASID) { memset(ASIDMap, 0xff, sizeof(ASIDMap)); NextASID = 0; FlushTLB(); } ASIDMap[ix] = NextASID++; } SetCASID(ASIDMap[ix]); INTERRUPTS_ON();#elif defined(PPC403) SetPID(ix+1);#else #error "Unsupported CPU type"#endif}typedef struct _EXCARGS { DWORD dwExceptionCode; /* exception code */ DWORD dwExceptionFlags; /* continuable exception flag */ DWORD cArguments; /* number of arguments in array */ DWORD *lpArguments; /* address of array of arguments */} EXCARGS;void ExceptionDispatch(PCONTEXT pctx) { EXCEPTION_RECORD er; int id; EXCARGS *pea; BOOL bHandled; PTHREAD pth; PEXCINFO pexi; pth = pCurThread; pexi = (PEXCINFO)pth->pcstkTop; DEBUGMSG(ZONE_SEH, (TEXT("ExceptionDispatch: pexi=%8.8lx Iar=%8.8lx Id=0x%x\r\n"), pexi, pexi->oldIar, pexi->id)); pctx->Iar = pexi->oldIar; pctx->Msr = pexi->oldMode==KERNEL_MODE ? KERNEL_MSR : USER_MSR; pctx->Gpr1 = (ULONG)pctx + sizeof(CONTEXT); memset(&er, 0, sizeof(er)); er.ExceptionAddress = (PVOID)pctx->Iar; // Check for RaiseException call versus a CPU detected exception. // RaiseException just becomes a call to CaptureContext as a KPSL. // HandleExcepion sets the LSB of the callstack linkage but ObjectCall // does not. if (!(pexi->linkage & 1)) { pea = (EXCARGS *)(pctx->Gpr1 + offsetof(STACK_FRAME_HEADER, Parameter0)); DEBUGMSG(ZONE_SEH, (TEXT("Raising exception %x flags=%x args=%d pexi=%8.8lx\r\n"), pea->dwExceptionCode, pea->dwExceptionFlags, pea->cArguments, pexi)); er.ExceptionCode = pea->dwExceptionCode; er.ExceptionFlags = pea->dwExceptionFlags; if (pea->lpArguments && pea->cArguments) { if (pea->cArguments > EXCEPTION_MAXIMUM_PARAMETERS) { er.ExceptionCode = STATUS_INVALID_PARAMETER; er.ExceptionFlags = EXCEPTION_NONCONTINUABLE; } else { memcpy(er.ExceptionInformation, pea->lpArguments,pea->cArguments*sizeof(DWORD)); er.NumberParameters = pea->cArguments; } } } else { // CPU detected exception. Extract some additional information about // the cause of the exception from the EXCINFO (CALLSTACK) structure. id = pexi->id; pctx->Gpr1 += pexi->lowSp + ALIGN8(sizeof(CALLSTACK) + STK_SLACK_SPACE); if (((id == ID_CPAGE_FAULT) || (id == ID_DPAGE_FAULT)) && AutoCommit(pexi->excInfo)) { pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; } switch (id) { case ID_ALIGNMENT: er.ExceptionCode = STATUS_DATATYPE_MISALIGNMENT; break; case ID_PROGRAM: // // Extract the exception cause from the SRR1 value. // In the case of program exceptions the general handler stores // the SRR1 value in the pexi->excInfo field. // if (pexi->excInfo & SRR1_TRAP) { // program trap ?? er.ExceptionInformation[0] = *(ULONG *)pctx->Iar & 0xffff; if ( er.ExceptionInformation[0] == TO_BKP ) er.ExceptionCode = STATUS_BREAKPOINT; else // if ( er.ExceptionInformation[0] == TO_DIV0 ) er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO; } break; case ID_DPAGE_FAULT: // Data page fault er.ExceptionInformation[0] = pexi->StoreOp; // == 1 if Store // fall through:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -