23 #include "precompiled.h"
30 #define ENABLE_MAHAF 0
65 for(
PCV_u8 p = buf; p < buf+numBytes; p++)
66 sum =
u8((sum + *p) & 0xFF);
79 if(memcmp(table->
signature, signature, 4) != 0)
85 for(
size_t i = 0; i < 4; i++)
89 if(!isalpha(c) && c !=
'_' && c !=
'!')
101 const bool isOemTable = (memcmp(table->
signature,
"OEM", 3) == 0);
122 static void* SUCCEEDED = (
void*)(intptr_t)1;
123 static void* FAILED = (
void*)(intptr_t)-1;
125 typedef void* (*UnsafeFunction)(
PCV_u8 mem,
size_t numBytes,
void* arg);
127 static void* CallWithSafetyBlanket(UnsafeFunction func,
PCV_u8 mem,
size_t numBytes,
void* arg)
132 return func(mem, numBytes, arg);
139 return func(mem, numBytes, arg);
143 static void* TransactPhysicalMemory(uintptr_t physicalAddress,
size_t numBytes, UnsafeFunction func,
void* arg = 0)
148 void* ret = CallWithSafetyBlanket(func, mem, numBytes, arg);
164 typedef const volatile BiosDataArea* PCV_BiosDataArea;
166 static void* UnsafeReadEbdaPhysicalAddress(
PCV_u8 mem,
size_t numBytes,
void*
UNUSED(arg))
168 ENSURE(numBytes >=
sizeof(BiosDataArea));
170 PCV_BiosDataArea bda = (PCV_BiosDataArea)mem;
171 const uintptr_t ebdaPhysicalAddress = ((uintptr_t)bda->ebdaSegment) * 16;
172 return (
void*)ebdaPhysicalAddress;
182 u32 rsdtPhysicalAddress;
185 typedef const volatile RSDP* PCV_RSDP;
187 static const size_t RSDP_ALIGNMENT = 16;
189 static void* UnsafeLocateAndRetrieveRsdp(
PCV_u8 buf,
size_t numBytes,
void* arg)
191 ENSURE(numBytes >=
sizeof(RSDP));
193 for(
PCV_u8 p = buf; p < buf+numBytes; p += RSDP_ALIGNMENT)
195 RSDP* prsdp = (RSDP*)p;
196 if(memcmp(prsdp->signature,
"RSD PTR ", 8) != 0)
201 memcpy(arg, prsdp,
sizeof(RSDP));
208 static bool RetrieveRsdp(RSDP& rsdp)
212 void* ret = TransactPhysicalMemory(0x400, 0x100, UnsafeReadEbdaPhysicalAddress);
215 const uintptr_t ebdaPhysicalAddress = (uintptr_t)ret;
216 ret = TransactPhysicalMemory(ebdaPhysicalAddress, 0x400, UnsafeLocateAndRetrieveRsdp, &rsdp);
222 ret = TransactPhysicalMemory(0xE0000, 0x20000, UnsafeLocateAndRetrieveRsdp, &rsdp);
233 static void* UnsafeAllocateAndCopyTable(
PCV_u8 mem,
size_t numBytes,
void* arg)
238 const size_t tableSize = table->size;
242 if(numBytes < tableSize)
244 memcpy(arg, &tableSize,
sizeof(
size_t));
252 memcpy((
void*)copy, (
const void*)mem, tableSize);
257 static const AcpiTable* AllocateAndCopyTable(uintptr_t physicalAddress)
262 static const size_t initialSize = 4*
KiB;
263 size_t actualSize = 0;
264 void* ret = TransactPhysicalMemory(physicalAddress, initialSize, UnsafeAllocateAndCopyTable, &actualSize);
267 ret = TransactPhysicalMemory(physicalAddress, actualSize, UnsafeAllocateAndCopyTable);
274 #endif // ENABLE_MAHAF
286 if(!RetrieveRsdp(rsdp))
293 u32 tableAddresses[1];
295 const RSDT* rsdt = (
const RSDT*)AllocateAndCopyTable(rsdp.rsdtPhysicalAddress);
302 numTables = (rsdt->header.size -
sizeof(
AcpiTable)) /
sizeof(rsdt->tableAddresses[0]);
307 tables[i] = AllocateAndCopyTable(rsdt->tableAddresses[i]);
314 numTables = tableIDs.size();
322 memcpy((
void*)tables[i], &table[0], table.size());
373 if(strncmp(table->
signature, signature, 4) == 0)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
static void AllocateAndCopyTables(const AcpiTable **&tables, size_t &numTables)
static void DeallocateTable(const T *table)
static u8 ComputeChecksum(PCV_u8 buf, size_t numBytes)
static bool ValidateTable(const AcpiTable *table, const char *signature=0)
const AcpiTable * acpi_GetTable(const char *signature)
static const AcpiTable * invalidTables
Table GetTable(Provider provider, TableId tableId)
const volatile AcpiTable * PCV_AcpiTable
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
void mahaf_UnmapPhysicalMemory(volatile void *virtualAddress)
void acpi_Shutdown()
invalidates all pointers returned by acpi_GetTable.
std::vector< TableId > TableIds
#define T(string_literal)
volatile void * mahaf_MapPhysicalMemory(uintptr_t physicalAddress, size_t numBytes)
static const AcpiTable ** tables
const volatile u8 * PCV_u8
#define FOURCC_BE(a, b, c, d)
big-endian version of FOURCC
bool mahaf_IsPhysicalMappingDangerous()
bool cpu_CAS(volatile intptr_t *location, intptr_t expected, intptr_t newValue)
atomic "compare and swap".
static AcpiTable * AllocateTable(size_t size)
#define SAFE_ARRAY_DELETE(p)
delete memory ensuing from new[] and set the pointer to zero (thus making double-frees safe / a no-op...
TableIds GetTableIDs(Provider provider)