reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c
2019-08-31 01:42:40 +02:00

123 lines
3.7 KiB
C

/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <freeldr.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(HWDETECT);
BOOLEAN AcpiPresent = FALSE;
static PRSDP_DESCRIPTOR
FindAcpiBios(VOID)
{
PUCHAR Ptr;
/* Find the 'Root System Descriptor Table Pointer' */
Ptr = (PUCHAR)0xE0000;
while ((ULONG_PTR)Ptr < 0x100000)
{
if (!memcmp(Ptr, "RSD PTR ", 8))
{
TRACE("ACPI supported\n");
return (PRSDP_DESCRIPTOR)Ptr;
}
Ptr = (PUCHAR)((ULONG_PTR)Ptr + 0x10);
}
TRACE("ACPI not supported\n");
return NULL;
}
VOID
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
PCONFIGURATION_COMPONENT_DATA BiosKey;
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PRSDP_DESCRIPTOR Rsdp;
PACPI_BIOS_DATA AcpiBiosData;
ULONG TableSize;
Rsdp = FindAcpiBios();
if (Rsdp)
{
/* Set up the flag in the loader block */
AcpiPresent = TRUE;
/* Calculate the table size */
TableSize = PcBiosMapCount * sizeof(BIOS_MEMORY_MAP) +
sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP);
/* Set 'Configuration Data' value */
PartialResourceList =
FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize,
TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate resource descriptor\n");
return;
}
memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
PartialResourceList->Version = 0;
PartialResourceList->Revision = 0;
PartialResourceList->Count = 1;
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize;
/* Fill the table */
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
AcpiBiosData->Count = PcBiosMapCount;
memcpy(AcpiBiosData->MemoryMap, PcBiosMemoryMap,
PcBiosMapCount * sizeof(BIOS_MEMORY_MAP));
TRACE("RSDT %p, data size %x\n", Rsdp->rsdt_physical_address,
TableSize);
/* Create new bus key */
FldrCreateComponentKey(SystemKey,
AdapterClass,
MultiFunctionAdapter,
0x0,
0x0,
0xFFFFFFFF,
"ACPI BIOS",
PartialResourceList,
sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize,
&BiosKey);
/* Increment bus number */
(*BusNumber)++;
}
}
/* EOF */