From 033ceb33532417f0775485aac6244c000fc98f77 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Wed, 28 Apr 2021 20:15:24 +0200 Subject: [PATCH] stivale: Implement SMBIOS related stuff. Fixes #81 --- stage23/lib/acpi.c | 64 +++++++++++++++++++++++++++++++++++++++ stage23/lib/acpi.h | 1 + stage23/protos/stivale.c | 4 +++ stage23/protos/stivale2.c | 13 ++++++++ test/stivale.c | 7 ++++- test/stivale2.c | 8 +++++ 6 files changed, 96 insertions(+), 1 deletion(-) 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:");