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

📄 fault.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        iretd
        cli
        hlt
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
PageFault()
{
    _asm {
        pushad
        mov     ebx, OFFSET KData
        mov     edi, cr2
        test    edi, edi
        jns     short pf05 

        // Address > 2GB, kmode only
        mov     esi, [esp+32]
        and     esi, 1
        jnz     short pf50              // prevelige vialoation, get out now
        mov     ecx, edi
        shr     ecx, VA_SECTION
        cmp     ecx, SECURE_SECTION
        jne     short pf50              // get out if not secure section
        
pf05:
        dec     [ebx].cNest             // count kernel reentrancy level
        mov     esi, esp                // (esi) = original stack pointer
        jnz     short pf10
        lea     esp, [ebx-4]            // switch to kernel stack (&KData-4)

//  Process a page fault for the "user" address space (0 to 0x7FFFFFFF)
//
//  (edi) = Faulting address
//  (ebx) = ptr to KData
//  (esi) = Original ESP

pf10:   cld                         // Need to do this since the page fault could have come from anywhere!
        cmp     dword ptr ([KData].dwInDebugger), 0 // see if debugger active
        jne     short pf20                          // if so, skip turning on of interrupts
        sti                                         // enable interrupts

pf20:   push    [esi+32]
        push    edi
        call    LoadPageTable
        cli
        test    eax, eax
        jz      short pf40          // page not found in the Virtual memory tree
        cmp     word ptr ([KData].bResched), 1
        je      short pf60          // must reschedule now
        inc     [ebx].cNest         // back out of kernel one level
        mov     esp, esi            // restore stack pointer
        popad
        add     esp, 4
        iretd

        
//  This one was not a good one!  Jump to common fault handler
//
//  (edi) = faulting address

pf40:   inc     [ebx].cNest         // back out of kernel one level
        mov     esp, esi            // restore stack pointer
pf50:   mov     ecx, edi            // (ecx) = fault effective address
        mov     esi, 0Eh
        jmp     CommonFault

// The reschedule flag was set and we are at the first nest level into the kernel
// so we must reschedule now.

pf60:   mov     edi, PtrCurThd      // (edi) = ptr to current THREAD
        jmp     Reschedule
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
GeneralFault()
{
    _asm {
        pushad
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        mov     esi, 13
        jmp     CommonFault
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
InvalidOpcode(void)
{
    __asm {
        push    eax
        pushad
        mov     esi, 6
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        jmp     CommonFault
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
ZeroDivide(void)
{
    __asm {
        push    eax
        pushad
        xor     esi, esi            // (esi) = 0 (divide by zero fault)
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        jmp     CommonFault
    }
}

const BYTE PosTable[256] = {
    0,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,
    6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
};




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void __declspec(naked) 
GetHighPos(
    DWORD foo
    ) 
{
    _asm {
        mov ecx, dword ptr [esp + 4]
        push ebx
        lea ebx, PosTable

        mov dl, 0xff
        xor eax, eax
        mov al, cl
        xlatb
        test al, al
        jne res

        shr ecx, 8
        add dl, 8
        mov al, cl
        xlatb
        test al, al
        jne res

        shr ecx, 8
        add dl, 8
        mov al, cl
        xlatb
        test al, al
        jne res

        shr ecx, 8
        add dl, 8
        mov al, cl
        xlatb
        test al, al
        jne res

        mov al, 9
res:
        add al, dl
        pop ebx
        ret
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
Int1Fault(void)
{
    __asm {
        push    eax                             // Save orig EAX as fake error code
        cmp     word ptr [esp + 6], 0FFFFh      // Is it an API call fault?
        je      skip_debug                      // Yes - handle page fault first
        mov     eax, [esp + 4]                  // (eax) = faulting EIP
        and     dword ptr [esp + 12], not 0100h  // Clear TF if set
        test    byte ptr [esp + 8], 3           // Are we trying to SS ring 0?
        jz      skip_debug                      // Yes - get out quick
        mov     eax, dword ptr [esp]            // Restore original EAX

        pushad
        mov     esi, 1
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        jmp     CommonFault

skip_debug:
        pop     eax
        iretd
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
Int2Fault(void)
{
    __asm {
        push    eax                 // Fake error code
        pushad
        mov     esi, 2
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        jmp     CommonFault
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Naked 
Int3Fault(void)
{
    __asm {
        dec     dword ptr [esp]     // Back up EIP
        push    eax                 // Fake error code
        pushad
        mov     esi, 3
        xor     ecx, ecx            // (ecx) = 0 (fault effective address)
        jmp     CommonFault
    }
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
InvalidateRange(
    PVOID pvAddr,
    ULONG ulSize
    )
{
    // just flush TLB
    KCall ((FARPROC) OEMCacheRangeFlush, 0, 0, CACHE_SYNC_FLUSH_TLB);
}


static DWORD addrPagesForPT;
#define IsSystemStarted()   (VAcs.hCrit)

static BOOL AllocPagesForPT (DWORD cbPages)
{
    if (IsSystemStarted ()) {
        return HoldPages (cbPages, FALSE);
    }

    // called from OEMInit - special handling
    addrPagesForPT = pTOC->ulRAMFree + MemForPT;
    MemForPT += cbPages * PAGE_SIZE;

    return TRUE;
}

static DWORD GetNextPageForPT (void)
{
    DWORD dwPhys;
    if (IsSystemStarted ()) {
        return GetHeldPage ();
    }

    // called from OEMInit - special handling
    dwPhys = LIN_TO_PHYS (addrPagesForPT);
    addrPagesForPT += PAGE_SIZE;
    
    return dwPhys;
}

#define PG_KERNEL_RW        (PG_WRITE_MASK | PG_VALID_MASK | PG_ACCESSED_MASK | PG_DIRTY_MASK)

#define FIRST_STATIC_PDE    (0xC40 >> 2)    // VA 0xC4000000, in 4M chunks
#define STATIC_PDE_LIMIT    (0xE00 >> 2)    // VA 0xE0000000, in 4M chunks

#define LARGE_PAGE_SUPPORT_DETECTED     (KData.dwCpuCap & CPUID_PSE)

const int dw4M = 4 * 1024 * 1024;

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
FindFreePDE(
    DWORD dwNumPDE              // Number of consecutive 4MB sections needed
    ) 
{
    DWORD pdeStart, pdeWalk;
    DWORD dwNumFound;

    for (pdeStart = FIRST_STATIC_PDE; (pdeStart + dwNumPDE - 1) < STATIC_PDE_LIMIT; pdeStart++) {

        dwNumFound = 0;

        if (!g_pPageDir->PTE[pdeStart]) {
            //
            // This is a potential starting point. See if enough consecutive
            // blocks are available.
            //
            dwNumFound = 1;
            
            for (pdeWalk = pdeStart + 1; pdeWalk < pdeStart + dwNumPDE; pdeWalk++) {
                if (g_pPageDir->PTE[pdeWalk]) {
                    break;
                } else {
                    dwNumFound++;
                }
            }

            if (dwNumFound == dwNumPDE) {
                return pdeStart;
            }
        }
    }

    // none found
    return 0;
}


DWORD FindExistingMapping (DWORD dw4MPhysBase, DWORD dwNumPDE)
{
    DWORD pdeStart, pdeWalk, dwPDE;
    DWORD dwNumFound;
    PPAGETABLE pPageTable;

    DEBUGCHK (!(dw4MPhysBase & (dw4M - 1)));    // must be 4M aligned

    // loop through the page directory until we find an unused entry or existing mapping
    for (pdeStart = FIRST_STATIC_PDE; g_pPageDir->PTE[pdeStart] && ((pdeStart + dwNumPDE - 1) < STATIC_PDE_LIMIT); pdeStart++) {

        // find the consective PDE entries that satisfy the request
        for (dwNumFound = 0, pdeWalk = pdeStart; dwNumFound < dwNumPDE; dwNumFound ++, pdeWalk ++) {
            
            if (LARGE_PAGE_SUPPORT_DETECTED) {
                // large page, physical base is in the entry itself
                dwPDE = g_pPageDir->PTE[pdeWalk] & PG_PHYS_ADDR_MASK;
            } else {
                // 4K page tables, first entry in the pagetable is the 4M aligned address
                pPageTable = (PPAGETABLE) Phys2Virt (g_pPageDir->PTE[pdeWalk] & PG_PHYS_ADDR_MASK);
                DEBUGCHK (pPageTable);
                dwPDE = pPageTable->PTE[0] & PG_PHYS_ADDR_MASK;
            }
            
            if (dwPDE != dw4MPhysBase + dwNumFound * dw4M) {
                break;
            }
        }
        if (dwNumFound == dwNumPDE) {
            return pdeStart;
        }
    }

    // not found
    return 0;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
NKCreateStaticMapping(
    DWORD dwPhysBase,

⌨️ 快捷键说明

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