23 #include "../../core/processor/x86_common/PhysicalMemoryManager.h" 24 #include "pedigree/kernel/Log.h" 25 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 26 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 27 #include "pedigree/kernel/utilities/RangeList.h" 28 #include "pedigree/kernel/utilities/utility.h" 30 Acpi Acpi::m_Instance;
32 void Acpi::initialise()
37 WARNING(
"Acpi: not compliant to the ACPI Specification");
41 NOTICE(
"ACPI Specification");
43 " RSDT pointer at " <<
Hex 44 << reinterpret_cast<uintptr_t>(m_pRsdtPointer));
47 if (m_pRsdtPointer->revision >= 2)
49 if (m_pRsdtPointer->xsdtAddress != 0)
51 NOTICE(
" XSDT at " <<
Hex << m_pRsdtPointer->xsdtAddress);
55 NOTICE(
" RSDT at " <<
Hex << m_pRsdtPointer->rsdtAddress);
61 physicalMemoryManager.getAcpiRanges();
62 if (AcpiRanges.
size() == 0)
64 ERROR(
"Acpi: No ACPI memory range");
67 if (AcpiRanges.
size() > 1)
69 ERROR(
"Acpi: More than one ACPI memory range");
75 physical_uintptr_t address =
77 size_t sAddress = AcpiRange.length + (AcpiRange.address - address);
81 m_AcpiMemoryRegion, nPages,
88 ERROR(
"Acpi: Could not allocate the MemoryRegion");
94 m_AcpiMemoryRegion.convertPhysicalPointer<SystemDescriptionTableHeader>(
95 m_pRsdtPointer->rsdtAddress);
96 if (m_pRsdt->signature != 0x54445352 || checksum(m_pRsdt) !=
true)
98 ERROR(
"Acpi: RSDT invalid");
105 (m_pRsdt->length -
sizeof(SystemDescriptionTableHeader)) / 4;
106 for (
size_t i = 0; i < sEntries; i++)
108 uint32_t *pTable = adjust_pointer(
109 reinterpret_cast<uint32_t *>(m_pRsdt),
110 sizeof(SystemDescriptionTableHeader) + 4 * i);
112 SystemDescriptionTableHeader *pSystemDescTable =
114 .convertPhysicalPointer<SystemDescriptionTableHeader>(*pTable);
118 Signature, reinterpret_cast<char *>(&pSystemDescTable->signature),
122 NOTICE(
" " << Signature <<
" at " <<
Hex << *pTable);
125 if (checksum(pSystemDescTable) !=
true)
132 if (pSystemDescTable->signature == 0x50434146)
134 reinterpret_cast<FixedACPIDescriptionTable *
>(pSystemDescTable);
137 else if (pSystemDescTable->signature == 0x43495041)
138 m_pApic = pSystemDescTable;
149 ERROR(
"Acpi: no Fixed ACPI Description Table (FACP)");
154 parseFixedACPIDescriptionTable();
159 parseMultipleApicDescriptionTable();
166 : m_bValid(0), m_pRsdtPointer(0), m_AcpiMemoryRegion(
"ACPI"), m_pRsdt(0),
170 m_pApic(0), m_bValidApicInfo(false), m_bHasPICs(false),
171 m_LocalApicAddress(0), m_IoApics()
172 #if defined(MULTIPROCESSOR)
174 m_bValidProcessorInfo(false), m_Processors()
180 void Acpi::parseFixedACPIDescriptionTable()
182 NOTICE(
"ACPI: Fixed Description Table (FACP)");
185 " Firmware ACPI Control Structure at " <<
Hex 186 << m_pFacp->firmwareControl);
188 " Differentiated System Description Table at " <<
Hex << m_pFacp->dsdt);
190 " Interrupt Model: " <<
Dec 191 << ((m_pFacp->interruptModel == 0) ?
193 "multiple local APICs"));
194 NOTICE(
" SCI Interrupt #" <<
Dec << m_pFacp->sciInterrupt);
195 NOTICE(
" SMI Command Port at " <<
Hex << m_pFacp->smiCommandPort);
196 NOTICE(
" enable " <<
Hex << m_pFacp->acpiEnableCommand);
197 NOTICE(
" disable " <<
Hex << m_pFacp->acpiDisableCommand);
198 if (m_pFacp->s4BiosCommand != 0)
200 NOTICE(
" S4 BIOS " <<
Hex << m_pFacp->s4BiosCommand);
202 NOTICE(
" Power-Management");
204 " Event 1A at " <<
Hex << m_pFacp->pm1aEventBlock <<
" - " 205 << (m_pFacp->pm1aEventBlock +
206 m_pFacp->pm1EventLength));
207 if (m_pFacp->pm1bEventBlock != 0)
211 <<
Hex << m_pFacp->pm1bEventBlock <<
" - " 212 << (m_pFacp->pm1bEventBlock + m_pFacp->pm1EventLength));
215 " Control 1A at " <<
Hex << m_pFacp->pm1aControlBlock <<
" - " 216 << (m_pFacp->pm1aControlBlock +
217 m_pFacp->pm1ControlLength));
218 if (m_pFacp->pm1bControlBlock != 0)
222 <<
Hex << m_pFacp->pm1bControlBlock <<
" - " 223 << (m_pFacp->pm1bControlBlock + m_pFacp->pm1ControlLength));
225 if (m_pFacp->pm2ControlBlock != 0)
229 <<
Hex << m_pFacp->pm2ControlBlock <<
" - " 230 << (m_pFacp->pm2ControlBlock + m_pFacp->pm2ControlLength));
233 " Timer at " <<
Hex << m_pFacp->pmTimerBlock <<
" - " 234 << (m_pFacp->pmTimerBlock + m_pFacp->pmTimerLength));
235 if (m_pFacp->gpe0Block != 0)
238 " General Purpose Event 0 at " 239 <<
Hex << m_pFacp->gpe0Block <<
" - " 240 << (m_pFacp->gpe0Block + m_pFacp->gpe0BlockLength));
242 if (m_pFacp->gpe1Block != 0)
245 " General Purpose Event 1 at " 246 <<
Hex << m_pFacp->gpe1Block <<
" - " 247 << (m_pFacp->gpe1Block + m_pFacp->gpe1BlockLength));
249 if (m_pFacp->gpe1Base != 0)
251 NOTICE(
" General Purpose Event Base: " <<
Hex << m_pFacp->gpe1Base);
254 NOTICE(
" Flags " <<
Hex << m_pFacp->flags);
258 void Acpi::parseMultipleApicDescriptionTable()
260 NOTICE(
"ACPI: Multiple APIC Description Table (APIC)");
263 uint32_t *pLocalApicAddress =
reinterpret_cast<uint32_t *
>(
264 adjust_pointer(m_pApic,
sizeof(SystemDescriptionTableHeader)));
265 uint32_t *pFlags = adjust_pointer(pLocalApicAddress, 4);
267 m_LocalApicAddress = *pLocalApicAddress;
268 m_bHasPICs = (((*pFlags) & 0x01) == 0x01);
270 uint8_t *pType =
reinterpret_cast<uint8_t *
>(adjust_pointer(pFlags, 4));
271 for (; pType < reinterpret_cast<uint8_t *>(
272 adjust_pointer(m_pApic, m_pApic->length));)
277 ProcessorLocalApic *pLocalApic =
278 reinterpret_cast<ProcessorLocalApic *
>(
279 adjust_pointer(pType, 2));
280 bool bUsable = ((pLocalApic->flags & 0x01) == 0x01);
282 " Processor #" <<
Dec << pLocalApic->processorId
283 << (bUsable ?
" usable" :
" unusable"));
285 #if defined(MULTIPROCESSOR) 292 pLocalApic->processorId, pLocalApic->apicId);
293 m_Processors.pushBack(pProcessorInfo);
298 else if (*pType == 1)
301 reinterpret_cast<IoApic *
>(adjust_pointer(pType, 2));
304 " I/O APIC #" <<
Dec << pIoApic->apicId <<
" at " <<
Hex 306 <<
", global system interrupt base " 307 << pIoApic->globalSystemInterruptBase);
314 pIoApic->apicId, pIoApic->address);
315 m_IoApics.pushBack(pIoApicInfo);
318 else if (*pType == 2)
320 InterruptSourceOverride *pInterruptSourceOverride =
321 reinterpret_cast<InterruptSourceOverride *
>(
322 adjust_pointer(pType, 2));
325 " Interrupt override: " 326 << ((pInterruptSourceOverride->bus == 0) ?
"ISA" :
"unknown")
327 <<
" bus, #" <<
Dec << pInterruptSourceOverride->source
328 <<
" -> #" << pInterruptSourceOverride->globalSystemInterrupt
329 <<
", flags " <<
Hex << pInterruptSourceOverride->flags);
334 else if (*pType == 3)
336 ERROR(
" NMI source");
339 else if (*pType == 4)
341 ERROR(
" Local APIC NMI");
344 else if (*pType == 5)
346 ERROR(
" Local APIC address override");
349 else if (*pType == 6)
354 else if (*pType == 7)
356 ERROR(
" Local SAPIC");
359 else if (*pType == 8)
361 ERROR(
" Platform Interrupt Source");
365 NOTICE(
" unknown entry #" <<
Dec << *pType);
369 uint8_t *sTable = adjust_pointer(pType, 1);
370 pType = adjust_pointer(pType, *sTable);
373 m_bValidApicInfo =
true;
374 #if defined(MULTIPROCESSOR) 375 m_bValidProcessorInfo =
true;
383 uint16_t *ebdaSegment =
reinterpret_cast<uint16_t *
>(0x40E);
384 m_pRsdtPointer = find(reinterpret_cast<void *>((*ebdaSegment) * 16), 0x400);
386 if (m_pRsdtPointer == 0)
389 m_pRsdtPointer = find(reinterpret_cast<void *>(0xE0000), 0x20000);
392 return (m_pRsdtPointer != 0);
395 Acpi::RsdtPointer *Acpi::find(
void *pMemory,
size_t sMemory)
397 RsdtPointer *pRdstPointer =
reinterpret_cast<RsdtPointer *
>(pMemory);
398 while (reinterpret_cast<uintptr_t>(pRdstPointer) <
399 (
reinterpret_cast<uintptr_t
>(pMemory) + sMemory))
401 if (pRdstPointer->signature == 0x2052545020445352ULL &&
402 checksum(pRdstPointer) ==
true)
404 pRdstPointer = adjust_pointer(pRdstPointer, 16);
409 bool Acpi::checksum(
const RsdtPointer *pRdstPointer)
412 if (::checksum(reinterpret_cast<const uint8_t *>(pRdstPointer), 20) ==
416 if (pRdstPointer->revision >= 2)
420 reinterpret_cast<const uint8_t *>(pRdstPointer),
421 pRdstPointer->length) ==
false)
428 bool Acpi::checksum(
const SystemDescriptionTableHeader *pHeader)
431 reinterpret_cast<const uint8_t *>(pHeader), pHeader->length);
static X86CommonPhysicalMemoryManager & instance()
static size_t getPageSize() PURE
static const size_t continuous
static const size_t force
Range getRange(size_t index) const
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)
static const size_t Write
static const size_t KernelMode
static const size_t nonRamMemory
Implementation of the PhysicalMemoryManager for common x86.