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

📄 mdsh3.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        // the cause of the exception from the EXCINFO (CALLSTACK) structure.
        pctx->R15 += pexi->lowSp + sizeof(CALLSTACK);
        exc = pexi->exc;
        info = pexi->info;

        // Construct an EXCEPTION_RECORD from the EXCINFO structure
        er.ExceptionInformation[1] = info;
        // TLB Miss on load or store. Attempt to auto-commit the page. If that fails,
        // fall through into general exception processing.
        if (((exc == 0x3) || (exc == 2)) && AutoCommit(info)) {
            pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
            goto continueExecution;
        }
        switch (exc) {
        case 8:		// Address error (store)
            er.ExceptionInformation[0] = 1;
        case 7:		// Address error (load or instruction fetch)
            if (GetContextMode(pctx) != USER_MODE || !(info&0x80000000)) {
                er.ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
                break;
            }
            goto accessError;

        case 3:		// TLB Miss (store)
        case 4:		// TLB modification
        case 6:		// TLB protection violation (store)
            er.ExceptionInformation[0] = 1;
        case 2:		// TLB miss (load or instruction fetch)
        case 5:		// TLB protection violation (load)
            if (ProcessPageFault((exc==3)||(exc==4)||(exc==6), info)) {
                pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
                goto continueExecution;
            }
	accessError:        	
            er.ExceptionCode = STATUS_ACCESS_VIOLATION;
            er.NumberParameters = 2;
            break;
#ifdef SH4
        case 0x40:
        case 0x41:
            KCall((PKFN)SwitchFPUOwner,pctx);
            pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
            goto continueExecution;
        case 9: {			// floating point exception
            DWORD code;
            code = GetCauseFloatCode();
#if 0
            NKDbgPrintfW(L"ExceptionAddress 0x%x\r\n", er.ExceptionAddress);
            NKDbgPrintfW(L"code 0x%x, exc 0x%x\r\n",code,exc);
#endif
            if (code & 0x10)
                er.ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
            else if (code & 0x8)
                er.ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
            else if (code & 0x4)
                er.ExceptionCode = STATUS_FLOAT_OVERFLOW;
            else if (code & 0x2)
                er.ExceptionCode = STATUS_FLOAT_UNDERFLOW;
            else if (code & 0x1)
                er.ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
            else
            {
                //
                // Reach here 
                // --if code is 0x20 (FPU error)
                // --if code is 0x0 (processor thinks an ieee
                //   exception is possible)
                //
                // both cases require that fp operation be emulated
                // for correct ieee result.
                //
                // save the fpscr before FPUFlushContext will flush it
                // to zero.
                //
                // FPUFlushContext clears fpscr
                //
                FPUFlushContext();

                //
                // Copy current thread fregs and xfreg to user context
                //
                memcpy(&pctx->FRegs[0],&pCurThread->ctx.FRegs[0],sizeof(DWORD)*16);
                memcpy(&pctx->xFRegs[0],&pCurThread->ctx.xFRegs[0],sizeof(DWORD)*16);
                pctx->Fpscr = pCurThread->ctx.Fpscr;
                pctx->Fpul = pCurThread->ctx.Fpul;

                if (HandleHWFloatException(&er,pctx)) 
                {
                    //
                    // update current thread context with user context
                    //
                    memcpy(&pCurThread->ctx.FRegs[0],&pctx->FRegs[0],sizeof(DWORD)*16);
                    memcpy(&pCurThread->ctx.xFRegs[0],&pctx->xFRegs[0],sizeof(DWORD)*16);

                    pCurThread->ctx.Fpul = pctx->Fpul;
                    pCurThread->ctx.Fpscr = pctx->Fpscr;
                    pCurThread->ctx.Psr = pctx->Psr;

                    pctx->Fir+=2; // +2: return control to instruction successor
                    pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
                    goto continueExecution;
                }
            }
            //
            // Update user context fpscr and fpul
            //
            pCurThread->ctx.Fpscr = pctx->Fpscr;
            pCurThread->ctx.Fpul = pctx->Fpul;
            pCurThread->ctx.Psr = pctx->Psr;
            break;
        }
#endif
        case 11:		// Breakpoint
            pctx->Fir -= 2;		// backup to the trapa instruction
            er.ExceptionInformation[0] = info;
            er.ExceptionCode = STATUS_BREAKPOINT;
            break;

        case 12:	// Reserved instruction
        case 13:	// Illegal slot instruction
#ifdef SH3
            //
            // Assume DSP instruction.
            // If DSP processor and DSP not enabled, enable the DSP.
            //

            if ( SH3DSP && ((pctx->Psr & 0x1000) == 0) ){
                KCall((PKFN)SwitchDSPOwner,pctx);
                pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
                goto continueExecution;
            }
#endif
            er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
            break;
        case 15:	// Hardware breakpoint
            er.ExceptionInformation[0] = info;
            er.ExceptionCode = STATUS_USER_BREAK;
            break;

        case 0xFF:  // Stack overflow
            er.ExceptionCode = STATUS_STACK_OVERFLOW;
            er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
            break;
        }
    }

    if (exc != 11 && exc != 15) {
        NKDbgPrintfW(L"Exception %03x Thread=%8.8lx Proc=%8.8lx '%s'\r\n",
                     exc<<5, pth, hCurProc, 
                     pCurProc->lpszProcName ? pCurProc->lpszProcName : L"");
        NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx RA=%8.8lx TEA=%8.8lx\r\n",
                     pCurThread->aky, pctx->Fir, pctx->PR, info);
        if (UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) {
            NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n");
        }
    }

    // Invoke the kernel debugger to attempt to debug the exception before
    // letting the program resolve the condition via SEH.
    pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
    if (!UserDbgTrap(&er,pctx,FALSE) && ((UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) || !KDTrap(&er, pctx, FALSE))) {
        bHandled = NKDispatchException(pth, &er, pctx);
        if (!bHandled) {
            if (!UserDbgTrap(&er, pctx, TRUE) && !KDTrap(&er, pctx, TRUE)) {
                if (er.ExceptionCode == STATUS_BREAKPOINT) {
                    RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx Ignored.\r\n"), pctx->Fir));
                    DumpFrame(pth, pctx, exc<<5, info);
                    pctx->Fir += 2;		// skip over the trapa instruction
                } else {
                    // Terminate the process.
                    RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"),
                                  er.ExceptionCode));
                    DumpFrame(pth, pctx, exc<<5, info);
                    if (InSysCall()) {
                        OutputDebugStringW(L"Halting system\r\n");
                        for (;;)
                            ;
                    } else {
                        if (!GET_DEAD(pth)) {
                            SET_DEAD(pth);
                            pctx->Fir = (ULONG)pExitThread;
                            pctx->R0 = 0;
                            RETAILMSG(1, (TEXT("Terminating thread %8.8lx\r\n"), pth));
                        } else {
                            RETAILMSG(1, (TEXT("Can't terminate thread %8.8lx, sleeping forever\r\n"), pth));
                            SurrenderCritSecs();
                            Sleep(INFINITE);
                            DEBUGCHK(0);    // should never get here
                        }
                    }
                }
            }
        }
    }
    if (exc == 2 || exc == 3)
        GuardCommit(info);
 continueExecution:

    // If returning from handling a stack overflow, reset the thread's stack overflow
    // flag. It would be good to free the tail of the stack at this time
    // so that the thread will stack fault again if the stack gets too big. But we
    // are currently using that stack page.
    if (exc == 0xFF)
    	CLEAR_STACKFAULT(pth);
    if (GET_DYING(pth) && !GET_DEAD(pth) && (pCurProc == pth->pOwnerProc)) {
        SET_DEAD(pth);
        CLEAR_USERBLOCK(pth);
        CLEAR_DEBUGWAIT(pth);
        pctx->Fir = (ULONG)pExitThread;
        pctx->R0 = 0;
    }   
    return;
}

void DumpFrame(PTHREAD pth, PCONTEXT pctx, DWORD dwExc, DWORD info) {
    DWORD oldCCR;
    oldCCR = CCR;
    CCR = 0;		// disable the cache to avoid changing its state
    NKDbgPrintfW(L"Exception %03x Thread=%8.8lx AKY=%8.8lx PC=%8.8lx\r\n",
                 dwExc, pth, pCurThread->aky, pctx->Fir);
    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 R13=%8.8lx R14=%8.8lx R15=%8.8lx\r\n",
                 pctx->R12, pctx->R13, pctx->R14, pctx->R15);
    NKDbgPrintfW(L" PR=%8.8lx  SR=%8.8lx\r\n TEA/TRPA=%8.8x",
                 pctx->PR, pctx->Psr, info);
    NKDbgPrintfW(L"PTEL=%8.8lx PTEH=%8.8lx MMUCR=%8.8lx TTB=%8.8lx\r\n",
                 MMUPTEL, MMUPTEH, MMUCR, MMUTTB);
    NKDbgPrintfW(L"CCR=%8.8lx\r\n", oldCCR);
    CCR = oldCCR;	// restore original cache state
}

// normal thread stack: from top, TLS then args then free

void MDCreateThread(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, DWORD dwVMBase, BOOL kmode, ulong param) {
    if (!((ulong)lpStack>>VA_SECTION))
        lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase);
    pTh->dwStackBase = (DWORD)lpStack;
    // Clear all registers: Esp. fpu state for SH-4
    memset(&pTh->ctx, 0, sizeof(pTh->ctx));
    // Leave room for arguments and TLS on the stack
    pTh->ctx.R15 = (ulong)lpStack + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 4*4;
    pTh->dwStackBound = pTh->ctx.R15 & ~(PAGE_SIZE-1);
    pTh->tlsPtr = (LPDWORD)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4));
    pTh->ctx.R4 = (ulong)lpStart;
    pTh->ctx.R5 = param;
    pTh->ctx.PR = 0;
#ifdef SH4
    pTh->ctx.Psr = 0x8000; // disable floating point
    pTh->ctx.Fpscr = 0x40000;  // handle no exceptions
#else
    pTh->ctx.Psr = 0;
#endif
    pTh->ctx.Fir = (ULONG)lpBase;
    pTh->ctx.ContextFlags = CONTEXT_FULL;
    SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE));
}

// main thread stack: from top, TLS then buf then buf2 then buf2 (ascii) then args then free

LPCWSTR MDCreateMainThread1(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, DWORD dwVMBase,
                            LPBYTE buf, ulong buflen, LPBYTE buf2, ulong buflen2) {
    LPCWSTR pcmdline;
    if (!((ulong)lpStack>>VA_SECTION))
        lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase);
    pTh->dwStackBase = (DWORD)lpStack;
    pcmdline = (LPCWSTR)((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3));
    memcpy((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3),buf,buflen);
    pTh->pOwnerProc->lpszProcName = (LPWSTR)((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3)-((buflen2+3)&~3));
    memcpy(pTh->pOwnerProc->lpszProcName,buf2,buflen2);
    KPlpvTls = pTh->tlsPtr = (LPDWORD)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4));
    return pcmdline;
}

void MDCreateMainThread2(PTHREAD pTh, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, BOOL kmode,
                         ulong p1, ulong p2, ulong buflen, ulong buflen2, ulong p4) {

    // Clear all registers: Esp. fpu state for SH-4
    memset(&pTh->ctx, 0, sizeof(pTh->ctx));
    // Leave room for arguments on the stack
    pTh->ctx.R15 = (pTh->dwStackBase + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 8*4 - ((buflen+3)&~3) - ((buflen2+3)&~3)) & ~7;
    pTh->dwStackBound = pTh->ctx.R15 & ~(PAGE_SIZE-1);
    pTh->ctx.R4 = (ulong)lpStart;
    pTh->ctx.R5 = p1;
    pTh->ctx.R6 = p2;
    pTh->ctx.R7 = pTh->dwStackBase+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3);
    ((LPDWORD)pTh->ctx.R15)[4] = p4;
    pTh->ctx.PR = 0;
#ifdef SH4
    pTh->ctx.Psr = 0x8000; // disable floating point
    pTh->ctx.Fpscr = 0x40000;  // handle no exceptions
#else
    pTh->ctx.Psr = 0;
#endif
    pTh->ctx.Fir = (ULONG)lpBase;
    SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE));
    pTh->ctx.ContextFlags = CONTEXT_FULL;
}

#ifdef XTIME
extern DWORD ExceptionTime;// tick at exception entry

void SyscallTime(int iSyscall) {
    DWORD	dwTime;
    dwTime = ExceptionTime - TMUADDR->tcnt1;
    xt.dwTime[iSyscall]+= dwTime;
    if ((++xt.dwCount[iSyscall]) == 1)
        xt.dwMax[iSyscall]=xt.dwMin[iSyscall]= dwTime;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -