📄 mdsched.c
字号:
//
// 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 + -