909 lines
19 KiB
C
909 lines
19 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
x86bios.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements supplies the HAL interface to the 386/486
|
|||
|
real mode emulator for the purpose of emulating BIOS calls..
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
David N. Cutler (davec) 13-Nov-1994
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "nthal.h"
|
|||
|
#include "hal.h"
|
|||
|
#include "xm86.h"
|
|||
|
#include "x86new.h"
|
|||
|
|
|||
|
//
|
|||
|
// Define the size of low memory.
|
|||
|
//
|
|||
|
|
|||
|
#define LOW_MEMORY_SIZE 0x800
|
|||
|
|
|||
|
//
|
|||
|
// Define storage for low emulated memory.
|
|||
|
//
|
|||
|
|
|||
|
UCHAR x86BiosLowMemory[LOW_MEMORY_SIZE + 3];
|
|||
|
ULONG x86BiosScratchMemory;
|
|||
|
|
|||
|
//
|
|||
|
// Define storage to capture the base address of I/O space, the base address
|
|||
|
// of I/O memory space, and the base address of the video frame buffer.
|
|||
|
//
|
|||
|
|
|||
|
ULONG_PTR x86BiosFrameBuffer;
|
|||
|
ULONG_PTR x86BiosIoMemory;
|
|||
|
ULONG_PTR x86BiosIoSpace;
|
|||
|
|
|||
|
//
|
|||
|
// Define an area of storage to allow for buffer passing between the BIOS
|
|||
|
// and native mode code.
|
|||
|
//
|
|||
|
|
|||
|
ULONG_PTR x86BiosTransferMemory = 0;
|
|||
|
ULONG x86BiosTransferLength = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Define BIOS initialized state.
|
|||
|
//
|
|||
|
|
|||
|
BOOLEAN x86BiosInitialized = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Define storage for PCI BIOS initialization state.
|
|||
|
//
|
|||
|
|
|||
|
UCHAR XmNumberPciBusses = 0;
|
|||
|
BOOLEAN XmPciBiosPresent = FALSE;
|
|||
|
PGETSETPCIBUSDATA XmGetPciData;
|
|||
|
PGETSETPCIBUSDATA XmSetPciData;
|
|||
|
|
|||
|
ULONG
|
|||
|
x86BiosReadIoSpace (
|
|||
|
IN XM_OPERATION_DATATYPE DataType,
|
|||
|
IN USHORT PortNumber
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function reads from emulated I/O space.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DataType - Supplies the datatype for the read operation.
|
|||
|
|
|||
|
PortNumber - Supplies the port number in I/O space to read from.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The value read from I/O space is returned as the function value.
|
|||
|
|
|||
|
N.B. If an aligned operation is specified, then the individual
|
|||
|
bytes are read from the specified port one at a time and
|
|||
|
assembled into the specified datatype.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
ULONG Result;
|
|||
|
|
|||
|
union {
|
|||
|
PUCHAR Byte;
|
|||
|
PUSHORT Word;
|
|||
|
PULONG Long;
|
|||
|
} u;
|
|||
|
|
|||
|
//
|
|||
|
// Compute port address and read port.
|
|||
|
//
|
|||
|
|
|||
|
u.Long = (PULONG)(x86BiosIoSpace + PortNumber);
|
|||
|
if (DataType == BYTE_DATA) {
|
|||
|
Result = READ_PORT_UCHAR(u.Byte);
|
|||
|
|
|||
|
} else if (DataType == LONG_DATA) {
|
|||
|
if (((ULONG_PTR)u.Long & 0x3) != 0) {
|
|||
|
Result = (READ_PORT_UCHAR(u.Byte + 0)) |
|
|||
|
(READ_PORT_UCHAR(u.Byte + 1) << 8) |
|
|||
|
(READ_PORT_UCHAR(u.Byte + 2) << 16) |
|
|||
|
(READ_PORT_UCHAR(u.Byte + 3) << 24);
|
|||
|
|
|||
|
} else {
|
|||
|
Result = READ_PORT_ULONG(u.Long);
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
if (((ULONG_PTR)u.Word & 0x1) != 0) {
|
|||
|
Result = (READ_PORT_UCHAR(u.Byte + 0)) |
|
|||
|
(READ_PORT_UCHAR(u.Byte + 1) << 8);
|
|||
|
|
|||
|
} else {
|
|||
|
Result = READ_PORT_USHORT(u.Word);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Result;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
x86BiosWriteIoSpace (
|
|||
|
IN XM_OPERATION_DATATYPE DataType,
|
|||
|
IN USHORT PortNumber,
|
|||
|
IN ULONG Value
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function write to emulated I/O space.
|
|||
|
|
|||
|
N.B. If an aligned operation is specified, then the individual
|
|||
|
bytes are written to the specified port one at a time.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DataType - Supplies the datatype for the write operation.
|
|||
|
|
|||
|
PortNumber - Supplies the port number in I/O space to write to.
|
|||
|
|
|||
|
Value - Supplies the value to write.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
union {
|
|||
|
PUCHAR Byte;
|
|||
|
PUSHORT Word;
|
|||
|
PULONG Long;
|
|||
|
} u;
|
|||
|
|
|||
|
//
|
|||
|
// Compute port address and read port.
|
|||
|
//
|
|||
|
|
|||
|
u.Long = (PULONG)(x86BiosIoSpace + PortNumber);
|
|||
|
if (DataType == BYTE_DATA) {
|
|||
|
WRITE_PORT_UCHAR(u.Byte, (UCHAR)Value);
|
|||
|
|
|||
|
} else if (DataType == LONG_DATA) {
|
|||
|
if (((ULONG_PTR)u.Long & 0x3) != 0) {
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 0, (UCHAR)(Value));
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 1, (UCHAR)(Value >> 8));
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 2, (UCHAR)(Value >> 16));
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 3, (UCHAR)(Value >> 24));
|
|||
|
|
|||
|
} else {
|
|||
|
WRITE_PORT_ULONG(u.Long, Value);
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
if (((ULONG_PTR)u.Word & 0x1) != 0) {
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 0, (UCHAR)(Value));
|
|||
|
WRITE_PORT_UCHAR(u.Byte + 1, (UCHAR)(Value >> 8));
|
|||
|
|
|||
|
} else {
|
|||
|
WRITE_PORT_USHORT(u.Word, (USHORT)Value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
PVOID
|
|||
|
x86BiosTranslateAddress (
|
|||
|
IN USHORT Segment,
|
|||
|
IN USHORT Offset
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This translates a segment/offset address into a memory address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Segment - Supplies the segment register value.
|
|||
|
|
|||
|
Offset - Supplies the offset within segment.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The memory address of the translated segment/offset pair is
|
|||
|
returned as the function value.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
ULONG Value;
|
|||
|
|
|||
|
//
|
|||
|
// Compute the logical memory address and case on high hex digit of
|
|||
|
// the resultant address.
|
|||
|
//
|
|||
|
|
|||
|
Value = Offset + (Segment << 4);
|
|||
|
Offset = (USHORT)(Value & 0xffff);
|
|||
|
Value &= 0xf0000;
|
|||
|
switch ((Value >> 16) & 0xf) {
|
|||
|
|
|||
|
//
|
|||
|
// Interrupt vector/stack space.
|
|||
|
//
|
|||
|
|
|||
|
case 0x0:
|
|||
|
if (Offset > LOW_MEMORY_SIZE) {
|
|||
|
x86BiosScratchMemory = 0;
|
|||
|
return (PVOID)&x86BiosScratchMemory;
|
|||
|
|
|||
|
} else {
|
|||
|
return (PVOID)(&x86BiosLowMemory[0] + Offset);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The memory range from 0x10000 to 0x8ffff reads as zero
|
|||
|
// and writes are ignored.
|
|||
|
//
|
|||
|
|
|||
|
case 0x1:
|
|||
|
case 0x3:
|
|||
|
case 0x4:
|
|||
|
case 0x5:
|
|||
|
case 0x6:
|
|||
|
case 0x7:
|
|||
|
case 0x8:
|
|||
|
x86BiosScratchMemory = 0;
|
|||
|
return (PVOID)&x86BiosScratchMemory;
|
|||
|
|
|||
|
case 0x9:
|
|||
|
//
|
|||
|
// BUGBUG: Found a VGA adapter loaded in segment 9
|
|||
|
// Emulator assumptions about video adapters needs to be
|
|||
|
// looked at
|
|||
|
//
|
|||
|
return (PVOID)(x86BiosIoMemory + Offset + Value);
|
|||
|
|
|||
|
//
|
|||
|
// The memory range from 0x20000 to 0x20fff is used to transfer
|
|||
|
// buffers between native mode and emulated mode.
|
|||
|
//
|
|||
|
|
|||
|
case 0x2:
|
|||
|
if (Offset < x86BiosTransferLength) {
|
|||
|
return (PVOID)(x86BiosTransferMemory + Offset);
|
|||
|
} else {
|
|||
|
x86BiosScratchMemory = 0;
|
|||
|
return (PVOID)&x86BiosScratchMemory;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The memory range from 0xa0000 to 0xbffff maps to the
|
|||
|
// framebuffer if previously specified, otherwise I/O memory.
|
|||
|
//
|
|||
|
|
|||
|
case 0xa:
|
|||
|
case 0xb:
|
|||
|
if (x86BiosFrameBuffer != 0) {
|
|||
|
return (PVOID)(x86BiosFrameBuffer + Offset + Value);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The memory range from 0xc0000 to 0xfffff maps to I/O memory
|
|||
|
//
|
|||
|
|
|||
|
case 0xc:
|
|||
|
case 0xd:
|
|||
|
case 0xe:
|
|||
|
case 0xf:
|
|||
|
return (PVOID)(x86BiosIoMemory + Offset + Value);
|
|||
|
|
|||
|
DEFAULT_UNREACHABLE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
x86BiosInitializeBios (
|
|||
|
IN PVOID BiosIoSpace,
|
|||
|
IN PVOID BiosIoMemory
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes x86 BIOS emulation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BiosIoSpace - Supplies the base address of the I/O space to be used
|
|||
|
for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies the base address of the I/O memory to be
|
|||
|
used for BIOS emulation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Initialize x86 BIOS emulation.
|
|||
|
//
|
|||
|
|
|||
|
x86BiosInitializeBiosShadowed(BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
NULL);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
x86BiosInitializeBiosEx (
|
|||
|
IN PVOID BiosIoSpace,
|
|||
|
IN PVOID BiosIoMemory,
|
|||
|
IN PVOID BiosTransferMemory,
|
|||
|
IN ULONG TransferLength
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes x86 BIOS emulation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BiosIoSpace - Supplies the base address of the I/O space to be used
|
|||
|
for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies the base address of the I/O memory to be
|
|||
|
used for BIOS emulation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Initialize x86 BIOS emulation.
|
|||
|
//
|
|||
|
|
|||
|
x86BiosInitializeBiosShadowed(BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
NULL);
|
|||
|
|
|||
|
x86BiosTransferMemory = (ULONG_PTR)BiosTransferMemory;
|
|||
|
x86BiosTransferLength = TransferLength;
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
x86BiosInitializeBiosShadowed (
|
|||
|
IN PVOID BiosIoSpace,
|
|||
|
IN PVOID BiosIoMemory,
|
|||
|
IN PVOID BiosFrameBuffer
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes x86 BIOS emulation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BiosIoSpace - Supplies the base address of the I/O space to be used
|
|||
|
for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies the base address of the I/O memory to be
|
|||
|
used for BIOS emulation.
|
|||
|
|
|||
|
BiosFrameBuffer - Supplies the base address of the video frame buffer
|
|||
|
to be used for bios emulation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Zero low memory.
|
|||
|
//
|
|||
|
|
|||
|
memset(&x86BiosLowMemory, 0, LOW_MEMORY_SIZE);
|
|||
|
|
|||
|
//
|
|||
|
// Save base address of I/O memory and I/O space.
|
|||
|
//
|
|||
|
|
|||
|
x86BiosIoSpace = (ULONG_PTR)BiosIoSpace;
|
|||
|
x86BiosIoMemory = (ULONG_PTR)BiosIoMemory;
|
|||
|
x86BiosFrameBuffer = (ULONG_PTR)BiosFrameBuffer;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the emulator and the BIOS.
|
|||
|
//
|
|||
|
|
|||
|
XmInitializeEmulator(0,
|
|||
|
LOW_MEMORY_SIZE,
|
|||
|
x86BiosReadIoSpace,
|
|||
|
x86BiosWriteIoSpace,
|
|||
|
x86BiosTranslateAddress);
|
|||
|
|
|||
|
x86BiosInitialized = TRUE;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
x86BiosInitializeBiosShadowedPci (
|
|||
|
IN PVOID BiosIoSpace,
|
|||
|
IN PVOID BiosIoMemory,
|
|||
|
IN PVOID BiosFrameBuffer,
|
|||
|
IN UCHAR NumberPciBusses,
|
|||
|
IN PGETSETPCIBUSDATA GetPciData,
|
|||
|
IN PGETSETPCIBUSDATA SetPciData
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes x86 BIOS emulation and also sets up the
|
|||
|
emulator with BIOS shadowed and PCI functions enabled. Since the
|
|||
|
PCI specification requires BIOS shadowing, there isn't any need
|
|||
|
to provide a function that turns on the PCI functions, but doesn't
|
|||
|
shadow the BIOS.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BiosIoSpace - Supplies the base address of the I/O space to be used
|
|||
|
for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies the base address of the I/O memory to be
|
|||
|
used for BIOS emulation.
|
|||
|
|
|||
|
BiosFrameBuffer - Supplies the base address of the video frame buffer
|
|||
|
to be used for bios emulation.
|
|||
|
|
|||
|
NumberPciBusses - Supplies the number of PCI busses in the system.
|
|||
|
|
|||
|
GetPciData - Supplies the address of a function to read the PCI
|
|||
|
configuration space.
|
|||
|
|
|||
|
SetPciData - Supplies the address of a function to write the PCI
|
|||
|
configuration space.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Enable PCI BIOS support.
|
|||
|
//
|
|||
|
|
|||
|
XmPciBiosPresent = TRUE;
|
|||
|
XmGetPciData = GetPciData;
|
|||
|
XmSetPciData = SetPciData;
|
|||
|
XmNumberPciBusses = NumberPciBusses;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize x86 BIOS emulation.
|
|||
|
//
|
|||
|
|
|||
|
x86BiosInitializeBiosShadowed(BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
BiosFrameBuffer);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosExecuteInterrupt (
|
|||
|
IN UCHAR Number,
|
|||
|
IN OUT PXM86_CONTEXT Context,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function executes an interrupt by calling the x86 emulator.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Number - Supplies the number of the interrupt that is to be emulated.
|
|||
|
|
|||
|
Context - Supplies a pointer to an x86 context structure.
|
|||
|
|
|||
|
BiosIoSpace - Supplies an optional base address of the I/O space
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies an optional base address of the I/O memory
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Execute x86 interrupt.
|
|||
|
//
|
|||
|
|
|||
|
return x86BiosExecuteInterruptShadowed(Number,
|
|||
|
Context,
|
|||
|
BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosExecuteInterruptShadowed (
|
|||
|
IN UCHAR Number,
|
|||
|
IN OUT PXM86_CONTEXT Context,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL,
|
|||
|
IN PVOID BiosFrameBuffer OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function executes an interrupt by calling the x86 emulator.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Number - Supplies the number of the interrupt that is to be emulated.
|
|||
|
|
|||
|
Context - Supplies a pointer to an x86 context structure.
|
|||
|
|
|||
|
BiosIoSpace - Supplies an optional base address of the I/O space
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies an optional base address of the I/O memory
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
BiosFrameBuffer - Supplies an optional base address of the video
|
|||
|
frame buffer to be used for bios emulation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
XM_STATUS Status;
|
|||
|
|
|||
|
//
|
|||
|
// If a new base address is specified, then set the appropriate base.
|
|||
|
//
|
|||
|
|
|||
|
if (BiosIoSpace != NULL) {
|
|||
|
x86BiosIoSpace = (ULONG_PTR)BiosIoSpace;
|
|||
|
}
|
|||
|
|
|||
|
if (BiosIoMemory != NULL) {
|
|||
|
x86BiosIoMemory = (ULONG_PTR)BiosIoMemory;
|
|||
|
}
|
|||
|
|
|||
|
if (BiosFrameBuffer != NULL) {
|
|||
|
x86BiosFrameBuffer = (ULONG_PTR)BiosFrameBuffer;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Execute the specified interrupt.
|
|||
|
//
|
|||
|
|
|||
|
Status = XmEmulateInterrupt(Number, Context);
|
|||
|
if (Status != XM_SUCCESS) {
|
|||
|
DbgPrint("HAL: Interrupt emulation failed, status %lx\n", Status);
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosExecuteInterruptShadowedPci (
|
|||
|
IN UCHAR Number,
|
|||
|
IN OUT PXM86_CONTEXT Context,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL,
|
|||
|
IN PVOID BiosFrameBuffer OPTIONAL,
|
|||
|
IN UCHAR NumberPciBusses,
|
|||
|
IN PGETSETPCIBUSDATA GetPciData,
|
|||
|
IN PGETSETPCIBUSDATA SetPciData
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function executes an interrupt by calling the x86 emulator.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Number - Supplies the number of the interrupt that is to be emulated.
|
|||
|
|
|||
|
Context - Supplies a pointer to an x86 context structure.
|
|||
|
|
|||
|
BiosIoSpace - Supplies an optional base address of the I/O space
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
BiosIoMemory - Supplies an optional base address of the I/O memory
|
|||
|
to be used for BIOS emulation.
|
|||
|
|
|||
|
NumberPciBusses - Supplies the number of PCI busses in the system.
|
|||
|
|
|||
|
GetPciData - Supplies the address of a function to read the PCI
|
|||
|
configuration space.
|
|||
|
|
|||
|
SetPciData - Supplies the address of a function to write the PCI
|
|||
|
configuration space.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Enable PCI BIOS support.
|
|||
|
//
|
|||
|
|
|||
|
XmPciBiosPresent = TRUE;
|
|||
|
XmGetPciData = GetPciData;
|
|||
|
XmSetPciData = SetPciData;
|
|||
|
XmNumberPciBusses = NumberPciBusses;
|
|||
|
|
|||
|
//
|
|||
|
// Execute x86 interrupt.
|
|||
|
//
|
|||
|
|
|||
|
return x86BiosExecuteInterruptShadowed(Number,
|
|||
|
Context,
|
|||
|
BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
BiosFrameBuffer);
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosInitializeAdapter(
|
|||
|
IN ULONG Adapter,
|
|||
|
IN OUT PXM86_CONTEXT Context OPTIONAL,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes the adapter whose BIOS starts at the
|
|||
|
specified 20-bit address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Adpater - Supplies the 20-bit address of the BIOS for the adapter
|
|||
|
to be initialized.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the specified adapter.
|
|||
|
//
|
|||
|
|
|||
|
return x86BiosInitializeAdapterShadowed(Adapter,
|
|||
|
Context,
|
|||
|
BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
NULL);
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosInitializeAdapterShadowed (
|
|||
|
IN ULONG Adapter,
|
|||
|
IN OUT PXM86_CONTEXT Context OPTIONAL,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL,
|
|||
|
IN PVOID BiosFrameBuffer OPTIONAL
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes the adapter whose BIOS starts at the
|
|||
|
specified 20-bit address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Adpater - Supplies the 20-bit address of the BIOS for the adapter
|
|||
|
to be initialized.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PUCHAR Byte;
|
|||
|
XM86_CONTEXT State;
|
|||
|
USHORT Offset;
|
|||
|
USHORT Segment;
|
|||
|
XM_STATUS Status;
|
|||
|
|
|||
|
//
|
|||
|
// If BIOS emulation has not been initialized, then return an error.
|
|||
|
//
|
|||
|
|
|||
|
if (x86BiosInitialized == FALSE) {
|
|||
|
return XM_EMULATOR_NOT_INITIALIZED;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If an emulator context is not specified, then use a default
|
|||
|
// context.
|
|||
|
//
|
|||
|
|
|||
|
if (ARGUMENT_PRESENT(Context) == FALSE) {
|
|||
|
State.Eax = 0;
|
|||
|
State.Ecx = 0;
|
|||
|
State.Edx = 0;
|
|||
|
State.Ebx = 0;
|
|||
|
State.Ebp = 0;
|
|||
|
State.Esi = 0;
|
|||
|
State.Edi = 0;
|
|||
|
Context = &State;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If a new base address is specified, then set the appropriate base.
|
|||
|
//
|
|||
|
|
|||
|
if (BiosIoSpace != NULL) {
|
|||
|
x86BiosIoSpace = (ULONG_PTR)BiosIoSpace;
|
|||
|
}
|
|||
|
|
|||
|
if (BiosIoMemory != NULL) {
|
|||
|
x86BiosIoMemory = (ULONG_PTR)BiosIoMemory;
|
|||
|
}
|
|||
|
|
|||
|
if (BiosFrameBuffer != NULL) {
|
|||
|
x86BiosFrameBuffer = (ULONG_PTR)BiosFrameBuffer;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the specified adpater is not BIOS code, then return an error.
|
|||
|
//
|
|||
|
|
|||
|
Segment = (USHORT)((Adapter >> 4) & 0xf000);
|
|||
|
Offset = (USHORT)(Adapter & 0xffff);
|
|||
|
Byte = (PUCHAR)x86BiosTranslateAddress(Segment, Offset);
|
|||
|
|
|||
|
if ((*Byte++ != 0x55) || (*Byte != 0xaa)) {
|
|||
|
return XM_ILLEGAL_CODE_SEGMENT;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Call the BIOS code to initialize the specified adapter.
|
|||
|
//
|
|||
|
|
|||
|
Adapter += 3;
|
|||
|
Segment = (USHORT)((Adapter >> 4) & 0xf000);
|
|||
|
Offset = (USHORT)(Adapter & 0xffff);
|
|||
|
Status = XmEmulateFarCall(Segment, Offset, Context);
|
|||
|
if (Status != XM_SUCCESS) {
|
|||
|
DbgPrint("HAL: Adapter initialization falied, status %lx\n", Status);
|
|||
|
}
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
XM_STATUS
|
|||
|
x86BiosInitializeAdapterShadowedPci(
|
|||
|
IN ULONG Adapter,
|
|||
|
IN OUT PXM86_CONTEXT Context OPTIONAL,
|
|||
|
IN PVOID BiosIoSpace OPTIONAL,
|
|||
|
IN PVOID BiosIoMemory OPTIONAL,
|
|||
|
IN PVOID BiosFrameBuffer OPTIONAL,
|
|||
|
IN UCHAR NumberPciBusses,
|
|||
|
IN PGETSETPCIBUSDATA GetPciData,
|
|||
|
IN PGETSETPCIBUSDATA SetPciData
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function initializes the adapter whose BIOS starts at the
|
|||
|
specified 20-bit address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Adpater - Supplies the 20-bit address of the BIOS for the adapter
|
|||
|
to be initialized.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The emulation completion status.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Enable PCI BIOS support.
|
|||
|
//
|
|||
|
|
|||
|
XmPciBiosPresent = TRUE;
|
|||
|
XmGetPciData = GetPciData;
|
|||
|
XmSetPciData = SetPciData;
|
|||
|
XmNumberPciBusses = NumberPciBusses;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the specified adapter.
|
|||
|
//
|
|||
|
|
|||
|
return x86BiosInitializeAdapterShadowed(Adapter,
|
|||
|
Context,
|
|||
|
BiosIoSpace,
|
|||
|
BiosIoMemory,
|
|||
|
BiosFrameBuffer);
|
|||
|
}
|