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

📄 mdsched.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#include "kernel.h"
#define HEADER_FILE
#include "kxmips.h"

#ifdef MIPS_HAS_FPU
void SaveFloatContext(PTHREAD);
void RestoreFloatContext(PTHREAD);
DWORD GetAndClearFloatCode(void);
BOOL HandleHWFloatException(EXCEPTION_RECORD *er, PCONTEXT pctx, CAUSE cause);
void FPUFlushContext(void);
#endif

const wchar_t NKSignon[] = TEXT("Windows CE Kernel for MIPS Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");

#ifdef _MIPS64
    const wchar_t NKCpuType [] = TEXT("MIPS64");
    #ifdef MIPS_HAS_FPU
        DWORD CEInstructionSet = PROCESSOR_MIPS_MIPSIVFP_INSTRUCTION;
    #else
        DWORD CEInstructionSet = PROCESSOR_MIPS_MIPSIV_INSTRUCTION;
    #endif
#else
    const wchar_t NKCpuType [] = TEXT("MIPS32");
    #ifdef MIPS_HAS_FPU
        DWORD CEInstructionSet = PROCESSOR_MIPS_MIPSIIFP_INSTRUCTION;
    #else
        DWORD CEInstructionSet = PROCESSOR_MIPS_MIPSII_INSTRUCTION;
    #endif
#endif

// Define breakpoint instruction values.

#define MIPS32_BREAK(_t) ((SPEC_OP << 26) | ((_t) << 16) | BREAK_OP)
#define MIPS16_BREAK(_t) ((RR_OP16 << 11) | ((_t) << 5) | BREAK_OP16)


DWORD dwStaticMapBase;
DWORD dwStaticMapLength;
DWORD dwNKCoProcEnableBits = 0x20000000;

extern void (*lpNKHaltSystem)(void);
extern void FakeNKHaltSystem (void);

MEMBLOCK *MDAllocMemBlock (DWORD dwBase, DWORD ixBlock)
{
    MEMBLOCK *pmb = (MEMBLOCK *) AllocMem (HEAP_MEMBLOCK);
    if (pmb)
        memset (pmb, 0, sizeof (MEMBLOCK));
    return pmb;
}

void MDFreeMemBlock (MEMBLOCK *pmb)
{
    DEBUGCHK (pmb);
    FreeMem (pmb, HEAP_MEMBLOCK);
}

typedef struct _MAPENTRY {
    DWORD   dwVAStart;
    DWORD   dwTLBEntry;
    DWORD   dwVAEnd;
} MAPENTRY, *PMAPENTRY;

// TLB miss handler is making the following assumption
ERRFALSE(sizeof(MAPENTRY) == 12);   
ERRFALSE(offsetof(MAPENTRY,dwVAStart)  == 0);
ERRFALSE(offsetof(MAPENTRY,dwTLBEntry) == 4);
ERRFALSE(offsetof(MAPENTRY,dwVAEnd)    == 8);

#define  MAX_STATIC_MAPPING     63
MAPENTRY MapArray[MAX_STATIC_MAPPING+1];


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD CombineEntry (int idx, DWORD dwPhysBase, DWORD dwPhysEnd)
{
    if (idx) {
        PMAPENTRY pMap = &MapArray[idx-1];
        DWORD dwEntry = PFNfromEntry (pMap->dwTLBEntry);

        if ((dwEntry + ((pMap->dwVAEnd - pMap->dwVAStart) >> PFN_SHIFT)) == dwPhysBase) {
            // okay to combine, just increment dwVAEnd by requested size
            pMap->dwVAEnd += (dwPhysEnd - dwPhysBase) << PFN_SHIFT;
            return dwEntry;
        }
    }

    return 0;
}

#define SHIFTED_8K_MASK             0x1f            // mask for shifted physical address to make 8K alignment

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
NKCreateStaticMapping(
    DWORD dwShiftedPhysAddr,// physical address >> 8
    DWORD dwSize            // size of region required
    ) 
{
    DWORD       dwPhysEnd, ulPfn, dwPhysBase;
    PMAPENTRY   pMap;
    int         i;

    // calculate 8k-aligned end of physical address
    dwPhysEnd = (dwShiftedPhysAddr + ((dwSize + 0xff) >> 8) + SHIFTED_8K_MASK) & ~SHIFTED_8K_MASK;

    // return CPU defined mapping if < 0x20000000
    if (dwPhysEnd < (0x20000000 >> 8)) {
        //
        // Physical address requested falls in the range mapped by the CPU
        // itself (KSEG1)
        //
        return Phys2VirtUC(PA2PFN(dwShiftedPhysAddr << 8));
    }

    // calculate 8k-aligned base/end of the TLB entry
    dwPhysBase = PFNfrom256 (dwShiftedPhysAddr & ~SHIFTED_8K_MASK);
    dwPhysEnd  = PFNfrom256 (dwPhysEnd);

    // search existing mapping
    for (i = 0, pMap = MapArray; (ulPfn = PFNfromEntry (pMap->dwTLBEntry)) && (i < MAX_STATIC_MAPPING); i ++, pMap ++) {
        DWORD dwEntrySize = (pMap->dwVAEnd - pMap->dwVAStart) >> PFN_SHIFT;   // size >> PFN_SHIFT

        if ((ulPfn <= dwPhysBase)
            && ((ulPfn + dwEntrySize) >= dwPhysEnd)) {
            // existing mapping found, just return the right address
            break;
        }
    }

    // too many mappings?
    if (MAX_STATIC_MAPPING == i) {
        KSetLastError (pCurThread, ERROR_OUTOFMEMORY);
        return NULL;
    }

    if (!ulPfn) {
        // no existing mapping, create one
        DWORD dwVAStart = i? MapArray[i-1].dwVAEnd : NK_IO_BASE;
        DWORD dwVAEnd   = dwVAStart + ((dwPhysEnd - dwPhysBase) << PFN_SHIFT);

        // do have still have VA avaliable?
        if (dwVAEnd > NK_IO_END) {
            KSetLastError (pCurThread, ERROR_OUTOFMEMORY);
            return NULL;
        }

        // try to combine with the last entry
        if (!(ulPfn = CombineEntry (i, dwPhysBase, dwPhysEnd))) {
            // can't combine, create new entry
            MapArray[i+1]    = MapArray[i]; // shift (0xffffffff, 0, 0xffffffff) down
            pMap->dwVAEnd    = dwVAEnd;
            pMap->dwTLBEntry = (ulPfn = dwPhysBase) | PG_DIRTY_MASK | PG_VALID_MASK | PG_NOCACHE;
            pMap->dwVAStart  = dwVAStart;
        }
    }

    return (LPVOID) (((PFNfrom256 (dwShiftedPhysAddr) - ulPfn) << PFN_SHIFT) + pMap->dwVAStart);

}




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
SC_CreateStaticMapping(
    DWORD dwPhysBase,
    DWORD dwSize
    ) 
{
    TRUSTED_API (L"NKCreateStaticMapping", NULL);

    return NKCreateStaticMapping(dwPhysBase, dwSize);
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID MDValidateKVA (DWORD dwAddr)
{
    return ((dwAddr < 0xC0000000)                                  // between 0x80000000 - 0xc0000000
            || ((dwAddr >= 0xFFFFC000) && (dwAddr < 0xFFFFE000)))  // in KPage/KData
        ? (LPVOID) dwAddr : 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,
    PICONTEXT pctx,
    CAUSE cause,
    ULONG badVAddr,
    int level
    ) 
{
    ulong addr;
    PDWORD pdw;
    NKDbgPrintfW(L"Exception %03x Thread=%8.8lx AKY=%8.8lx PC=%8.8lx BVA=%8.8lx\r\n",
            cause.XCODE, pth, pCurThread->aky, pctx->Fir, badVAddr);
#ifdef  _MIPS64
    NKDbgPrintfW(L"SR=%8.8lx AT=%8.8lx%8.8lx V0=%8.8lx%8.8lx V1=%8.8lx%8.8lx\r\n",
            (long) pctx->Psr,
            (long)( pctx->IntAt >> 32 ), (long)( pctx->IntAt ),
            (long)( pctx->IntV0 >> 32 ), (long)( pctx->IntV0 ),
            (long)( pctx->IntV1 >> 32 ), (long)( pctx->IntV1 )
            );
    NKDbgPrintfW(L"A0=%8.8lx%8.8lx A1=%8.8lx%8.8lx A2=%8.8lx%8.8lx A3=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntA0 >> 32 ), (long)( pctx->IntA0 ),
            (long)( pctx->IntA1 >> 32 ), (long)( pctx->IntA1 ),
            (long)( pctx->IntA2 >> 32 ), (long)( pctx->IntA2 ),
            (long)( pctx->IntA3 >> 32 ), (long)( pctx->IntA3 )
            );
    NKDbgPrintfW(L"T0=%8.8lx%8.8lx T1=%8.8lx%8.8lx T2=%8.8lx%8.8lx T3=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntT0 >> 32 ), (long)( pctx->IntT0 ),
            (long)( pctx->IntT1 >> 32 ), (long)( pctx->IntT1 ),
            (long)( pctx->IntT2 >> 32 ), (long)( pctx->IntT2 ),
            (long)( pctx->IntT3 >> 32 ), (long)( pctx->IntT3 )
            );
    NKDbgPrintfW(L"T4=%8.8lx%8.8lx T5=%8.8lx%8.8lx T6=%8.8lx%8.8lx T7=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntT4 >> 32 ), (long)( pctx->IntT4 ),
            (long)( pctx->IntT5 >> 32 ), (long)( pctx->IntT5 ),
            (long)( pctx->IntT6 >> 32 ), (long)( pctx->IntT6 ),
            (long)( pctx->IntT7 >> 32 ), (long)( pctx->IntT7 )
            );
    NKDbgPrintfW(L"S0=%8.8lx%8.8lx S1=%8.8lx%8.8lx S2=%8.8lx%8.8lx S3=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntS0 >> 32 ), (long)( pctx->IntS0 ),
            (long)( pctx->IntS1 >> 32 ), (long)( pctx->IntS1 ),
            (long)( pctx->IntS2 >> 32 ), (long)( pctx->IntS2 ),
            (long)( pctx->IntS3 >> 32 ), (long)( pctx->IntS3 )
            );
    NKDbgPrintfW(L"S4=%8.8lx%8.8lx S5=%8.8lx%8.8lx S6=%8.8lx%8.8lx S7=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntS4 >> 32 ), (long)( pctx->IntS4 ),
            (long)( pctx->IntS5 >> 32 ), (long)( pctx->IntS5 ),
            (long)( pctx->IntS6 >> 32 ), (long)( pctx->IntS6 ),
            (long)( pctx->IntS7 >> 32 ), (long)( pctx->IntS7 )
            );
    NKDbgPrintfW(L"T8=%8.8lx%8.8lx T9=%8.8lx%8.8lx LO=%8.8lx%8.8lx HI=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntT8 >> 32 ), (long)( pctx->IntT8 ),
            (long)( pctx->IntT9 >> 32 ), (long)( pctx->IntT9 ),
            (long)( pctx->IntLo >> 32 ), (long)( pctx->IntLo ),
            (long)( pctx->IntHi >> 32 ), (long)( pctx->IntHi )
            );
    NKDbgPrintfW(L"GP=%8.8lx%8.8lx SP=%8.8lx%8.8lx S8=%8.8lx%8.8lx RA=%8.8lx%8.8lx\r\n",
            (long)( pctx->IntGp >> 32 ), (long)( pctx->IntGp ),
            (long)( pctx->IntSp >> 32 ), (long)( pctx->IntSp ),
            (long)( pctx->IntS8 >> 32 ), (long)( pctx->IntS8 ),
            (long)( pctx->IntRa >> 32 ), (long)( pctx->IntRa )
            );
#else   //  _MIPS64
    NKDbgPrintfW(L"SR=%8.8lx AT=%8.8lx V0=%8.8lx V1=%8.8lx\r\n",
            pctx->Psr, pctx->IntAt, pctx->IntV0, pctx->IntV1);
    NKDbgPrintfW(L"A0=%8.8lx A1=%8.8lx A2=%8.8lx A3=%8.8lx\r\n",
            pctx->IntA0, pctx->IntA1, pctx->IntA2, pctx->IntA3);
    NKDbgPrintfW(L"T0=%8.8lx T1=%8.8lx T2=%8.8lx T3=%8.8lx\r\n",
            pctx->IntT0, pctx->IntT1, pctx->IntT2, pctx->IntT3);
    NKDbgPrintfW(L"T4=%8.8lx T5=%8.8lx T6=%8.8lx T7=%8.8lx\r\n",
            pctx->IntT4, pctx->IntT5, pctx->IntT6, pctx->IntT7);
    NKDbgPrintfW(L"S0=%8.8lx S1=%8.8lx S2=%8.8lx S3=%8.8lx\r\n",
            pctx->IntS0, pctx->IntS1, pctx->IntS2, pctx->IntS3);
    NKDbgPrintfW(L"S4=%8.8lx S5=%8.8lx S6=%8.8lx S7=%8.8lx\r\n",
            pctx->IntS4, pctx->IntS5, pctx->IntS6, pctx->IntS7);
    NKDbgPrintfW(L"T8=%8.8lx T9=%8.8lx LO=%8.8lx HI=%8.8lx\r\n",
            pctx->IntT8, pctx->IntT9, pctx->IntLo, pctx->IntHi);
    NKDbgPrintfW(L"GP=%8.8lx SP=%8.8lx S8=%8.8lx RA=%8.8lx\r\n",
            pctx->IntGp, pctx->IntSp, pctx->IntS8, pctx->IntRa);
#endif  //  _MIPS64
    if (level > 1) {
        addr = (pctx->Fir & -4) - 8*4;
        pdw = VerifyAccess((PVOID)addr, VERIFY_KERNEL_OK, CurAKey);
        if (pdw)
            DumpDwords((PDWORD)addr, 12);
    }
}

typedef struct _tlbentry {
    ulong   lo0;
    ulong   lo1;
    ulong   hi;
    ulong   mask;
} TLBENTRY;
typedef TLBENTRY *PTLBENTRY;

// Value of PRId register (least significant 16 bits)
WORD ProcessorRevision;



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
HookInterrupt(
    int hwInterruptNumber,
    FARPROC pfnHandler
    ) 
{
    if ((0 > hwInterruptNumber) || (5 < hwInterruptNumber))
        return FALSE;
    ISRTable[hwInterruptNumber] = (DWORD)pfnHandler;
    KData.basePSR |= (0x0400 << hwInterruptNumber);
    return TRUE;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
UnhookInterrupt(
    int hwInterruptNumber,
    FARPROC pfnHandler
    ) 
{
    extern int DisabledInterruptHandler();
    if (hwInterruptNumber > 5 || ISRTable[hwInterruptNumber] != (DWORD)pfnHandler)
        return FALSE;
    ISRTable[hwInterruptNumber] = (DWORD)DisabledInterruptHandler;
    KData.basePSR &= ~(0x0400 << hwInterruptNumber);
    return TRUE;
}

/* Machine dependent constants */
const DWORD cbMDStkAlign = 8;                   // stack 8 bytes aligned

/* Machine dependent thread creation */
// normal thread stack: from top, TLS then PRETLS then args then free
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
MDCreateThread(
    PTHREAD pTh,

⌨️ 快捷键说明

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