📄 mdarm.c
字号:
/* Copyright (c) 1996-2000 Microsoft Corporation. All rights reserved. */#include "kernel.h"#ifdef THUMBSUPPORT#define THUMB_SUPPORT_STR TEXT("(Thumb Enabled)")#else#define THUMB_SUPPORT_STR TEXT(" ")#endif#ifdef THUMBconst wchar_t NKSignon[] = TEXT("Windows CE Kernel for THUMB ") THUMB_SUPPORT_STR TEXT(" Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");#elseconst wchar_t NKSignon[] = TEXT("Windows CE Kernel for ARM ") THUMB_SUPPORT_STR TEXT(" Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");#endifDWORD CEProcessorType;WORD ProcessorLevel = 4;WORD ProcessorRevision;DWORD CurMSec;DWORD DiffMSec;// Fault Status register fields:#define FSR_DOMAIN 0xF0#define FSR_STATUS 0x0D#define FSR_PAGE_ERROR 0x02#define FSR_ALIGNMENT 0x01#define FSR_TRANSLATION 0x05#define FSR_DOMAIN_ERROR 0x09#define FSR_PERMISSION 0x0D#define BREAKPOINT 0x06000010 // special undefined instruction#define THM_BREAKPOINT 0xDEFE // Thumb equivalentconst LPCSTR IdStrings[] = { "RaiseException", "Reschedule", "Undefined Instruction", "SWI", "Prefetch Abort", "Data Abort", "IRQ", "<Invalid>", "<Invalid>", "[Stack fault]", "[HW Break]",};void 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 addr, int level) { NKDbgPrintfW(L"Exception '%a' Thread=%8.8lx AKY=%8.8lx PC=%8.8lx BVA=%8.8lx\r\n", IdStrings[id+1], pth, pCurThread->aky, pctx->Pc, addr); NKDbgPrintfW(L" R0=%8.8lx R1=%8.8lx R2=%8.8lx R3=%8.8lx\r\n", pctx->R0, pctx->R1, pctx->R2, pctx->R3); NKDbgPrintfW(L" R4=%8.8lx R5=%8.8lx R6=%8.8lx R7=%8.8lx\r\n", pctx->R4, pctx->R5, pctx->R6, pctx->R7); NKDbgPrintfW(L" R8=%8.8lx R9=%8.8lx R10=%8.8lx R11=%8.8lx\r\n", pctx->R8, pctx->R9, pctx->R10, pctx->R11); NKDbgPrintfW(L"R12=%8.8lx SP=%8.8lx Lr=%8.8lx Psr=%8.8lx\r\n", pctx->R12, pctx->Sp, pctx->Lr, pctx->Psr);}void NextThread(void);void KCNextThread(void);void OEMIdle(void);void DoPowerOff(void);void __declspec(iw32) TLBClear(void);ulong OEMInterruptHandler(void);extern char InterlockedAPIs[], InterlockedEnd[];void ARMInit(int cpuType, int abSp, int iSp, int uSp) { int ix; /* Initialize SectionTable in KPage */ for (ix = 1 ; ix <= SECTION_MASK ; ++ix) SectionTable[ix] = NULL_SECTION; /* Copy kernel data to RAM & zero out BSS */ KernelRelocate(pTOC); OEMInitDebugSerial(); // initialize serial port OEMWriteDebugString((PWSTR)NKSignon); /* Copy interlocked api code into the kpage */ DEBUGCHK(sizeof(KData) <= FIRST_INTERLOCK); DEBUGCHK((InterlockedEnd-InterlockedAPIs)+FIRST_INTERLOCK <= 0x400); memcpy((char *)&KData+FIRST_INTERLOCK, InterlockedAPIs, InterlockedEnd-InterlockedAPIs); /* setup processor version information */ CEProcessorType = cpuType >> 4 & 0xFFF; ProcessorRevision = cpuType & 0x0f; NKDbgPrintfW(L"ProcessorType=%4.4x Revision=%d\r\n", CEProcessorType, ProcessorRevision); NKDbgPrintfW(L"sp_abt=%8.8x sp_irq=%8.8x sp_undef=%8.8x\r\n", abSp, iSp, uSp); OEMInit(); // initialize firmware KernelFindMemory(); NKDbgPrintfW(L"Sp=%8.8x\r\n", &cpuType);#ifdef DEBUG OEMWriteDebugString(TEXT("ARMInit done.\r\n"));#endif}typedef struct ExcInfo { DWORD linkage; ULONG oldPc; UINT oldMode; char id; BYTE lowSpBits; ushort fsr; ULONG addr;} EXCINFO;typedef EXCINFO *PEXCINFO;ERRFALSE(sizeof(EXCINFO) <= sizeof(CALLSTACK));ERRFALSE(offsetof(EXCINFO,linkage) == offsetof(CALLSTACK,pcstkNext));ERRFALSE(offsetof(EXCINFO,oldPc) == offsetof(CALLSTACK,retAddr));ERRFALSE(offsetof(EXCINFO,oldMode) == offsetof(CALLSTACK,pprcLast));ERRFALSE(64 >= sizeof(CALLSTACK));PTHREAD HandleException(PTHREAD pth, int id, ulong addr, ushort info) { PEXCINFO pexi; DWORD stackaddr; if (id != ID_RESCHEDULE) {#if 0 NKDbgPrintfW(L"%a: Thread=%8.8lx Proc=%8.8lx AKY=%8.8lx\r\n", IdStrings[id+1], pth, pCurProc, pCurThread->aky); NKDbgPrintfW(L"PC=%8.8lx Lr=%8.8lx Sp=%8.8lx Psr=%4.4x\r\n", pth->ctx.Pc, pth->ctx.Lr, pth->ctx.Sp, pth->ctx.Psr); if (id == ID_DATA_ABORT) NKDbgPrintfW(L"FAR=%8.8lx FSR=%4.4x\r\n", addr, info);#endif KCALLPROFON(0); pexi = (struct ExcInfo *)((pth->ctx.Sp & ~63) - 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 pth; // restart instruction } SET_STACKFAULT(pth); id = ID_STACK_FAULT; // stack fault exception code addr = (DWORD)pexi; } if (pth->ctx.Pc != (ulong)CaptureContext+4) { pexi->id = id; pexi->lowSpBits = (uchar)pth->ctx.Sp & 63; pexi->oldPc = pth->ctx.Pc; pexi->oldMode = pth->ctx.Psr & 0xFF; pexi->addr = addr; pexi->fsr = info; pexi->linkage = (DWORD)pth->pcstkTop | 1; pth->pcstkTop = (PCALLSTACK)pexi; pth->ctx.Sp = (DWORD)pexi; if ((pexi->oldMode & 0x1F) == USER_MODE) pth->ctx.Psr = (pth->ctx.Psr & ~0xFF) | SYSTEM_MODE; else pth->ctx.Psr &= ~THUMB_STATE; pth->ctx.Pc = (ULONG)CaptureContext; KCALLPROFOFF(0); return pth; // 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 0; } if (PowerOffFlag) { DoPowerOff(); PowerOffFlag = 0; }reschedTop: if (ReschedFlag) { ReschedFlag = 0; NextThread(); } if (KCResched) { KCResched = 0; KCNextThread(); } if (KCResched) goto reschedTop; if (!RunList.pth) { INTERRUPTS_OFF(); if (!ReschedFlag && !KCResched) { OEMIdle(); INTERRUPTS_ON(); ReschedFlag = 1; goto reschedTop; } else { INTERRUPTS_ON(); goto reschedTop; } } SetCPUASID(RunList.pth); hCurThread = RunList.pth->hTh; pCurThread = RunList.pth; KPlpvTls = RunList.pth->tlsPtr; return RunList.pth;}// LoadPageTable - load entries into page tables from kernel structures//// LoadPageTable is called for prefetch and data aborts to copy page table// entries from the kernel virtual memory tables to the ARM h/w page tables.DWORD currsecond;DWORD secondpos[16];DWORD secondslot[16];DWORD used[16];LPDWORD SecondAddr(DWORD ind, DWORD ent) { return (LPDWORD)&ArmHigh->aPT[ind].PTEs[ent];}LPDWORD FirstAddr(DWORD ind) { return (LPDWORD)&ArmHigh->firstPT[ind];}int LoadPageTable(ulong addr) { PSECTION pscn; MEMBLOCK *pmb; ulong entry; unsigned ix1st, ix2nd; int loop; if ((addr < 0x80000000) && (pscn = SectionTable[addr>>VA_SECTION]) && (pmb = (*pscn)[(addr>>VA_BLOCK)&BLOCK_MASK]) && (pmb != RESERVED_BLOCK) && TestAccess(&pmb->alk, &CurAKey) && ((entry = pmb->aPages[(addr>>VA_PAGE)&PAGE_MASK]) & PG_VALID_MASK)) { ix1st = addr >> 20; // index into 1st level page table ix2nd = (addr >> VA_PAGE) & L2_MASK; // index into 2nd level page table // Remove previous entry from the page tables. if (*FirstAddr(ix1st)) { for (loop = 0; loop < 16; loop++) if (used[loop] && (secondpos[loop] == ix1st)) break; DEBUGCHK(loop != 16); *SecondAddr(loop,secondslot[loop]) = 0; secondslot[loop] = ix2nd; *SecondAddr(loop,ix2nd) = entry; } else { if (used[currsecond]) { *FirstAddr(secondpos[currsecond]) = 0; *SecondAddr(currsecond,secondslot[currsecond]) = 0; } else used[currsecond] = 1; secondpos[currsecond] = ix1st; secondslot[currsecond] = ix2nd; *SecondAddr(currsecond,ix2nd) = entry; *FirstAddr(ix1st) = PageTableDescriptor + currsecond*sizeof(PAGETBL); currsecond = (currsecond+1)&0xf; } return TRUE; // tell abort handler to retry } return FALSE;}void InvalidateSoftwareTLB(void) { int loop; if (!InSysCall()) { KCall((PKFN)InvalidateSoftwareTLB); return; } KCALLPROFON(63); for (loop = 0; loop < 16; loop++) { // Remove previous entry from the page tables. if (used[loop]) { *FirstAddr(secondpos[loop]) = 0; *SecondAddr(loop,secondslot[loop]) = 0; used[loop] = 0; } } KCALLPROFOFF(63);}// FlushTLB - clear TLBs and cached page table entries//// FlushTLB is called by the virtual memory system whenever the permissions on// any pages are changed or when any pages are freed.void FlushTLB(void) { FlushICache(); FlushDCache(); InvalidateSoftwareTLB(); TLBClear(); // clear h/w TLBs}void ExceptionDispatch(PCONTEXT pctx) { EXCEPTION_RECORD er; ULONG FaultAddr; ULONG addr; int id; BOOL bHandled; BOOL ThumbMode; PTHREAD pth; PEXCINFO pexi; uint fsr; pth = pCurThread; pexi = (PEXCINFO)pth->pcstkTop; DEBUGMSG(ZONE_SEH, (TEXT("ExceptionDispatch: pexi=%8.8lx Pc=%8.8lx\r\n"), pexi, pexi->oldPc)); pctx->Pc = pexi->oldPc; SetContextMode(pctx, pexi->oldMode); pctx->Sp = (ULONG)pctx + sizeof(CONTEXT); memset(&er, 0, sizeof(er)); er.ExceptionAddress = (PVOID)pctx->Pc;#if defined(THUMBSUPPORT) ThumbMode = (pctx->Psr & THUMB_STATE) != 0;#else ThumbMode = FALSE;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -