/*++ 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 #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; }