|
|
/*++
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_
|