:: commit 033ceb33532417f0775485aac6244c000fc98f77

mintsuki <mintsuki@protonmail.com> — 2021-04-28 18:15

parents: 3702060f69

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:");
tab: 248 wrap: offon