Is this wrong, or am I interpreting the RSDP incorrectly?[1763578] ACPI Table Revision 0 -> 1
Here is the code for my RSDP structure:
Code: Select all
#pragma pack(push, 1)
/* Root System Descriptor Pointer */
typedef struct _RSDP
{
char Signature[8];
uint8 Checksum;
char OEMID[6];
uint8 Revision;
uint32 RSDTAddress;
/* Following fields do not exist in ACPI 1.0 (Revision = 0) */
uint32 Length;
uint64 XSDTAddress;
uint8 ExtendedChecksum;
char Reserved[3];
} RSDP_t;
#pragma pack(pop)
Code: Select all
static RSDP_t* RSDP;
bool InitACPI()
{
/* Step 1: Find the RSDP */
uint16 ebdaAddrSeg = *((uint16*)(PTOV(ACPI_RSDP_EBDA_PTR_LOCATION)));
char buffer[80];
void* ebdaAddr = PTOV(ebdaAddrSeg);
void* i;
/* Maybe its in the EBDA? */
for(i = ebdaAddr; i < ebdaAddr+ACPI_RSDP_EBDA_SIZE; i += ACPI_RSDP_ALIGNMENT)
{
if(strncmp(i, APIC_RSDP_SIG, 8) == 0)
break;
}
if(i>=ebdaAddr+ACPI_RSDP_EBDA_SIZE)
{
/* No? Then it must be in the BIOS. */
for( i = PTOV(0x000E0000); i < PTOV(0x000FFFFF); i += ACPI_RSDP_ALIGNMENT)
{
if(strncmp(i, APIC_RSDP_SIG, 8) == 0)
break;
}
if(i >= PTOV(0x000FFFFF))
return false; /* No RSDP! */
}
RSDP = (RSDP_t*)i;
/* Check the validity of the table using the checksum */
uint8 checksum = 0;
for(i = (void*)RSDP; i < ((void*)RSDP)+ACPI_RSDP_1_SIZE; i++)
{
checksum += *((uint8*)i);
}
if(checksum != 0)
return false; /* INVALID RSDP! */
uitoa(RSDP->Revision, buffer, 10);
WriteTextModeLine(buffer, 0x07);
/* Check the revision */
if(RSDP->Revision > ACPI_REVISION_1)
{
/* If this is a later revision table than 1.0, check the validity of the table using the second checksum */
uint8 checksum = 0;
for(i = (void*)RSDP; i < ((void*)RSDP)+sizeof(RSDP_t); i++)
{
checksum += *((uint8*)i);
}
if(checksum != 0)
return false; /* INVALID RSDP! */
}
return true;
}
- My OS is for x86_64 only (i know this isn't the issue because everything else works, just not ACPI)
- PTOV is a macro that just adds a number to physical addresses to turn them into their virtual counterparts. I map the first 16GB of physical addresses inside the virtual address space before this function is called
- uitoa() just converts 64-bit unsigned integers into text
- WriteTextModeLine() just writes text to the screen while in text mode
- The RSDP that is found is inside the BIOS, not the EBDA