:: commit 7025da44e32b87adb0053a3a769a5335aac317fa

Andy-Python-Programmer <andypythonappdeveloper@gmail.com> — 2021-10-07 02:04

parents: 2786666b0a

multiboot2: add the basic memory info tag

Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
diff --git a/stage23/mm/pmm.h b/stage23/mm/pmm.h
index 5c789c13..5f6bcfa4 100644
--- a/stage23/mm/pmm.h
+++ b/stage23/mm/pmm.h
@@ -17,6 +17,13 @@
 #define MEMMAP_EFI_RECLAIMABLE        0x2000
 #define MEMMAP_EFI_BOOTSERVICES       0x2001
 
+struct meminfo {
+    size_t uppermem;
+    size_t lowermem;
+};
+
+struct meminfo mmap_get_info(size_t mmap_count, struct e820_entry_t *mmap);
+
 #if bios == 1
 extern struct e820_entry_t memmap[];
 extern size_t memmap_entries;
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index fb073684..7dc7341f 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -611,6 +611,35 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) {
     panic("High memory allocator: Out of memory");
 }
 
+
+/// Compute and returns the amount of upper and lower memory till 
+/// the first hole.
+struct meminfo mmap_get_info(size_t mmap_count, struct e820_entry_t *mmap) {
+    struct meminfo info = {0};
+
+    for (size_t i = 0; i < mmap_count; i++) {
+        if (mmap[i].type == MEMMAP_USABLE) {
+            // NOTE: Upper memory starts at address 1MiB and the
+            // value of uppermem is the address of the first upper memory
+            // hole minus 1MiB.
+            if (mmap[i].base < 0x100000) {
+                if (mmap[i].base + mmap[i].length > 0x100000) {
+                    size_t low_len = 0x100000 - mmap[i].base;
+
+                    info.lowermem += low_len;
+                    info.uppermem += mmap[i].length - low_len;
+                } else {
+                    info.lowermem += mmap[i].length;
+                }
+            } else {
+                info.uppermem += mmap[i].length;
+            }
+        }
+    }
+
+    return info;
+}
+
 bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only, bool do_panic, bool simulation, bool new_entry) {
     if (length == 0)
         return true;
diff --git a/stage23/protos/multiboot1.c b/stage23/protos/multiboot1.c
index c9828652..71eac9aa 100644
--- a/stage23/protos/multiboot1.c
+++ b/stage23/protos/multiboot1.c
@@ -246,32 +246,22 @@ nofb:;
     size_t mb_mmap_len = mb_mmap_count * sizeof(struct multiboot1_mmap_entry);
     struct multiboot1_mmap_entry *mmap = conv_mem_alloc(mb_mmap_len);
 
-    size_t memory_lower = 0, memory_upper = 0;
-
     // Multiboot is bad and passes raw memmap. We do the same to support it.
     for (size_t i = 0; i < mb_mmap_count; i++) {
         mmap[i].size = sizeof(struct multiboot1_mmap_entry) - 4;
         mmap[i].addr = raw_memmap[i].base;
         mmap[i].len  = raw_memmap[i].length;
         mmap[i].type = raw_memmap[i].type;
-
-        if (mmap[i].type == MEMMAP_USABLE) {
-            if (mmap[i].addr < 0x100000) {
-                if (mmap[i].addr + mmap[i].len > 0x100000) {
-                    size_t low_len = 0x100000 - mmap[i].addr;
-                    memory_lower += low_len;
-                    memory_upper += mmap[i].len - low_len;
-                } else {
-                    memory_lower += mmap[i].len;
-                }
-            } else {
-                memory_upper += mmap[i].len;
-            }
-        }
     }
 
-    multiboot1_info.mem_lower = memory_lower / 1024;
-    multiboot1_info.mem_upper = memory_upper / 1024;
+    {
+        struct meminfo memory_info = mmap_get_info(mb_mmap_count, raw_memmap);
+
+        // Convert the uppermem and lowermem fields from bytes to
+        // KiB.
+        multiboot1_info.mem_lower = memory_info.lowermem / 1024;
+        multiboot1_info.mem_upper = memory_info.uppermem / 1024;
+    }
 
     multiboot1_info.mmap_length = mb_mmap_len;
     multiboot1_info.mmap_addr = ((uint32_t)(size_t)mmap);
diff --git a/stage23/protos/multiboot2.c b/stage23/protos/multiboot2.c
index a03b1a45..4e80da34 100644
--- a/stage23/protos/multiboot2.c
+++ b/stage23/protos/multiboot2.c
@@ -59,6 +59,7 @@ static size_t get_multiboot2_info_size(
         ALIGN_UP(sizeof(struct multiboot_tag_old_acpi) + 20, MULTIBOOT_TAG_ALIGN) +                                     // old ACPI info
         ALIGN_UP(sizeof(struct multiboot_tag_elf_sections) + section_hdr_size, MULTIBOOT_TAG_ALIGN) +                   // ELF info
         ALIGN_UP(modules_size, MULTIBOOT_TAG_ALIGN) +                                                                   // modules
+        ALIGN_UP(sizeof(struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN) +                                     // basic memory info
         ALIGN_UP(sizeof(struct multiboot_tag_mmap) + sizeof(struct multiboot_mmap_entry) * 256, MULTIBOOT_TAG_ALIGN) +  // MMAP
         #if uefi == 1
             ALIGN_UP(sizeof(struct multiboot_tag_efi_mmap) + (efi_desc_size * 256), MULTIBOOT_TAG_ALIGN) +              // EFI MMAP
@@ -120,12 +121,15 @@ void multiboot2_load(char *config, char* cmdline) {
                         case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
                         case MULTIBOOT_TAG_TYPE_MODULE:
                         case MULTIBOOT_TAG_TYPE_MMAP:
+                        case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
                         #if uefi == 1
                             case MULTIBOOT_TAG_TYPE_EFI_MMAP:
                             #if defined (__i386__)
                                 case MULTIBOOT_TAG_TYPE_EFI32:
+                                case MULTIBOOT_TAG_TYPE_EFI32_IH:
                             #elif defined (__x86_64__)
                                 case MULTIBOOT_TAG_TYPE_EFI64:
+                                case MULTIBOOT_TAG_TYPE_EFI64_IH:
                             #endif
                         #endif
                         case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
@@ -430,7 +434,7 @@ void multiboot2_load(char *config, char* cmdline) {
     // Create new ACPI info tag
     //////////////////////////////////////////////
     {
-        void *new_rsdp = acpi_get_rsdp();
+        void *new_rsdp = acpi_get_rsdp_v2();
 
         if (new_rsdp != NULL) {
             uint32_t size = sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp); // XSDP is 36 bytes wide
@@ -518,13 +522,13 @@ void multiboot2_load(char *config, char* cmdline) {
     efi_exit_boot_services();
 #endif
 
+    size_t mb_mmap_count;
+    struct e820_entry_t *raw_memmap = get_raw_memmap(&mb_mmap_count);
+
     //////////////////////////////////////////////
     // Create memory map tag
     //////////////////////////////////////////////
     {
-        size_t mb_mmap_count;
-        struct e820_entry_t *raw_memmap = get_raw_memmap(&mb_mmap_count);
-
         if (mb_mmap_count > 256) {
             panic("multiboot2: too many memory map entries");
         }
@@ -549,6 +553,24 @@ void multiboot2_load(char *config, char* cmdline) {
         append_tag(info_idx, mmap_tag);
     }
 
+    //////////////////////////////////////////////
+    // Create basic memory info tag
+    //////////////////////////////////////////////
+    {
+        struct meminfo meminfo = mmap_get_info(mb_mmap_count, raw_memmap);
+        struct multiboot_tag_basic_meminfo *tag = (struct multiboot_tag_basic_meminfo *)(mb2_info + info_idx);
+
+        tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
+        tag->size = sizeof(struct multiboot_tag_basic_meminfo);
+
+        // Convert the uppermem and lowermem fields from bytes to
+        // KiB.
+        tag->mem_upper = (uint32_t)(meminfo.uppermem / 1024);
+        tag->mem_lower = (uint32_t)(meminfo.lowermem / 1024);
+
+        append_tag(info_idx, tag);
+    }
+
     //////////////////////////////////////////////
     // Create EFI memory map tag
     //////////////////////////////////////////////
tab: 248 wrap: offon