📄 mdsh3.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"
#include "shx.h"
extern void UnusedHandler(void);
extern void OEMInitDebugSerial(void);
extern void InitClock(void);
extern void LoadKPage(void);
extern void DumpFrame(PTHREAD pth, PCONTEXT pctx, DWORD dwExc, DWORD info);
extern void APICallReturn(void);
#ifdef SH4
void SaveFloatContext(PTHREAD);
void RestoreFloatContext(PTHREAD);
DWORD GetAndClearFloatCode(void);
DWORD GetAndClearFloatCode(void);
DWORD GetCauseFloatCode(void);
extern BOOL HandleHWFloatException(EXCEPTION_RECORD *ExceptionRecord,
PCONTEXT pctx);
extern unsigned int get_fpscr();
extern void set_fpscr(unsigned int);
extern void clr_fpscr(unsigned int);
extern void DisableFPU();
#endif
#ifdef SH3
// frequency control register value
extern unsigned short SH3FQCR_Fast;
extern unsigned int SH3DSP;
void SaveSH3DSPContext(PTHREAD);
void RestoreSH3DSPContext(PTHREAD);
#endif
#if defined (SH3)
const wchar_t NKCpuType [] = TEXT("SH-3");
#elif defined (SH4)
const wchar_t NKCpuType [] = TEXT("SH-4");
#else
#error "Unknown CPU"
#endif
// OEM definable extra bits for the Cache Control Register
unsigned long OEMExtraCCR;
extern char InterlockedAPIs[], InterlockedEnd[];
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);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SH3Init(
int cpuType
)
{
int ix;
#ifdef SH3
/* initialize frequency control register */
if (SH3FQCR_Fast)
*(volatile ushort *)0xffffff80 = SH3FQCR_Fast;
#endif
/* Disable the cpu cache & flush it. */
CCR = 0;
CCR = CACHE_FLUSH;
// SH4 cpu architecture requires when modifying CCR from P2 area,
// at least 8 instructions must be in between before issuing // a branch to U0/P0/P1/P3 area.
__asm("nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n");
/* Zero out kernel data page. */
memset(&KData, 0, sizeof(KData));
KData.handleBase = 0x80000000;
KData.pAPIReturn = (ulong)APICallReturn;
/* Initialize SectionTable in KPage */
for (ix = 1 ; ix <= SECTION_MASK ; ++ix)
SectionTable[ix] = NULL_SECTION;
/* Copy kernel data to RAM & zero out BSS */
KernelRelocate(pTOC);
OEMInitDebugSerial(); // initialize serial port
OEMWriteDebugString(TEXT("\r\nWindows CE Kernel for Hitachi SH Built on ") TEXT(__DATE__)
TEXT(" at ") TEXT(__TIME__) TEXT("\r\n"));
#if defined(SH4)
OEMWriteDebugString(TEXT("SH-4 Kernel\r\n"));
#else
NKDbgPrintfW(L"SH-3 Kernel. FQCR=%x\r\n", *(volatile ushort *)0xffffff80);
#endif
/* Initialize address translation hardware. */
MMUTEA = 0; /* clear transation address */
MMUTTB = (DWORD)SectionTable; /* set translation table base address */
MMUPTEH = 0; /* clear ASID */
MMUCR = TLB_FLUSH | TLB_ENABLE;
LoadKPage();
/* Copy interlocked api code into the kpage */
DEBUGCHK(sizeof(KData) <= FIRST_INTERLOCK);
DEBUGCHK((InterlockedEnd-InterlockedAPIs)+FIRST_INTERLOCK == 0x400);
memcpy((char *)&KData+FIRST_INTERLOCK, InterlockedAPIs, InterlockedEnd-InterlockedAPIs);
// Enable the CPU cache. Can't do this before KernelRelocate because OEMExtraCCR
// may not be properly initialized before that point.
CCR = CACHE_ENABLE | OEMExtraCCR;
// SH4 cpu architecture requires when modifying CCR from P2 area,
// at least 8 instructions must be in between before issuing a branch // to U0/P0/P1/P3 area.
__asm("nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n");
NKDbgPrintfW(L"CCR=%4.4x\r\n", CCR);
OEMInit(); // initialize firmware
KernelFindMemory();
#ifdef DEBUG
OEMWriteDebugString(TEXT("SH3Init done.\r\n"));
#endif
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
HookInterrupt(
int hwInterruptNumber,
FARPROC pfnHandler
)
{
if (hwInterruptNumber > 112)
return FALSE;
InterruptTable[hwInterruptNumber] = (DWORD)pfnHandler;
return TRUE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
UnhookInterrupt(
int hwInterruptNumber,
FARPROC pfnHandler
)
{
if (hwInterruptNumber > 112 ||
InterruptTable[hwInterruptNumber] != (DWORD)pfnHandler)
return FALSE;
InterruptTable[hwInterruptNumber] = (DWORD)UnusedHandler;
return TRUE;
}
#ifdef SH4
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SwitchFPUOwner(
PCONTEXT pctx
)
{
KCALLPROFON(61);
if (g_CurFPUOwner != pCurThread) {
if (g_CurFPUOwner)
SaveFloatContext(g_CurFPUOwner);
g_CurFPUOwner = pCurThread;
RestoreFloatContext(pCurThread);
}
KCALLPROFOFF(61);
pctx->Psr &= ~SR_FPU_DISABLED;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
FPUFlushContext(void)
{
if (!InSysCall())
KCall ((FARPROC) FPUFlushContext);
else if (g_CurFPUOwner) {
SaveFloatContext(g_CurFPUOwner);
g_CurFPUOwner->ctx.Psr |= SR_FPU_DISABLED;
DisableFPU();
g_CurFPUOwner = 0;
}
}
DWORD dwStoreQueueBase;
BOOL DoSetRAMMode(BOOL bEnable, LPVOID *lplpvAddress, LPDWORD lpLength);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_SetRAMMode(
BOOL bEnable,
LPVOID *lplpvAddress,
LPDWORD lpLength
)
{
TRUSTED_API (L"SC_SetRAMMode", FALSE);
return DoSetRAMMode(bEnable, lplpvAddress, lpLength);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
SC_SetStoreQueueBase(
DWORD dwPhysPage
)
{
TRUSTED_API (L"SC_SetStoreQueueBase", NULL);
if (dwPhysPage & (1024*1024-1)) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
return 0;
}
if (dwPhysPage & 0xe0000000) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
return 0;
}
dwStoreQueueBase = dwPhysPage | PG_VALID_MASK | PG_1M_MASK | PG_PROT_WRITE | PG_DIRTY_MASK | 1;
OEMCacheRangeFlush (0, 0, CACHE_SYNC_ALL);
return (LPVOID)0xE0000000;
}
#else // !SH4
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SwitchDSPOwner(
PCONTEXT pctx
)
{
KCALLPROFON(68);
if (g_CurDSPOwner != pCurThread) {
if (g_CurDSPOwner)
SaveSH3DSPContext(g_CurDSPOwner);
g_CurDSPOwner = pCurThread;
RestoreSH3DSPContext(pCurThread);
}
pctx->Psr |= SR_DSP_ENABLED; // enable the DSP
KCALLPROFOFF(68);
}
void DSPFlushContext(void) {
if (g_CurDSPOwner) {
SaveSH3DSPContext(g_CurDSPOwner);
g_CurDSPOwner->ctx.Psr &= ~SR_DSP_ENABLED; // disable the DSP
g_CurDSPOwner = 0;
}
}
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
NKCreateStaticMapping(
DWORD dwPhysBase,
DWORD dwSize
)
{
dwPhysBase <<= 8; // Only supports 32-bit physical address.
if (dwPhysBase < 0x20000000 && ((dwPhysBase + dwSize) < 0x20000000)) {
return Phys2VirtUC(dwPhysBase);
} else {
return NULL;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID MDValidateKVA (DWORD dwAddr)
{
return ((dwAddr < 0xC0000000) || (dwAddr >= 0xE0000000)) // between 0x80000000 - 0xc0000000
// or >= 0xE0000000
? (LPVOID) dwAddr : NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
SC_CreateStaticMapping(
DWORD dwPhysBase,
DWORD dwSize
)
{
TRUSTED_API (L"NKCreateStaticMapping", NULL);
return NKCreateStaticMapping(dwPhysBase, dwSize);
}
typedef struct ExcInfo {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -