177 lines
4.2 KiB
C
177 lines
4.2 KiB
C
|
||
/*++
|
||
|
||
Copyright (c) 1990, 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
hwpmbiosc.c
|
||
|
||
Abstract:
|
||
|
||
This modules contains ACPI BIOS C supporting routines
|
||
|
||
Author:
|
||
|
||
Jake Oshins (jakeo) 6-Feb-1997
|
||
|
||
Environment:
|
||
|
||
Real mode.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "hwdetect.h"
|
||
#include <string.h>
|
||
#include "acpibios.h"
|
||
|
||
|
||
BOOLEAN
|
||
HwGetAcpiBiosData(
|
||
IN FPUCHAR *Configuration,
|
||
OUT PUSHORT Length
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine checks to see if an ACPI BIOS is present. If it is,
|
||
then it returns the ACPI Root System Description Pointer.
|
||
|
||
Arguments:
|
||
|
||
Configuration - structure that holds ACPI pointer
|
||
Length - length of that structure
|
||
|
||
Return Value:
|
||
|
||
TRUE if ACPI BIOS is present, FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
ULONG romAddr, romEnd;
|
||
FPUCHAR current;
|
||
FPULONG EbdaAddr;
|
||
FPACPI_BIOS_INSTALLATION_CHECK header;
|
||
UCHAR sum, node = 0;
|
||
USHORT i, nodeSize;
|
||
enum PASS { PASS1 = 0, PASS2, MAX_PASSES } pass;
|
||
|
||
//
|
||
// Search on 16 byte boundaries for the signature of the
|
||
// Root System Description Table structure.
|
||
//
|
||
#if defined(NEC_98)
|
||
//
|
||
// PC98, we search (physical) memory from 0xE8000
|
||
// to 0xFFFFF.
|
||
|
||
MAKE_FP(current, 0xE8000);
|
||
romAddr = 0xE8000;
|
||
romEnd = ACPI_BIOS_END;
|
||
#else
|
||
for (pass = PASS1; pass < MAX_PASSES; pass++) {
|
||
|
||
if (pass == PASS1) {
|
||
//
|
||
// On the first pass, we search the first 1K of the
|
||
// Extended BIOS data area.
|
||
//
|
||
|
||
//
|
||
// Earlier, we stored the address of the EBDA in address
|
||
// DOS_BEGIN_SEGMENT << 4 : EBIOS_INFO_OFFSET
|
||
//
|
||
MAKE_FP(EbdaAddr, ((DOS_BEGIN_SEGMENT << 4) + EBIOS_INFO_OFFSET));
|
||
MAKE_FP(current, *EbdaAddr);
|
||
|
||
if (*EbdaAddr == 0) {
|
||
continue;
|
||
}
|
||
|
||
romAddr = *EbdaAddr;
|
||
romEnd = romAddr + 1024;
|
||
|
||
} else {
|
||
//
|
||
// On the second pass, we search (physical) memory 0xE0000
|
||
// to 0xF0000.
|
||
|
||
MAKE_FP(current, ACPI_BIOS_START);
|
||
romAddr = ACPI_BIOS_START;
|
||
romEnd = ACPI_BIOS_END;
|
||
}
|
||
#endif
|
||
|
||
while (romAddr < romEnd) {
|
||
|
||
header = (FPACPI_BIOS_INSTALLATION_CHECK)current;
|
||
|
||
//
|
||
// Signature to match is the string "RSD PTR".
|
||
//
|
||
if (header->Signature[0] == 'R' && header->Signature[1] == 'S' &&
|
||
header->Signature[2] == 'D' && header->Signature[3] == ' ' &&
|
||
header->Signature[4] == 'P' && header->Signature[5] == 'T' &&
|
||
header->Signature[6] == 'R' && header->Signature[7] == ' ' ) {
|
||
|
||
sum = 0;
|
||
for (i = 0; i < sizeof(ACPI_BIOS_INSTALLATION_CHECK); i++) {
|
||
sum += current[i];
|
||
}
|
||
if (sum == 0) {
|
||
pass = MAX_PASSES; // leave 'for' loop
|
||
break; // leave 'while' loop
|
||
}
|
||
#if DBG
|
||
BlPrint("GetAcpiBiosData: Checksum fails\n");
|
||
#endif
|
||
}
|
||
romAddr += ACPI_BIOS_HEADER_INCREMENT;
|
||
MAKE_FP(current, romAddr);
|
||
}
|
||
#if defined(NEC_98)
|
||
#else
|
||
}
|
||
#endif
|
||
if (romAddr >= romEnd) {
|
||
#if DBG
|
||
BlPrint("GetAcpiBiosData: RSDT pointer not found\n");
|
||
#endif
|
||
return FALSE;
|
||
}
|
||
|
||
nodeSize = sizeof(ACPI_BIOS_INSTALLATION_CHECK) + DATA_HEADER_SIZE;
|
||
current = (FPUCHAR) HwAllocateHeap(nodeSize, FALSE);
|
||
if (!current) {
|
||
#if DBG
|
||
BlPrint("GetAcpiBiosData: Out of heap space.\n");
|
||
#endif
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Collect ACPI Bios installation check data and device node data.
|
||
//
|
||
|
||
_fmemcpy (current + DATA_HEADER_SIZE,
|
||
(FPUCHAR)header,
|
||
sizeof(ACPI_BIOS_INSTALLATION_CHECK)
|
||
);
|
||
|
||
*Configuration = current;
|
||
*Length = nodeSize;
|
||
|
||
#if DBG
|
||
BlPrint("ACPI BIOS found at 0x%x:%x. RdstAddress is 0x%x:%x\n",
|
||
(USHORT)(romAddr >> 16),
|
||
(USHORT)(romAddr),
|
||
(USHORT)(header->RsdtAddress >> 16),
|
||
(USHORT)(header->RsdtAddress)
|
||
);
|
||
#endif
|
||
return TRUE;
|
||
}
|