221 lines
4.3 KiB
C
221 lines
4.3 KiB
C
/*++
|
||
|
||
Copyright (c) 1998 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
fakeacpi.c
|
||
|
||
Abstract:
|
||
|
||
Temporary support for Acpi tables in SIMICS simulator environment. This
|
||
file should be removed when SIMICS provides Acpi tables.
|
||
|
||
Author:
|
||
|
||
Forrest Foltz (forrestf) 04-02-2001
|
||
|
||
Environment:
|
||
|
||
Kernel mode only.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#if defined(_AMD64_SIMULATOR_)
|
||
|
||
#include "halcmn.h"
|
||
|
||
typedef struct _FAKE_ACPI_PORT_DESC {
|
||
ACPI_REG_TYPE AcpiReg;
|
||
USHORT PortSize;
|
||
USHORT BlockSize;
|
||
BOOLEAN Mask;
|
||
ULONG Data;
|
||
PUCHAR IoPortName;
|
||
} FAKE_ACPI_PORT_DESC, *PFAKE_ACPI_PORT_DESC;
|
||
|
||
#define FPE(p,r,s,b,d) { p, r, s, b, d, #p }
|
||
|
||
FAKE_ACPI_PORT_DESC HalpFakePortDescriptions[] = {
|
||
FPE( PM1a_ENABLE, 2, 2, FALSE, 1 ),
|
||
FPE( PM1b_ENABLE, 2, 2, FALSE, 0 ),
|
||
FPE( PM1a_STATUS, 2, 2, TRUE, 0 ),
|
||
FPE( PM1b_STATUS, 2, 2, TRUE, 0 ),
|
||
FPE( PM1a_CONTROL, 2, 2, FALSE, 0 ),
|
||
FPE( PM1b_CONTROL, 2, 2, FALSE, 0 ),
|
||
FPE( GP_STATUS, 1, 2, TRUE, 0 ),
|
||
FPE( GP_ENABLE, 1, 2, FALSE, 0 ),
|
||
FPE( SMI_CMD, 1, 1, FALSE, 0 )
|
||
};
|
||
|
||
#if DBG
|
||
BOOLEAN HalpDebugFakeAcpi = FALSE;
|
||
#else
|
||
#define HalpDebugFakeAcpi FALSE
|
||
#endif
|
||
|
||
|
||
PFAKE_ACPI_PORT_DESC
|
||
HalpFindFakeAcpiPortDesc (
|
||
ACPI_REG_TYPE AcpiReg
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Locates the FAKE_ACPI_PORT_DESC structure appropriate to the
|
||
supplied AcpiReg.
|
||
|
||
Arguments:
|
||
|
||
AcpiReg - Specifies which ACPI fixed register to find the structure for.
|
||
|
||
Return Value:
|
||
|
||
Returns a pointer to the appropriate FAKE_ACPI_PORT_DESC structure if
|
||
it was found, or NULL otherwise.
|
||
|
||
--*/
|
||
{
|
||
ULONG i;
|
||
PFAKE_ACPI_PORT_DESC portDesc;
|
||
|
||
for (i = 0; i < RTL_NUMBER_OF(HalpFakePortDescriptions); i += 1) {
|
||
portDesc = &HalpFakePortDescriptions[i];
|
||
if (portDesc->AcpiReg == AcpiReg) {
|
||
return portDesc;
|
||
}
|
||
}
|
||
|
||
DbgPrint("AMD64: Need to emulate ACPI I/O port 0x%x\n",AcpiReg);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
USHORT
|
||
HalpReadAcpiRegister (
|
||
IN ACPI_REG_TYPE AcpiReg,
|
||
IN ULONG Register
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Read from the specified ACPI fixed register.
|
||
|
||
Arguments:
|
||
|
||
AcpiReg - Specifies which ACPI fixed register to read from.
|
||
|
||
Register - Specifies which GP register to read from. Not used for PM1x
|
||
registers.
|
||
|
||
Return Value:
|
||
|
||
Value of the specified ACPI fixed register.
|
||
|
||
--*/
|
||
{
|
||
PFAKE_ACPI_PORT_DESC portDesc;
|
||
PUCHAR source;
|
||
USHORT retVal;
|
||
|
||
portDesc = HalpFindFakeAcpiPortDesc(AcpiReg);
|
||
if (portDesc == NULL) {
|
||
return 0xffff;
|
||
}
|
||
|
||
ASSERT((Register + portDesc->PortSize) <= portDesc->BlockSize);
|
||
|
||
source = (PUCHAR)&portDesc->Data + Register;
|
||
retVal = 0;
|
||
|
||
RtlCopyMemory((PUCHAR)&retVal, source, portDesc->PortSize);
|
||
|
||
if (HalpDebugFakeAcpi != FALSE) {
|
||
DbgPrint("HalpReadAcpiRegister(%s,0x%x) returns 0x%x\n",
|
||
portDesc->IoPortName,
|
||
Register,
|
||
retVal);
|
||
}
|
||
|
||
return retVal;
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpWriteAcpiRegister (
|
||
IN ACPI_REG_TYPE AcpiReg,
|
||
IN ULONG Register,
|
||
IN USHORT Value
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Write to the specified ACPI fixed register.
|
||
|
||
Arguments:
|
||
|
||
AcpiReg - Specifies which ACPI fixed register to write to.
|
||
|
||
Register - Specifies which GP register to write to. Not used for PM1x
|
||
registers.
|
||
|
||
Value - Data to write.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFAKE_ACPI_PORT_DESC portDesc;
|
||
PUCHAR source;
|
||
PUCHAR destination;
|
||
ULONG i;
|
||
|
||
portDesc = HalpFindFakeAcpiPortDesc(AcpiReg);
|
||
if (portDesc == NULL) {
|
||
return;
|
||
}
|
||
|
||
ASSERT((Register + portDesc->PortSize) <= portDesc->BlockSize);
|
||
|
||
source = (PUCHAR)&Value;
|
||
destination = (PUCHAR)&portDesc->Data + Register;
|
||
|
||
if (HalpDebugFakeAcpi != FALSE) {
|
||
DbgPrint("HalpWriteAcpiRegister(%s,0x%x) with value 0x%x\n",
|
||
portDesc->IoPortName,
|
||
Register,
|
||
Value);
|
||
}
|
||
|
||
for (i = 0; i < portDesc->PortSize; i++) {
|
||
|
||
if (portDesc->Mask != FALSE) {
|
||
*destination &= ~(*source);
|
||
} else {
|
||
*destination = *source;
|
||
}
|
||
|
||
source += 1;
|
||
destination += 1;
|
||
}
|
||
|
||
if (AcpiReg == SMI_CMD && Register == 0) {
|
||
|
||
//
|
||
// Assume that we have just turned ACPI on.
|
||
//
|
||
|
||
HalpFindFakeAcpiPortDesc(PM1a_CONTROL)->Data |= 1;
|
||
}
|
||
}
|
||
|
||
#endif // _AMD64_SIMULATOR_
|