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

📄 fault.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        mov     [edx].tlsPtr, ecx       // update thread's tlsPtr
        mov     [KData].lpvTls, ecx     // set KData's TLS pointer

        // update fs
        mov     edx, offset g_aGlobalDescriptorTable+KGDT_PCR
        sub     ecx, FS_LIMIT+1         // (ecx) = ptr to NK_PCR base
        mov     word ptr [edx+2], cx    // set low word of FS base
        shr     ecx, 16
        mov     byte ptr [edx+4], cl    // set third byte of FS base
        mov     byte ptr [edx+7], ch    // set high byte of FS base
        push    fs
        pop     fs                      // cause fs to reload

        jmp     short CBRtnCommon

        
/////////////////////////////////////////////////////////////////////////////////////////
// callbacks
//      CALLER MUST BE IN KMODE
DoPerformCallback:

        sti                             // interrupt okay now
        // setup OBJCALLSTRUCT
        mov     edx, fs:[0]             // replace EFLAGS with linkage
        mov     [esp], edx              // replace EFLAGS with linkage
        sub     esp, 12                 // room for mode, prevSP, and method
        push    esp                     // arg1 == ptr to OBJCALLSTRUCT
        lea     ecx, [esp+20]           // (ecx) = original SP
        mov     [esp+8], ecx            // pobs->prevSP = original SP
        
        call    PerformCallBackExt      // argument to PerformCallBackExt is (excpLink, ra, pcbi, pmode)

        // eax == function to call

        mov     ecx, [esp+12]           // (ecx) = mode
        add     esp, 20                 // remove args we pushed
        cmp     dword ptr [esp-12], 0   // use same stack?
        je      short CBCommon

        // need to change stack
        mov     edx, PtrCurThd          // (edx) == pCurThread
        mov     ecx, [edx].tlsNonSecure // (ecx) == TLSPTR of the non-secure stack
        mov     [edx].tlsPtr, ecx       // update thread's tlsPtr
        mov     [KData].lpvTls, ecx     // set KData's TLS pointer

        // update fs
        //  (ecx) == pCurThread->tlsPtr
        mov     edx, offset g_aGlobalDescriptorTable+KGDT_PCR
        sub     ecx, FS_LIMIT+1         // (ecx) = ptr to NK_PCR base
        mov     word ptr [edx+2], cx    // set low word of FS base
        shr     ecx, 16
        mov     byte ptr [edx+4], cl    // set third byte of FS base
        mov     byte ptr [edx+7], ch    // set high byte of FS base
        // make sure fs got updated
        push    fs
        pop     fs                      // cause fs to reload
        

        // save current ESP in callstack structure
        mov     ecx, [esp-12]           // (ecx) == new SP
        xchg    ecx, esp                // switch stack


                push    dword ptr [ecx+32]
        push    dword ptr [ecx+28]
        push    dword ptr [ecx+24]
        push    dword ptr [ecx+20]
        push    dword ptr [ecx+16]
        push    dword ptr [ecx+12]
        push    dword ptr [ecx+8]
        push    dword ptr [ecx+4]
        sub     esp, 4                  // room for return address

        mov     ecx, [ecx-8]            // reload mode

CBCommon:
        // (eax) == function to call
        // (ecx) == mode
        
        // mark PSL boundary
        mov     dword ptr fs:[0], -2

        // save registers for exception handling
        mov     edx, PtrCurThd          // (eax) = ptr to THREAD struct
        mov     edx, [edx].pcstkTop     // (eax) = ptr to CALLSTACK struct
        mov     [edx].ExEsp, esp        // .\     v
        mov     [edx].ExEbp, ebp        // ..\    v
        mov     [edx].ExEbx, ebx        // ...> save registers for possible exception recovery
        mov     [edx].ExEsi, esi        // ../
        mov     [edx].ExEdi, edi        // ./

        // (ecx) == mode
        cmp     ecx, KERNEL_MODE
        je      short CBInKMode

        // setup return address to trap back        
        mov     dword ptr [esp], SYSCALL_RETURN

        // setup far-return stack
        mov     edx, esp
        push    KGDT_R3_DATA | 3        // SS of ring 3
        push    edx                     // target ESP
        push    KGDT_R3_CODE | 3        // CS of ring 3
        push    eax                     // function to call
        // return to user code
        retf

CBInKMode:
        pop     edx                 // get rid of return address
        call    eax                 // call the function directly

CBRtnCommon:        
        // (eax) == return value for callback
        push    eax                 // save return value
        sub     esp, 4              // room for linkage
        push    esp                 // arg0 == pLinkage
        call    CallbackReturn

        // (eax) == return address
        mov     ecx, eax            // (ecx) == return address
        
        mov     eax, [esp+4]
        mov     fs:[0], eax         // restore exception linkage
        mov     eax, [esp+8]        // restore return value
        add     esp, 12             // remove the stuffs we pushed onto 
        push    ecx                 // push return address onto stack
        
        ret                         // return to caller of PerformCallback in KMODE
        
    }
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int __declspec(naked) 
KCall(
    PKFN pfn, 
    ...
    )
{
    __asm {
        push    ebp
        mov     ebp, esp
        push    ebx
        mov     eax, 12[ebp]    // (eax) = arg0
        mov     edx, 16[ebp]    // (edx) = arg1
        mov     ecx, 20[ebp]    // (ecx) = arg2
        mov     ebx, 8[ebp]     // (ebx) = function address
        cmp     [KData].cNest, 1
        jne     short kcl50     // Already in non-preemtible state
        int KCALL_INT           // trap to ring0 for non-preemtible stuff
        pop     ebx
        pop     ebp             // restore original EBP
        ret

kcl50:  push    ecx             // push Arg2
        push    edx             // push Arg1
        push    eax             // push Arg0
        call    ebx             // invoke function
        add     esp, 3*4        // remove args from stack
        pop     ebx
        pop     ebp             // restore original EBP
        ret
    }
}
#pragma warning(default:4035 4733)         // Turn warning back on




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
Int22KCallHandler(void)
{
    __asm {
        push    eax                 // fake Error Code
        pushad
        mov     esi, esp            // save ptr to register save area
        mov     esp, offset KData-4 // switch to kernel stack
        dec     [KData].cNest
        sti
        push    ecx                 // push Arg2
        push    edx                 // push Arg1
        push    eax                 // push Arg0
        call    ebx                 // invoke non-preemtible function
        mov     [esi+7*4], eax      // save return value into PUSHAD frame
        mov     ecx, OFFSET KData
        xor     edi, edi            // force Reschedule to reload the thread's state
        cli

        cmp     word ptr ([ecx].bResched), 1
        jne     short NotReschedule
        jmp     Reschedule
NotReschedule:
        cmp     dword ptr ([ecx].dwKCRes), 1
        jne     short NotResched2
        jmp     Reschedule
NotResched2:
        mov     esp, esi
        inc     [ecx].cNest
        popad
        add     esp, 4              // throw away the error code
        iretd
    }
}


//------------------------------------------------------------------------------
// rdmsr - C wrapper for the assembly call. Must be in RING 0 to make this call!
// Assumes that the rdmsr instruction is supported on this CPU; you must check
// using the CPUID instruction before calling this function.
//------------------------------------------------------------------------------
static void rdmsr(
    DWORD dwAddr,       // Address of MSR being read
    DWORD *lpdwValHigh, // Receives upper 32 bits of value, can be NULL
    DWORD *lpdwValLow   // Receives lower 32 bits of value, can be NULL
    )
{
    DWORD dwValHigh, dwValLow;

    _asm {
        ;// RDMSR: address read from ECX, data returned in EDX:EAX
        mov     ecx, dwAddr
        rdmsr
        mov     dwValHigh, edx
        mov     dwValLow, eax
    }

    if (lpdwValHigh) {
        *lpdwValHigh = dwValHigh;
    }
    if (lpdwValLow) {
        *lpdwValLow = dwValLow;
    }
}


//------------------------------------------------------------------------------
// NKrdmsr - C wrapper for the rdmsr assembly call.  Handles getting into
// ring 0 but does not check whether MSRs are supported or whether the
// particular MSR address being read from is supported.
//------------------------------------------------------------------------------
BOOL
NKrdmsr(
    DWORD dwAddr,       // Address of MSR being read
    DWORD *lpdwValHigh, // Receives upper 32 bits of value, can be NULL
    DWORD *lpdwValLow   // Receives lower 32 bits of value, can be NULL
    )
{
    if (InSysCall()) {
        rdmsr(dwAddr, lpdwValHigh, lpdwValLow);
    } else {
        KCall((PKFN)rdmsr, dwAddr, lpdwValHigh, lpdwValLow);
    }

    return TRUE;
}


//------------------------------------------------------------------------------
// wrmsr - C wrapper for the assembly call. Must be in RING 0 to make this call!
// Assumes that the wrmsr instruction is supported on this CPU; you must check
// using the CPUID instruction before calling this function.
//------------------------------------------------------------------------------
static void wrmsr(
    DWORD dwAddr,       // Address of MSR being written
    DWORD dwValHigh,    // Upper 32 bits of value being written
    DWORD dwValLow      // Lower 32 bits of value being written
    )
{
    _asm {
        ;// WRMSR: address read from ECX, data read from EDX:EAX
        mov     ecx, dwAddr
        mov     edx, dwValHigh
        mov     eax, dwValLow
        wrmsr
    }
}


//------------------------------------------------------------------------------
// NKwrmsr - C wrapper for the wrmsr assembly call.  Handles getting into
// ring 0 but does not check whether MSRs are supported or whether the
// particular MSR address being written to is supported.
//------------------------------------------------------------------------------
BOOL
NKwrmsr(
    DWORD dwAddr,       // Address of MSR being written
    DWORD dwValHigh,    // Upper 32 bits of value being written
    DWORD dwValLow      // Lower 32 bits of value being written
    )
{
    if (InSysCall()) {
        wrmsr(dwAddr, dwValHigh, dwValLow);
    } else {
        KCall((PKFN)wrmsr, dwAddr, dwValHigh, dwValLow);
    }

    return TRUE;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
InitializePageTables(void)
{

    InitIDTEntry(SYSCALL_INT, KGDT_R1_CODE | 1, Int20SyscallHandler(), RING3_INT_GATE);
    InitIDTEntry(KCALL_INT, KGDT_R0_CODE, Int22KCallHandler, RING1_INT_GATE);

    NKDbgPrintfW (L"g_pPageDir = %8.8lx\n", g_pPageDir);
}

///////////////////////////// FLOATING POINT UNIT CODE /////////////////////////////////



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
InitializeEmx87(void) 
{
    // Fast FP save/restore instructions are not available when emulating FP
    KCALLPROFON(70);
    ProcessorFeatures &= ~CPUID_FXSR;
    _asm {
        mov eax, cr0
        or  eax, MP_MASK or EM_MASK
        and eax, NOT (TS_MASK or NE_MASK)
        mov cr0, eax
    }
    KCALLPROFOFF(70);
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
InitNPXHPHandler(
    LPVOID NPXNPHandler
    ) 
{
    KCALLPROFON(71);
    if(pTOC->ulKernelFlags & KFLAG_NOTALLKMODE)
    {
        InitIDTEntry(0x07, KGDT_R3_CODE, NPXNPHandler, RING3_TRAP_GATE);
    }
    else
    {
        InitIDTEntry(0x07, KGDT_R1_CODE, NPXNPHandler, RING1_TRAP_GATE);
    }
    KCALLPROFOFF(71);
}

BOOL __declspec(naked) NKIsSysIntrValid (DWORD idInt)
{
    _asm {
        mov     eax, [esp+4]            // (eax) = idInt
        sub     eax, SYSINTR_DEVICES    // (eax) = idInt - SYSINTR_DEVICES
        jb      NKIRetFalse             // return FALSE if < SYSINTR_DEVICES

        cmp     eax, SYSINTR_MAX_DEVICES // (eax) >= SYSINTR_MAX_DEVICES?
        jae     NKIRetFalse             // return FALSE if >= SYSINTR_MAX_DEVICES

        //; idInt is valid, return IntrEvents[idInt-SYSINTR_DEVICES]
        mov     eax, dword ptr KData.alpeIntrEvents[eax*4]

        ret

    NKIRetFalse:
        xor     eax, eax                // return FALSE
        ret
    }
}

//------------------------------------------------------------------------------
//----------------------------------------------------------------

⌨️ 快捷键说明

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