351 lines
8.1 KiB
C
351 lines
8.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1998 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
GbAcpi.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Temporary support for Acpi tables in Gambit simulator environment. This
|
|||
|
file should be removed when Gambit/Vpc provides Acpi tables.
|
|||
|
|
|||
|
The Acpi tables are created and a pointer to the RSDT is put into the
|
|||
|
Loader block.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Todd Kjos (HP) (v-tkjos) 1-Jun-1998
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "halp.h"
|
|||
|
#include "acpitabl.h"
|
|||
|
#include "xxacpi.h"
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
HalpOpenRegistryKey(
|
|||
|
OUT PHANDLE Handle,
|
|||
|
IN HANDLE BaseHandle OPTIONAL,
|
|||
|
IN PUNICODE_STRING KeyName,
|
|||
|
IN ACCESS_MASK DesiredAccess,
|
|||
|
IN BOOLEAN Create
|
|||
|
);
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpFakeAcpiRegisters(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
#define PMIO 0x8000
|
|||
|
#define PM1a_EVT_BLK (PMIO+0x0)
|
|||
|
#define PM1a_STS PM1a_EVT_BLK
|
|||
|
#define PM1a_EN (PM1a_STS+2)
|
|||
|
|
|||
|
#define PM1a_CNT_BLK (PMIO+0x4)
|
|||
|
#define PM1a_CNTa PM1a_CNT_BLK
|
|||
|
|
|||
|
#define PM_TMR (PMIO+0x8)
|
|||
|
#define GP0 (PMIO+0xc)
|
|||
|
#define GP0_STS_0 GP0
|
|||
|
#define GP0_STS_1 (GP0+1)
|
|||
|
#define GP0_EN_0 (GP0+2)
|
|||
|
#define GP0_EN_1 (GP0+3)
|
|||
|
|
|||
|
PCHAR HalpFakeAcpiRegisterFadtIds[][2] =
|
|||
|
{
|
|||
|
{"INTEL", "LIONEMU"},
|
|||
|
{"INTEL", "SR460AC"},
|
|||
|
{"INTEL", "AL460GX"},
|
|||
|
{NULL, NULL}
|
|||
|
};
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE, HalpFakeAcpiRegisters)
|
|||
|
#endif
|
|||
|
|
|||
|
USHORT AcpiRegPM1a_STS = 0;
|
|||
|
USHORT AcpiRegPM1a_EN = 0;
|
|||
|
USHORT AcpiRegPM1_CNTa = 1; // SCI_EN
|
|||
|
ULONG AcpiRegPM_TMR = 0;
|
|||
|
UCHAR AcpiRegGP0_STS_0 = 0;
|
|||
|
UCHAR AcpiRegGP0_STS_1 = 0;
|
|||
|
UCHAR AcpiRegGP0_EN_0 = 0;
|
|||
|
UCHAR AcpiRegGP0_EN_1 = 0;
|
|||
|
UCHAR AcpiRegNeedToImplement = 0;
|
|||
|
|
|||
|
BOOLEAN GambitAcpiDebug = FALSE;
|
|||
|
|
|||
|
//#define TKPRINT(X,Y) if (GambitAcpiDebug) HalDebugPrint(( HAL_INFO, "%s of %s (%#x)\n",X,# Y,Y ))
|
|||
|
#define TKPRINT(x, y)
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
GbAcpiReadFakePort(
|
|||
|
UINT_PTR Port,
|
|||
|
PVOID Data,
|
|||
|
ULONG Length
|
|||
|
)
|
|||
|
{
|
|||
|
if (Port < PMIO || Port > PMIO+0xfff) return(FALSE);
|
|||
|
|
|||
|
switch (Port) {
|
|||
|
case PM1a_STS:
|
|||
|
ASSERT(Length == 2);
|
|||
|
*(USHORT UNALIGNED *)Data = AcpiRegPM1a_STS;
|
|||
|
TKPRINT("Read",AcpiRegPM1a_STS);
|
|||
|
return TRUE;
|
|||
|
case PM1a_EN:
|
|||
|
ASSERT(Length == 2);
|
|||
|
*(USHORT UNALIGNED *)Data = AcpiRegPM1a_EN;
|
|||
|
TKPRINT("Read",AcpiRegPM1a_EN);
|
|||
|
return TRUE;
|
|||
|
case PM1a_CNTa:
|
|||
|
ASSERT(Length == 2);
|
|||
|
*(USHORT UNALIGNED *)Data = AcpiRegPM1_CNTa;
|
|||
|
TKPRINT("Read",AcpiRegPM1_CNTa);
|
|||
|
return TRUE;
|
|||
|
case PM_TMR:
|
|||
|
ASSERT(Length == 4);
|
|||
|
*(ULONG UNALIGNED *)Data = AcpiRegPM_TMR;
|
|||
|
TKPRINT("Read",AcpiRegPM_TMR);
|
|||
|
return TRUE;
|
|||
|
case GP0_STS_0:
|
|||
|
ASSERT(Length == 1);
|
|||
|
*(UCHAR UNALIGNED *)Data = AcpiRegGP0_STS_0;
|
|||
|
TKPRINT("Read",AcpiRegGP0_STS_0);
|
|||
|
return TRUE;
|
|||
|
case GP0_STS_1:
|
|||
|
ASSERT(Length == 1);
|
|||
|
*(UCHAR UNALIGNED *)Data = AcpiRegGP0_STS_1;
|
|||
|
TKPRINT("Read",AcpiRegGP0_STS_1);
|
|||
|
return TRUE;
|
|||
|
case GP0_EN_0:
|
|||
|
ASSERT(Length == 1);
|
|||
|
*(UCHAR UNALIGNED *)Data = AcpiRegGP0_EN_0;
|
|||
|
TKPRINT("Read",AcpiRegGP0_EN_0);
|
|||
|
return TRUE;
|
|||
|
case GP0_EN_1:
|
|||
|
ASSERT(Length == 1);
|
|||
|
*(UCHAR UNALIGNED *)Data = AcpiRegGP0_EN_1;
|
|||
|
TKPRINT("Read",AcpiRegGP0_EN_1);
|
|||
|
return TRUE;
|
|||
|
case 0x802b:
|
|||
|
ASSERT(Length == 1);
|
|||
|
*(UCHAR UNALIGNED *)Data = AcpiRegNeedToImplement;
|
|||
|
TKPRINT("Read",AcpiRegNeedToImplement);
|
|||
|
return TRUE;
|
|||
|
default:
|
|||
|
;
|
|||
|
// HalDebugPrint(( HAL_ERROR, "HAL: AcpiSimulation - Unknown Acpi register: %#Ix\n", Port ));
|
|||
|
// ASSERT(0);
|
|||
|
}
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
GbAcpiWriteFakePort(
|
|||
|
UINT_PTR Port,
|
|||
|
PVOID Value,
|
|||
|
ULONG Length
|
|||
|
)
|
|||
|
{
|
|||
|
if (Port < PMIO || Port > PMIO+0xfff) return(FALSE);
|
|||
|
|
|||
|
switch (Port) {
|
|||
|
case PM1a_STS:
|
|||
|
ASSERT(Length == 2);
|
|||
|
AcpiRegPM1a_STS &= ~(*(USHORT UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegPM1a_STS);
|
|||
|
return TRUE;
|
|||
|
case PM1a_EN:
|
|||
|
ASSERT(Length == 2);
|
|||
|
AcpiRegPM1a_EN = *((USHORT UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegPM1a_EN);
|
|||
|
return TRUE;
|
|||
|
case PM1a_CNTa:
|
|||
|
ASSERT(Length == 2);
|
|||
|
AcpiRegPM1_CNTa = *((USHORT UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegPM1_CNTa);
|
|||
|
return TRUE;
|
|||
|
case PM_TMR:
|
|||
|
ASSERT(Length == 4);
|
|||
|
AcpiRegPM_TMR = *((ULONG UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegPM_TMR);
|
|||
|
return TRUE;
|
|||
|
case GP0_STS_0:
|
|||
|
ASSERT(Length == 1);
|
|||
|
AcpiRegGP0_STS_0 &= ~(*(UCHAR UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegGP0_STS_0);
|
|||
|
return TRUE;
|
|||
|
case GP0_STS_1:
|
|||
|
ASSERT(Length == 1);
|
|||
|
AcpiRegGP0_STS_1 &= ~(*(UCHAR UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegGP0_STS_1);
|
|||
|
return TRUE;
|
|||
|
case GP0_EN_0:
|
|||
|
ASSERT(Length == 1);
|
|||
|
AcpiRegGP0_EN_0 = *((UCHAR UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegGP0_EN_0);
|
|||
|
return TRUE;
|
|||
|
case GP0_EN_1:
|
|||
|
ASSERT(Length == 1);
|
|||
|
AcpiRegGP0_EN_1 = *((UCHAR UNALIGNED *)Value);
|
|||
|
TKPRINT("Write",AcpiRegGP0_EN_1);
|
|||
|
return TRUE;
|
|||
|
default:
|
|||
|
;
|
|||
|
// HalDebugPrint(( HAL_ERROR, "HAL: AcpiSimulation - Unknown Acpi register: %#Ix\n",Port ));
|
|||
|
// ASSERT(0);
|
|||
|
}
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
USHORT
|
|||
|
HalpReadAcpiRegister(
|
|||
|
IN ACPI_REG_TYPE AcpiReg,
|
|||
|
IN ULONG Register
|
|||
|
)
|
|||
|
{
|
|||
|
USHORT value;
|
|||
|
BOOLEAN retVal = FALSE;
|
|||
|
|
|||
|
switch (AcpiReg) {
|
|||
|
case PM1a_ENABLE:
|
|||
|
|
|||
|
retVal = GbAcpiReadFakePort(PM1a_EN, &value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case PM1a_STATUS:
|
|||
|
|
|||
|
retVal = GbAcpiReadFakePort(PM1a_STS, &value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case PM1a_CONTROL:
|
|||
|
|
|||
|
retVal = GbAcpiReadFakePort(PM1a_CNTa, &value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case GP_STATUS:
|
|||
|
|
|||
|
retVal = GbAcpiReadFakePort(GP0_STS_0, &value, 1);
|
|||
|
if (!retVal) break;
|
|||
|
retVal = GbAcpiReadFakePort(GP0_STS_1, ((PUCHAR)&value) + 1, 1);
|
|||
|
break;
|
|||
|
|
|||
|
case GP_ENABLE:
|
|||
|
|
|||
|
retVal = GbAcpiReadFakePort(GP0_EN_0, &value, 1);
|
|||
|
if (!retVal) break;
|
|||
|
retVal = GbAcpiReadFakePort(GP0_EN_1, ((PUCHAR)&value) + 1, 1);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (retVal) {
|
|||
|
|
|||
|
return value;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return 0xffff;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
HalpWriteAcpiRegister(
|
|||
|
IN ACPI_REG_TYPE AcpiReg,
|
|||
|
IN ULONG Register,
|
|||
|
IN USHORT Value
|
|||
|
)
|
|||
|
{
|
|||
|
BOOLEAN retVal = FALSE;
|
|||
|
|
|||
|
switch (AcpiReg) {
|
|||
|
case PM1a_ENABLE:
|
|||
|
|
|||
|
retVal = GbAcpiWriteFakePort(PM1a_EN, &Value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case PM1a_STATUS:
|
|||
|
|
|||
|
retVal = GbAcpiWriteFakePort(PM1a_STS, &Value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case PM1a_CONTROL:
|
|||
|
|
|||
|
retVal = GbAcpiWriteFakePort(PM1a_CNTa, &Value, 2);
|
|||
|
break;
|
|||
|
|
|||
|
case GP_STATUS:
|
|||
|
|
|||
|
retVal = GbAcpiWriteFakePort(GP0_STS_0, &Value, 1);
|
|||
|
if (!retVal) break;
|
|||
|
retVal = GbAcpiWriteFakePort(GP0_STS_1, ((PUCHAR)&Value) + 1, 1);
|
|||
|
break;
|
|||
|
|
|||
|
case GP_ENABLE:
|
|||
|
|
|||
|
switch (Register) {
|
|||
|
case 0:
|
|||
|
retVal = GbAcpiWriteFakePort(GP0_EN_0, &Value, 1);
|
|||
|
break;
|
|||
|
case 1:
|
|||
|
retVal = GbAcpiWriteFakePort(GP0_EN_1, ((PUCHAR)&Value) + 1, 1);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpFakeAcpiRegisters(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG i = 0;
|
|||
|
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
while (HalpFakeAcpiRegisterFadtIds[i][0] != NULL) {
|
|||
|
|
|||
|
//DbgPrint("Comparing [%s]-[%s] to [%s]-[%s]\n",
|
|||
|
// HalpFixedAcpiDescTable.Header.OEMID,
|
|||
|
// HalpFixedAcpiDescTable.Header.OEMTableID,
|
|||
|
// HalpFakeAcpiRegisterFadtIds[i][0],
|
|||
|
// HalpFakeAcpiRegisterFadtIds[i][1]);
|
|||
|
|
|||
|
if ((!strncmp(HalpFixedAcpiDescTable.Header.OEMID,
|
|||
|
HalpFakeAcpiRegisterFadtIds[i][0],
|
|||
|
6)) &&
|
|||
|
(!strncmp(HalpFixedAcpiDescTable.Header.OEMTableID,
|
|||
|
HalpFakeAcpiRegisterFadtIds[i][1],
|
|||
|
8))) {
|
|||
|
|
|||
|
//
|
|||
|
// This machine matches one of the entries
|
|||
|
// in the table that tells us that we should fake
|
|||
|
// our ACPI registers.
|
|||
|
//
|
|||
|
|
|||
|
//DbgPrint("Found a match\n");
|
|||
|
//
|
|||
|
// Make sure the oem revision is less than 3.
|
|||
|
// Then we need to fake the acpi registers
|
|||
|
//
|
|||
|
if(HalpFixedAcpiDescTable.Header.OEMRevision < 3)
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
i++;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|