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

📄 mdppc.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 821

uchar 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 ID

int NextASID = 0;           // next available address space ID
extern void SetCASID(int);

#endif

// These are filled in by KernelStart
DWORD CEProcessorType   = 0;     // 821, 823, 401, or 403
WORD  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 0

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 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 == StackFrameHeaderLength



BOOL 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  nothing

void 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 + -