You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
660 lines
11 KiB
660 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1996 Intel Corporation
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
i64bios.c copied from hali64\x86bios.c
|
|
|
|
Abstract:
|
|
|
|
|
|
This module implements the platform specific interface between a device
|
|
driver and the execution of x86 ROM bios code for the device.
|
|
|
|
Author:
|
|
|
|
William K. Cheung (wcheung) 20-Mar-1996
|
|
|
|
based on the version by David N. Cutler (davec) 17-Jun-1994
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
Bernard Lint, M.Jayakumar November 1998
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
#include "emulate.h"
|
|
|
|
|
|
#define LOW_MEM_SEGMET 0
|
|
|
|
#define LOW_MEM_OFFSET 0
|
|
|
|
#define SIZE_OF_VECTOR_TABLE 0x400
|
|
|
|
#define SIZE_OF_BIOS_DATA_AREA 0x400
|
|
|
|
extern XM_STATUS x86BiosExecuteInterrupt (
|
|
IN UCHAR Number,
|
|
IN OUT PXM86_CONTEXT Context,
|
|
IN PVOID BiosIoSpace OPTIONAL,
|
|
IN PVOID BiosIoMemory OPTIONAL
|
|
);
|
|
|
|
extern PVOID x86BiosTranslateAddress (
|
|
IN USHORT Segment,
|
|
IN USHORT Offset
|
|
);
|
|
|
|
extern BOOLEAN HalpVideoBiosPresent;
|
|
extern ULONG HalpMaxPciBus;
|
|
|
|
ULONG
|
|
HalpBiosGetPciConfig(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
ULONG
|
|
HalpBiosSetPciConfig(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
|
|
//
|
|
// Initialize Default X86 bios spaces
|
|
//
|
|
|
|
|
|
#define NUMBER_X86_PAGES (0x100000 / PAGE_SIZE) // map through 0xfffff
|
|
|
|
PVOID HalpIoControlBase = NULL;
|
|
PVOID HalpIoMemoryBase = NULL;
|
|
PVOID HalpFrameBufferBase = NULL;
|
|
PVOID HalpLowMemoryBase = NULL;
|
|
|
|
#define VGA_FRAMEBUFFER_SIZE (0xc0000 - 0xa0000)
|
|
|
|
//
|
|
// Define global data.
|
|
//
|
|
|
|
ULONG HalpX86BiosInitialized = FALSE;
|
|
ULONG HalpEnableInt10Calls = FALSE;
|
|
|
|
|
|
VOID
|
|
HalpInitIoMemoryBase(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
This routine completes any mappings needed by the bios emulation engine. HalpEfiInitialization maps
|
|
any EFI descriptor that cover the 1st MB of physical memory. Those mappngs are done according to
|
|
the cachable requirements in the descriptors. Most EFI implementations do not cover the VGA range so
|
|
this function does that if it is not already mapped.
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
PHYSICAL_ADDRESS COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS = { 0xA0000 };
|
|
|
|
|
|
if (HalpFrameBufferBase == NULL) {
|
|
HalpFrameBufferBase = MmMapIoSpace (COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS,
|
|
VGA_FRAMEBUFFER_SIZE,
|
|
MmNonCached);
|
|
|
|
ASSERT(HalpFrameBufferBase != NULL);
|
|
|
|
//
|
|
// Adjust to a zero base.
|
|
//
|
|
|
|
HalpFrameBufferBase = (PVOID)((ULONG64) HalpFrameBufferBase - 0XA0000);
|
|
}
|
|
|
|
ASSERT(HalpIoMemoryBase);
|
|
|
|
}
|
|
|
|
|
|
ULONG
|
|
HalpSetCmosData (
|
|
IN PVOID BusHandler,
|
|
IN PVOID RootHandler,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
ULONG
|
|
HalpGetCmosData (
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpAcquireCmosSpinLock (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpReleaseCmosSpinLock (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
return ;
|
|
}
|
|
|
|
|
|
HAL_DISPLAY_BIOS_INFORMATION
|
|
HalpGetDisplayBiosInformation (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguements:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
|
|
|
|
{
|
|
return HalpVideoBiosPresent ? HalDisplayEmulatedBios : HalDisplayNoBios;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpInitializeCmos (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
return ;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpReadCmosTime (
|
|
PTIME_FIELDS TimeFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
return ;
|
|
}
|
|
|
|
VOID
|
|
HalpWriteCmosTime (
|
|
PTIME_FIELDS TimeFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguements:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
HalpBiosDisplayReset (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguements:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Make an int10 call to set the display into 640x480 16 color mode
|
|
//
|
|
// mov ax, 12h
|
|
// int 10h
|
|
//
|
|
|
|
ULONG Eax = 0x12;
|
|
ULONG Exx = 0x00;
|
|
BOOLEAN Success;
|
|
|
|
Success = HalCallBios(0x10,
|
|
&Eax,
|
|
&Exx,
|
|
&Exx,
|
|
&Exx,
|
|
&Exx,
|
|
&Exx,
|
|
&Exx);
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
HalCallBios (
|
|
IN ULONG BiosCommand,
|
|
IN OUT PULONG Eax,
|
|
IN OUT PULONG Ebx,
|
|
IN OUT PULONG Ecx,
|
|
IN OUT PULONG Edx,
|
|
IN OUT PULONG Esi,
|
|
IN OUT PULONG Edi,
|
|
IN OUT PULONG Ebp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function provides the platform specific interface between a device
|
|
driver and the execution of the x86 ROM bios code for the specified ROM
|
|
bios command.
|
|
|
|
Arguments:
|
|
|
|
BiosCommand - Supplies the ROM bios command to be emulated.
|
|
|
|
Eax to Ebp - Supplies the x86 emulation context.
|
|
|
|
Return Value:
|
|
|
|
A value of TRUE is returned if the specified function is executed.
|
|
Otherwise, a value of FALSE is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
XM86_CONTEXT Context;
|
|
|
|
HalDebugPrint(( HAL_INFO, "HAL: HalCallBios - Cmd = 0x%x, eax = 0x%p\n", BiosCommand, Eax ));
|
|
//
|
|
// If the x86 BIOS Emulator has not been initialized, then return FALSE.
|
|
//
|
|
|
|
if (HalpX86BiosInitialized == FALSE) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the Adapter BIOS initialization failed and an Int10 command is
|
|
// specified, then return FALSE.
|
|
//
|
|
|
|
if ((BiosCommand == 0x10) && (HalpEnableInt10Calls == FALSE)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Copy the x86 bios context and emulate the specified command.
|
|
//
|
|
|
|
Context.Eax = *Eax;
|
|
Context.Ebx = *Ebx;
|
|
Context.Ecx = *Ecx;
|
|
Context.Edx = *Edx;
|
|
Context.Esi = *Esi;
|
|
Context.Edi = *Edi;
|
|
Context.Ebp = *Ebp;
|
|
|
|
|
|
if (x86BiosExecuteInterruptShadowed((UCHAR)BiosCommand,
|
|
&Context,
|
|
(PVOID)HalpIoControlBase,
|
|
(PVOID)HalpIoMemoryBase,
|
|
(PVOID)HalpFrameBufferBase
|
|
) != XM_SUCCESS) {
|
|
|
|
HalDebugPrint(( HAL_ERROR, "HAL: HalCallBios - ERROR in Cmd = 0x%x\n", BiosCommand ));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
//
|
|
// Copy the x86 bios context and return TRUE.
|
|
//
|
|
|
|
*Eax = Context.Eax;
|
|
*Ebx = Context.Ebx;
|
|
*Ecx = Context.Ecx;
|
|
*Edx = Context.Edx;
|
|
*Esi = Context.Esi;
|
|
*Edi = Context.Edi;
|
|
*Ebp = Context.Ebp;
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
HalpInitializeX86Int10Call(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes x86 bios emulator, display data area and
|
|
interrupt vector area.
|
|
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
XM86_CONTEXT State;
|
|
PXM86_CONTEXT Context;
|
|
PULONG x86BiosLowMemoryPtr, PhysicalMemoryPtr;
|
|
|
|
if (HalpLowMemoryBase == NULL) {
|
|
|
|
//
|
|
// There is no memory at zero so there cannot be any bios.
|
|
//
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Initialize the x86 bios emulator.
|
|
//
|
|
|
|
|
|
x86BiosInitializeBiosShadowedPci(HalpIoControlBase,
|
|
HalpIoMemoryBase,
|
|
HalpFrameBufferBase,
|
|
(UCHAR)(HalpMaxPciBus == 255 ? 255 : (HalpMaxPciBus + 1)),
|
|
HalpBiosGetPciConfig,
|
|
HalpBiosSetPciConfig
|
|
);
|
|
|
|
x86BiosLowMemoryPtr = (PULONG)(x86BiosTranslateAddress(LOW_MEM_SEGMET, LOW_MEM_OFFSET));
|
|
PhysicalMemoryPtr = (PULONG) HalpLowMemoryBase;
|
|
|
|
//
|
|
// Copy the VECTOR TABLE from 0 to 2k. This is because we are not executing
|
|
// the initialization of Adapter since SAL takes care of it. However, the
|
|
// emulation memory needs to be updated from the interrupt vector and BIOS
|
|
// data area.
|
|
//
|
|
|
|
RtlCopyMemory(x86BiosLowMemoryPtr,
|
|
PhysicalMemoryPtr,
|
|
(SIZE_OF_VECTOR_TABLE+SIZE_OF_BIOS_DATA_AREA)
|
|
);
|
|
|
|
HalpX86BiosInitialized = TRUE;
|
|
|
|
//
|
|
// Check to see if a video bios appears to be present and int10 vector
|
|
// points somewhere inside of the video bios
|
|
//
|
|
{
|
|
PUSHORT pBiosSignature = (PUSHORT)(x86BiosTranslateAddress(0xc000, // VIDEO_BIOS_SEGMENT
|
|
0x0000));
|
|
|
|
ULONG Address = *(PULONG)(x86BiosTranslateAddress(0x0, 0x40));
|
|
Address = ((Address & 0xFFFF0000) >> 12) + (Address & 0xFFFF); // Normalize
|
|
|
|
HalpEnableInt10Calls = (*pBiosSignature == 0xAA55) &&
|
|
(Address >= 0xC0000) && (Address < 0xD0000);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpResetX86DisplayAdapter(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function resets a display adapter using the x86 bios emulator.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Eax;
|
|
ULONG Ebx;
|
|
ULONG Ecx;
|
|
ULONG Edx;
|
|
ULONG Esi;
|
|
ULONG Edi;
|
|
ULONG Ebp;
|
|
|
|
//
|
|
// Initialize the x86 bios context and make the INT 10 call to initialize
|
|
// the display adapter to 80x25 color text mode.
|
|
//
|
|
|
|
Eax = 0x0003; // Function 0, Mode 3
|
|
Ebx = 0;
|
|
Ecx = 0;
|
|
Edx = 0;
|
|
Esi = 0;
|
|
Edi = 0;
|
|
Ebp = 0;
|
|
|
|
HalCallBios(0x10,
|
|
&Eax,
|
|
&Ebx,
|
|
&Ecx,
|
|
&Edx,
|
|
&Esi,
|
|
&Edi,
|
|
&Ebp);
|
|
}
|
|
|
|
ULONG
|
|
HalpBiosGetPciConfig(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function wraps HalGetBusDataByOffset for use by the x86 emulator.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return HalGetBusDataByOffset(PCIConfiguration,
|
|
BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpBiosSetPciConfig(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function wraps HalGetBusDataByOffset for use by the x86 emulator.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return HalSetBusDataByOffset(PCIConfiguration,
|
|
BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
}
|