263 lines
5.7 KiB
C
263 lines
5.7 KiB
C
|
/*++
|
|||
|
|
|||
|
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"
|
|||
|
|
|||
|
typedef struct FIRMWARE_INT_ARGUMENTS {
|
|||
|
ULONG pEAX;
|
|||
|
ULONG pEBX;
|
|||
|
ULONG pECX;
|
|||
|
ULONG pEDX;
|
|||
|
ULONG pESI;
|
|||
|
ULONG pEDI;
|
|||
|
ULONG pEBP;
|
|||
|
USHORT pES;
|
|||
|
USHORT pDS;
|
|||
|
USHORT pFlags;
|
|||
|
} FIRMWARE_INT_ARGUMENTS, *PFIRMWARE_INT_ARGUMENTS;
|
|||
|
|
|||
|
ULONG HalpX86BiosInitialized = FALSE;
|
|||
|
ULONG HalpEnableInt10Calls = FALSE;
|
|||
|
ULONG HalpUseFirmwareX86Emulator = FALSE;
|
|||
|
|
|||
|
typedef
|
|||
|
VOID
|
|||
|
(*PVENDOR_EXECUTE_INT) (
|
|||
|
IN USHORT Type,
|
|||
|
IN PFIRMWARE_INT_ARGUMENTS Context
|
|||
|
);
|
|||
|
|
|||
|
PVENDOR_EXECUTE_INT VendorX86ExecuteInt;
|
|||
|
|
|||
|
VOID HalpInitializeX86DisplayAdapter()
|
|||
|
|
|||
|
{
|
|||
|
PSYSTEM_PARAMETER_BLOCK SystemParameterBlock = (PSYSTEM_PARAMETER_BLOCK)(0x80001000);
|
|||
|
|
|||
|
//
|
|||
|
// If EISA I/O Ports or EISA Memory could not be mapped, then leave the
|
|||
|
// X86 BIOS Emulator disabled.
|
|||
|
//
|
|||
|
|
|||
|
if (HalpEisaControlBase == NULL || HalpEisaMemoryBase == NULL) {
|
|||
|
|
|||
|
// DbgPrint("X86 BIOS Emulator Disabled\n");
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If Firmware level X86 Bios Emulator exists, then use that instead of the
|
|||
|
// one built into the HAL.
|
|||
|
//
|
|||
|
|
|||
|
if ((SystemParameterBlock->VendorVectorLength/4) >= 34) {
|
|||
|
|
|||
|
VendorX86ExecuteInt =
|
|||
|
*(PVENDOR_EXECUTE_INT *)((ULONG)(SystemParameterBlock->VendorVector) + 34*4);
|
|||
|
|
|||
|
if (VendorX86ExecuteInt != NULL) {
|
|||
|
HalpX86BiosInitialized = TRUE;
|
|||
|
HalpUseFirmwareX86Emulator = TRUE;
|
|||
|
HalpEnableInt10Calls = TRUE;
|
|||
|
|
|||
|
// DbgPrint("Firmware X86 BIOS Emulator Enabled\n");
|
|||
|
// DbgPrint("INT 10 Calls Enabled\n");
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// DbgPrint("HAL X86 BIOS Emulator Enabled\n");
|
|||
|
|
|||
|
x86BiosInitializeBios(HalpEisaControlBase, HalpEisaMemoryBase);
|
|||
|
|
|||
|
HalpX86BiosInitialized = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Attempt to initialize the Display Adapter by executing the Display Adapters
|
|||
|
// initialization code in its BIOS. The standard for PC video adapters is for
|
|||
|
// the BIOS to reside at 0xC000:0000 on the ISA bus.
|
|||
|
//
|
|||
|
|
|||
|
// DbgPrint("X86BiosInitializeAdapter(0xc0000)\n");
|
|||
|
|
|||
|
if (x86BiosInitializeAdapter(0xc0000, NULL, NULL, NULL) != XM_SUCCESS) {
|
|||
|
HalpEnableInt10Calls = FALSE;
|
|||
|
|
|||
|
// DbgPrint("INT 10 Calls Disabled\n");
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
HalpEnableInt10Calls = TRUE;
|
|||
|
|
|||
|
// DbgPrint("INT 10 Calls Enabled\n");
|
|||
|
}
|
|||
|
|
|||
|
VOID HalpResetX86DisplayAdapter()
|
|||
|
|
|||
|
{
|
|||
|
XM86_CONTEXT Context;
|
|||
|
|
|||
|
//
|
|||
|
// Make INT 10 call to initialize 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);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
FIRMWARE_INT_ARGUMENTS Arguments;
|
|||
|
XM86_CONTEXT Context;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If the X86 BIOS Emulator has not been initialized then fail all INT calls.
|
|||
|
//
|
|||
|
|
|||
|
if (HalpX86BiosInitialized == FALSE) {
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the Video Adapter initialization failed, then we can not make INT 10 calls.
|
|||
|
//
|
|||
|
|
|||
|
if (BiosCommand == 0x10 && HalpEnableInt10Calls == FALSE) {
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
// DbgPrint("HalCallBios(%02X,%04X,%04X,%04X,%04X,%04X,%04X,%04X)\n",BiosCommand,*Eax,*Ebx,*Ecx,*Edx,*Esi,*Edi,*Ebp);
|
|||
|
|
|||
|
if (HalpUseFirmwareX86Emulator == TRUE) {
|
|||
|
|
|||
|
//
|
|||
|
// Make private vector call to the emulator in the firmware.
|
|||
|
//
|
|||
|
|
|||
|
Arguments.pEAX = *Eax;
|
|||
|
Arguments.pEBX = *Ebx;
|
|||
|
Arguments.pECX = *Ecx;
|
|||
|
Arguments.pEDX = *Edx;
|
|||
|
Arguments.pESI = *Esi;
|
|||
|
Arguments.pEDI = *Edi;
|
|||
|
Arguments.pEBP = *Ebp;
|
|||
|
Arguments.pES = 0;
|
|||
|
Arguments.pDS = 0;
|
|||
|
Arguments.pFlags = 0;
|
|||
|
|
|||
|
VendorX86ExecuteInt((USHORT)BiosCommand,&Arguments);
|
|||
|
|
|||
|
*Eax = Arguments.pEAX;
|
|||
|
*Ebx = Arguments.pEBX;
|
|||
|
*Ecx = Arguments.pECX;
|
|||
|
*Edx = Arguments.pEDX;
|
|||
|
*Esi = Arguments.pESI;
|
|||
|
*Edi = Arguments.pEDI;
|
|||
|
*Ebp = Arguments.pEBP;
|
|||
|
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//
|
|||
|
// Make call to emulator build into HAL
|
|||
|
//
|
|||
|
|
|||
|
Context.Eax = *Eax;
|
|||
|
Context.Ebx = *Ebx;
|
|||
|
Context.Ecx = *Ecx;
|
|||
|
Context.Edx = *Edx;
|
|||
|
Context.Esi = *Esi;
|
|||
|
Context.Edi = *Edi;
|
|||
|
Context.Ebp = *Ebp;
|
|||
|
|
|||
|
if (x86BiosExecuteInterrupt((UCHAR)BiosCommand, &Context, NULL, NULL) != XM_SUCCESS) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
*Eax = Context.Eax;
|
|||
|
*Ebx = Context.Ebx;
|
|||
|
*Ecx = Context.Ecx;
|
|||
|
*Edx = Context.Edx;
|
|||
|
*Esi = Context.Esi;
|
|||
|
*Edi = Context.Edi;
|
|||
|
*Ebp = Context.Ebp;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|