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

📄 mdarm.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -