📄 oeminit.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
Abstract:
This file implements the NK kernel interfaces for firmware interrupt
support on the CEPC.
Functions:
Notes:
--*/
#include <windows.h>
#include <oal.h>
#include <nkintr.h>
/*
@func void | OEMInit | Initialize Hardware Interfaces
@rdesc none
@comm OEMInit is called by the kernel after it has performed minimal
initialization. Interrupts are disabled and the kernel is not
ready to handle exceptions. The only kernel service available
to this function is <f HookInterrupt>. This should be used to
install ISR's for all the hardware interrupts to be handled by
the firmware. Note that ISR's must be installed for any interrupt
that is to be routed to a device driver - otherwise the
<f InterruptInitialize> call from the driver will fail.
@xref <l Overview.Windows CE Kernel OEM Interface> <f HookInterrupt>
<f InterruptInitialize>
*/
#ifndef VIAHIVE
#ifdef VIAHDDREG
extern DWORD VIAReadRegistryFromOEM(DWORD dwFlags, LPBYTE lpData, DWORD cbData);
DWORD (*pReadRegistryFromOEM)(DWORD dwFlags, LPBYTE lpData, DWORD cbData)
=VIAReadRegistryFromOEM;
extern DWORD VIAWriteRegistryToOEM(DWORD dwFlags, LPBYTE lpData, DWORD cbData);
DWORD (*pWriteRegistryToOEM)(DWORD dwFlags, LPBYTE lpData, DWORD cbData)
=VIAWriteRegistryToOEM;
#endif
#endif
BOOL bRandNumFlag = FALSE; // RNG enable flag
extern DWORD MainMemoryEndAddress;
VOID PCIInitBusInfo (void);
DWORD OEMPowerManagerInit(void);
void InitClock(void);
void x86InitMemory (void);
static void x86InitRomChain (void);
void x86InitPICs(void);
// Add One Line, VIA PowerSaver
extern DWORD CheckCPU( );
extern const BOOL g_fSupportHwDbg;
extern DWORD dwNKDrWatsonSize; // Must change this to enable Kernel Watson support
// must be multiple of PAGE_SIZE
BOOL g_fPostInit;
void CheckC5XL()
{
DWORD dwtemp0, dwtemp1, dwtemp2, dwtemp3;
DWORD dwModel, dwStep;
_asm
{
mov eax, 0
cpuid
mov dwtemp0, eax
mov dwtemp1, ebx
mov dwtemp2, ecx
mov dwtemp3, edx
}
//RETAILMSG(1, (TEXT("dwtemp0=%lXH dwtemp1=%lXH dwtemp2=%lXH dwtemp3=%lXH\r\n"), dwtemp0,dwtemp1,dwtemp2,dwtemp3));
if (dwtemp0 != 0x1 || dwtemp1 != 0x746E6543 || dwtemp2 != 0x736C7561 ||
dwtemp3 != 0x48727561)
{
RETAILMSG(1, (TEXT("Not VIA CPU!\r\n")));
return;
}
_asm
{
mov eax, 1
cpuid
mov dwModel, eax
}
//RETAILMSG(1, (TEXT("dwModel=%lXH\r\n"), dwModel));
dwStep = dwModel & 0x0f;
dwModel = dwModel >> 4;
dwModel = dwModel & 0xf;
switch(dwModel)
{
case 0x09:
{
if (dwStep >= 0x03) {
// Enable Random Number Generator
DWORD dwExtFeature, dwRNG, dwRNGFeature;
if (dwStep >= 0x08)
{
RETAILMSG(1, (TEXT("C5P, Step %x\r\n"), dwStep));
}
else
{
RETAILMSG(1, (TEXT("C5XL, Step %x\r\n"), dwStep));
}
_asm
{
mov eax, 0C0000000h
cpuid
mov dwExtFeature, eax
}
//RETAILMSG(1, (TEXT("dwExtFeature = %x\r\n"), dwExtFeature));
if (dwExtFeature < 0xC0000001)
return;
_asm
{
mov eax, 0C0000001h
cpuid
mov dwRNG, edx
}
DEBUGMSG(1, (TEXT("dwRNG = %x\r\n"), dwRNG));
if ((dwRNG&0x0000000C) == 0x0000000C)
DEBUGMSG(1, (TEXT("Random Number Generator is enabled!\r\n")));
// RNG Enable (110B[6])
_asm
{
mov ecx, 110Bh
rdmsr
or eax, 00000340h
wrmsr
rdmsr
mov dwRNGFeature, eax
}
//DWORD dwBuffer;
RETAILMSG(1, (TEXT("dwRNGFeature = %x\r\n"), dwRNGFeature));
if (dwRNGFeature&0x40) {
bRandNumFlag = TRUE;
RETAILMSG(1, (TEXT("Enable Random Number Generator!\r\n")));
}
}
}
break;
}
}
void OEMInit()
{
ULONG PCIAddr;
ULONG PCIData;
ULONG gbFunNum, gbBusNum, gbDevNum;
USHORT usUSBIoBase, usUSBStatus;
BOOL bUHCI = FALSE;
int i;
// initialize interrupts
OALIntrInit ();
// Initialize PCI bus information
PCIInitBusInfo ();
// start KITL
OALKitlStart ();
RETAILMSG(1, (TEXT("[VIA PLE/KLE CEPC:x86] BSP version: 2.321 %s %s"), TEXT(__DATE__), TEXT(__TIME__)));
#ifdef DEBUG
// Instead of calling OEMWriteDebugString directly, call through exported
// function pointer. This will allow these messages to be seen if debug
// message output is redirected to Ethernet or the parallel port. Otherwise,
// lpWriteDebugStringFunc == OEMWriteDebugString.
lpWriteDebugStringFunc(TEXT("CEPC Firmware Init\r\n"));
#endif
OEMPowerManagerInit();
// initialize PIC
x86InitPICs();
// initialize clock
InitClock();
for (gbFunNum=0; gbFunNum<8/*MAX_PCI_FUN*/; gbFunNum++)
{
for (gbBusNum=0; gbBusNum<3/*MAX_PCI_BUS*/; gbBusNum++)
{
for (gbDevNum=0; gbDevNum<32/*MAX_PCI_DEVICE*/; gbDevNum++)
{
PCIAddr=0x80000000+(gbBusNum<<16)+(gbDevNum<<11)+(gbFunNum<<8);
__asm
{
mov dx, 0cf8h
mov eax, PCIAddr
out dx, eax
mov dx, 0cfch
in eax, dx
mov PCIData, eax
}
//WRITE_PORT_ULONG((PULONG)0xcf8,PCIAddr);
//PCIData=READ_PORT_ULONG((PULONG)0xcfc);
//RETAILMSG(1, (TEXT("PCIData %x\r\n"), PCIData));
if (PCIData==0x30381106)
{
RETAILMSG(1, (TEXT("Find VIA USB Device\r\n")));
// Get USB IO Address, and Stop USB Controller
PCIAddr += 0x20;
__asm
{
mov dx, 0cf8h
mov eax, PCIAddr
out dx, eax
mov dx, 0cfch
in eax, dx
and ax, 0fffeh
mov usUSBIoBase, ax
mov dx, ax
xor ax, ax
out dx, ax
}
RETAILMSG(1, (TEXT("VIA USB IoBase %x\r\n"), usUSBIoBase));
// Check USB Halt
for ( i = 0; i < 0x1000; i++)
{
__asm
{
mov ax, usUSBIoBase
add ax, 2
mov dx, ax
in ax, dx
mov usUSBStatus, ax
out dx, ax
}
if (usUSBStatus & 0x20)
break;
}
DEBUGMSG(1, (TEXT("VIA USB Status %x, Loop %d\r\n"), usUSBStatus, i));
// Disable SMI for USB
PCIAddr += 0xa0;
__asm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -