stivale: Implement SMBIOS related stuff. Fixes #81
diff --git a/stage23/lib/acpi.c b/stage23/lib/acpi.c
index c5f2c3de..04bebdc0 100644
--- a/stage23/lib/acpi.c
+++ b/stage23/lib/acpi.c
@@ -34,6 +34,29 @@ void *acpi_get_rsdp(void) {
return NULL;
}
+void acpi_get_smbios(void **smbios32, void **smbios64) {
+ *smbios32 = NULL;
+ *smbios64 = NULL;
+
+ for (size_t i = 0xf0000; i < 0x100000; i += 16) {
+ if (!memcmp((char *)i, "_SM_", 4)
+ && !acpi_checksum((void *)i, *((uint8_t *)(i + 5)))) {
+ print("acpi: Found SMBIOS 32-bit entry point at %x\n", i);
+ *smbios32 = (void *)i;
+ break;
+ }
+ }
+
+ for (size_t i = 0xf0000; i < 0x100000; i += 16) {
+ if (!memcmp((char *)i, "_SM3_", 5)
+ && !acpi_checksum((void *)i, *((uint8_t *)(i + 6)))) {
+ print("acpi: Found SMBIOS 64-bit entry point at %x\n", i);
+ *smbios64 = (void *)i;
+ break;
+ }
+ }
+}
+
#endif
#if defined (uefi)
@@ -59,6 +82,47 @@ void *acpi_get_rsdp(void) {
return NULL;
}
+void acpi_get_smbios(void **smbios32, void **smbios64) {
+ *smbios32 = NULL;
+ *smbios64 = NULL;
+
+ for (size_t i = 0; i < gST->NumberOfTableEntries; i++) {
+ EFI_CONFIGURATION_TABLE *cur_table = &gST->ConfigurationTable[i];
+ EFI_GUID smbios_guid = SMBIOS_TABLE_GUID;
+
+ if (memcmp(&cur_table->VendorGuid, &smbios_guid, sizeof(EFI_GUID)) != 0)
+ continue;
+
+ if (acpi_checksum(cur_table->VendorTable,
+ *((uint8_t *)(cur_table->VendorTable + 5))) != 0)
+ continue;
+
+ print("acpi: Found SMBIOS 32-bit entry point at %X\n", cur_table->VendorTable);
+
+ *smbios32 = cur_table->VendorTable;
+
+ break;
+ }
+
+ for (size_t i = 0; i < gST->NumberOfTableEntries; i++) {
+ EFI_CONFIGURATION_TABLE *cur_table = &gST->ConfigurationTable[i];
+ EFI_GUID smbios3_guid = SMBIOS3_TABLE_GUID;
+
+ if (memcmp(&cur_table->VendorGuid, &smbios3_guid, sizeof(EFI_GUID)) != 0)
+ continue;
+
+ if (acpi_checksum(cur_table->VendorTable,
+ *((uint8_t *)(cur_table->VendorTable + 6))) != 0)
+ continue;
+
+ print("acpi: Found SMBIOS 64-bit entry point at %X\n", cur_table->VendorTable);
+
+ *smbios64 = cur_table->VendorTable;
+
+ break;
+ }
+}
+
#endif
void *acpi_get_table(const char *signature, int index) {
diff --git a/stage23/lib/acpi.h b/stage23/lib/acpi.h
index ba065135..72d9a572 100644
--- a/stage23/lib/acpi.h
+++ b/stage23/lib/acpi.h
@@ -42,5 +42,6 @@ struct rsdt {
uint8_t acpi_checksum(void *ptr, size_t size);
void *acpi_get_rsdp(void);
void *acpi_get_table(const char *signature, int index);
+void acpi_get_smbios(void **smbios32, void **smbios64);
#endif
diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c
index f7e41642..64eb2d0d 100644
--- a/stage23/protos/stivale.c
+++ b/stage23/protos/stivale.c
@@ -31,6 +31,7 @@ void stivale_load(char *config, char *cmdline) {
#endif
stivale_struct.flags |= (1 << 1); // we give colour information
+ stivale_struct.flags |= (1 << 2); // we give SMBIOS information
struct file_handle *kernel_file = ext_mem_alloc(sizeof(struct file_handle));
@@ -156,6 +157,9 @@ void stivale_load(char *config, char *cmdline) {
stivale_struct.rsdp = (uint64_t)(size_t)acpi_get_rsdp();
+ acpi_get_smbios((void **)&stivale_struct.smbios_entry_32,
+ (void **)&stivale_struct.smbios_entry_64);
+
stivale_struct.cmdline = (uint64_t)(size_t)cmdline;
stivale_struct.epoch = time();
diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c
index 49640738..abf4a908 100644
--- a/stage23/protos/stivale2.c
+++ b/stage23/protos/stivale2.c
@@ -241,6 +241,19 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
}
+ //////////////////////////////////////////////
+ // Create SMBIOS struct tag
+ //////////////////////////////////////////////
+ {
+ struct stivale2_struct_tag_smbios *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_smbios));
+ tag->tag.identifier = STIVALE2_STRUCT_TAG_SMBIOS_ID;
+
+ acpi_get_smbios((void **)&tag->smbios_entry_32,
+ (void **)&tag->smbios_entry_64);
+
+ append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
+ }
+
//////////////////////////////////////////////
// Create cmdline struct tag
//////////////////////////////////////////////
diff --git a/test/stivale.c b/test/stivale.c
index 3ec63a0e..d3b80a63 100644
--- a/test/stivale.c
+++ b/test/stivale.c
@@ -34,7 +34,7 @@ void stivale_main(struct stivale_struct *info) {
e9_printf("\tHeight: %d", info->framebuffer_height);
e9_printf("\tBPP: %d", info->framebuffer_bpp);
if (info->flags & (1 << 1)) {
- e9_printf("\tExtended colour information passed:");
+ e9_printf("\tExtended colour information provided:");
e9_printf("\t\tMemory model: %d", info->fb_memory_model);
e9_printf("\t\tRed mask size: %d", info->fb_red_mask_size);
e9_printf("\t\tRed mask shift: %d", info->fb_red_mask_shift);
@@ -43,6 +43,11 @@ void stivale_main(struct stivale_struct *info) {
e9_printf("\t\tBlue mask size: %d", info->fb_blue_mask_size);
e9_printf("\t\tBlue mask shift: %d", info->fb_blue_mask_shift);
}
+ if (info->flags & (1 << 2)) {
+ e9_printf("\tSMBIOS information provided:");
+ e9_printf("\t\t32-bit entry: %x", info->smbios_entry_32);
+ e9_printf("\t\t64-bit entry: %x", info->smbios_entry_64);
+ }
e9_printf("RSDP at %x", info->rsdp);
diff --git a/test/stivale2.c b/test/stivale2.c
index e196eecd..f95dde45 100644
--- a/test/stivale2.c
+++ b/test/stivale2.c
@@ -144,6 +144,14 @@ void stivale2_main(struct stivale2_struct *info) {
e9_printf(" RSDP: %x", r->rsdp);
break;
}
+ case STIVALE2_STRUCT_TAG_SMBIOS_ID: {
+ struct stivale2_struct_tag_smbios *r = (struct stivale2_struct_tag_smbios *)tag;
+ e9_puts("SMBIOS tag:");
+ e9_printf(" Flags: %x", r->flags);
+ e9_printf(" SMBIOS 32-bit entry point: %x", r->smbios_entry_32);
+ e9_printf(" SMBIOS 64-bit entry point: %x", r->smbios_entry_64);
+ break;
+ }
case STIVALE2_STRUCT_TAG_EPOCH_ID: {
struct stivale2_struct_tag_epoch *e = (struct stivale2_struct_tag_epoch *)tag;
e9_puts("Epoch tag:");
