mirror of https://github.com/lianthony/NT4.0
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.
359 lines
8.0 KiB
359 lines
8.0 KiB
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
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:
|
|
|
|
David N. Cutler (davec) 17-Jun-1994
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
|
|
ULONG
|
|
x86BiosGetPciDataByOffset(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
ULONG
|
|
x86BiosSetPciDataByOffset(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
|
|
extern PUCHAR HalpShadowBuffer;
|
|
extern ULONG HalpPciMaxBuses;
|
|
extern ULONG HalpInitPhase;
|
|
|
|
|
|
//
|
|
// Define global data.
|
|
//
|
|
|
|
ULONG HalpX86BiosInitialized = FALSE;
|
|
ULONG HalpEnableInt10Calls = FALSE;
|
|
|
|
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;
|
|
|
|
//
|
|
// If the x86 BIOS Emulator has not been initialized, then return FALSE.
|
|
//
|
|
|
|
if (HalpX86BiosInitialized == FALSE) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the Video Adapter 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 (x86BiosExecuteInterruptShadowedPci((UCHAR)BiosCommand,
|
|
&Context,
|
|
(PVOID)HalpIoControlBase,
|
|
(PVOID)(HalpShadowBuffer - 0xc0000),
|
|
(PVOID)HalpIoMemoryBase,
|
|
(UCHAR)HalpPciMaxBuses,
|
|
x86BiosGetPciDataByOffset,
|
|
x86BiosSetPciDataByOffset
|
|
) != XM_SUCCESS) {
|
|
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
|
|
HalpInitializeX86DisplayAdapter(
|
|
ULONG VideoDeviceBusNumber,
|
|
ULONG VideoDeviceSlotNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes a display adapter using the x86 bios emulator.
|
|
|
|
Arguments:
|
|
|
|
BiosAddress - If the BIOS is shadowed, this will be a pointer to
|
|
non-paged pool. If the BIOS is not shadowed, this
|
|
should be HalpIoMemoryBase + C0000.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
XM86_CONTEXT Context;
|
|
|
|
//
|
|
// If I/O Ports or I/O memory could not be mapped, then don't
|
|
// attempt to initialize the display adapter.
|
|
//
|
|
|
|
if (HalpIoControlBase == NULL || HalpIoMemoryBase == NULL) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Initialize the x86 bios emulator.
|
|
//
|
|
|
|
x86BiosInitializeBiosShadowedPci(HalpIoControlBase,
|
|
(PVOID)(HalpShadowBuffer - 0xc0000),
|
|
(PVOID)HalpIoMemoryBase,
|
|
(UCHAR)HalpPciMaxBuses,
|
|
x86BiosGetPciDataByOffset,
|
|
x86BiosSetPciDataByOffset
|
|
);
|
|
HalpX86BiosInitialized = TRUE;
|
|
|
|
//
|
|
// Attempt to initialize the display adapter by executing its ROM bios
|
|
// code. The standard ROM bios code address for PC video adapters is
|
|
// 0xC000:0000 on the ISA bus.
|
|
//
|
|
|
|
// This context specifies where to find the PCI video device in the
|
|
// format explained in the PCI BIOS Specification.
|
|
Context.Eax = (VideoDeviceBusNumber << 8) | (VideoDeviceSlotNumber << 3);
|
|
Context.Ebx = 0;
|
|
Context.Ecx = 0;
|
|
Context.Edx = 0;
|
|
Context.Esi = 0;
|
|
Context.Edi = 0;
|
|
Context.Ebp = 0;
|
|
|
|
if (x86BiosInitializeAdapterShadowedPci(0xc0000,
|
|
&Context,
|
|
(PVOID)HalpIoControlBase,
|
|
(PVOID)(HalpShadowBuffer - 0xc0000),
|
|
(PVOID)HalpIoMemoryBase,
|
|
(UCHAR)HalpPciMaxBuses,
|
|
x86BiosGetPciDataByOffset,
|
|
x86BiosSetPciDataByOffset
|
|
) != XM_SUCCESS) {
|
|
|
|
|
|
|
|
HalpEnableInt10Calls = FALSE;
|
|
return;
|
|
}
|
|
|
|
HalpEnableInt10Calls = TRUE;
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
HalpResetX86DisplayAdapter(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function resets a display adapter using the x86 bios emulator.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
XM86_CONTEXT Context;
|
|
|
|
//
|
|
// Initialize the x86 bios context and make the INT 10 call to initialize
|
|
// the display adapter to 80x25 color text mode.
|
|
//
|
|
|
|
Context.Eax = 0x0003; // Function 0, Mode 3
|
|
Context.Ebx = 0;
|
|
Context.Ecx = 0;
|
|
Context.Edx = 0;
|
|
Context.Esi = 0;
|
|
Context.Edi = 0;
|
|
Context.Ebp = 0;
|
|
|
|
HalCallBios(0x10,
|
|
&Context.Eax,
|
|
&Context.Ebx,
|
|
&Context.Ecx,
|
|
&Context.Edx,
|
|
&Context.Esi,
|
|
&Context.Edi,
|
|
&Context.Ebp);
|
|
}
|
|
|
|
ULONG
|
|
x86BiosGetPciDataByOffset(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is a wrapper. It exists because we don't have
|
|
a consistent interface to PCI config space during the boot
|
|
process.
|
|
|
|
--*/
|
|
{
|
|
|
|
if (HalpInitPhase == 0) {
|
|
return HalpPhase0GetPciDataByOffset(BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
} else {
|
|
return HalGetBusDataByOffset(PCIConfiguration,
|
|
BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
}
|
|
}
|
|
|
|
ULONG
|
|
x86BiosSetPciDataByOffset(
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is a wrapper. It exists because we don't have
|
|
a consistent interface to PCI config space during the boot
|
|
process.
|
|
|
|
--*/
|
|
{
|
|
if (HalpInitPhase == 0) {
|
|
return HalpPhase0SetPciDataByOffset(BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
} else {
|
|
return HalSetBusDataByOffset(PCIConfiguration,
|
|
BusNumber,
|
|
SlotNumber,
|
|
Buffer,
|
|
Offset,
|
|
Length
|
|
);
|
|
}
|
|
}
|
|
|
|
|