82 lines
1.8 KiB
C
82 lines
1.8 KiB
C
|
#include <multiboot.h>
|
||
|
#include <acpi.h>
|
||
|
|
||
|
struct kernel_context {
|
||
|
struct rsdp *rsdp;
|
||
|
struct xsdp *xsdp;
|
||
|
|
||
|
struct rsdt *rsdt;
|
||
|
};
|
||
|
|
||
|
struct kernel_context ctx = {0};
|
||
|
|
||
|
int strncmp( const char * s1, const char * s2, int n )
|
||
|
{
|
||
|
while ( n && *s1 && ( *s1 == *s2 ) )
|
||
|
{
|
||
|
++s1;
|
||
|
++s2;
|
||
|
--n;
|
||
|
}
|
||
|
if ( n == 0 )
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void *findFACP(void *RootSDT)
|
||
|
{
|
||
|
struct rsdt *rsdt = (struct rsdt *) RootSDT;
|
||
|
int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4;
|
||
|
|
||
|
for (int i = 0; i < entries; i++)
|
||
|
{
|
||
|
struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i];
|
||
|
if (!strncmp(h->Signature, "FACP", 4))
|
||
|
return (void *) h;
|
||
|
}
|
||
|
|
||
|
// No FACP found
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void kmain(struct multiboot_info *info) {
|
||
|
// Check if the bootloader gave us the upper and lower memory
|
||
|
if (!(info->flags & 0x1)) goto halt;
|
||
|
|
||
|
char *vmem = (char *)0xb8000;
|
||
|
|
||
|
struct rsdp *found_rsdp = acpi_search_for_rsdp();
|
||
|
if (!found_rsdp) goto halt;
|
||
|
if (found_rsdp->Revision == ACPI_VER_1) {
|
||
|
// ACPI v1.0 is being used
|
||
|
if (!acpi_validate_rsdp_checksum(found_rsdp)) goto halt;
|
||
|
ctx.rsdp = found_rsdp;
|
||
|
ctx.xsdp = 0;
|
||
|
|
||
|
if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress))
|
||
|
goto halt;
|
||
|
|
||
|
ctx.rsdt = (struct rsdt*)found_rsdp->RsdtAddress;
|
||
|
|
||
|
} else if (found_rsdp->Revision == ACPI_VER_OTHER) {
|
||
|
// ACPI v2.0+ is being used
|
||
|
// not supported yet....
|
||
|
goto halt;
|
||
|
} else goto halt;
|
||
|
|
||
|
void *fadt = findFACP(ctx.rsdt);
|
||
|
if (!fadt) goto halt;
|
||
|
char *next_sig = (char *)fadt;
|
||
|
vmem[0] = next_sig[0];
|
||
|
vmem[2] = next_sig[1];
|
||
|
vmem[4] = next_sig[2];
|
||
|
vmem[6] = next_sig[3];
|
||
|
halt:
|
||
|
for (;;) {}
|
||
|
}
|