:: commit dbbf8df9fc2bfe0aa5608ceaaed794798e4d9513

Mintsuki <mintsuki@protonmail.com> — 2026-03-25 02:30

parents: 598f4e6b09

protos/limine: Coalesce contiguous memmap entries when building page tables

diff --git a/common/protos/limine.c b/common/protos/limine.c
index 4b0119c9..f2fe591d 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -201,12 +201,18 @@ static pagemap_t build_pagemap(int base_revision,
     for (size_t i = 0; i < _memmap_entries; i++)
         _memmap[i] = memmap[i];
 
-    // Map all free memory regions to the higher half direct map offset
+    // Map all free memory regions to the higher half direct map offset.
+    // Coalesce contiguous entries into single map_pages calls to maximise
+    // the use of large pages (2MiB/1GiB).
+    uint64_t pending_base = 0, pending_top = 0;
+
     for (size_t i = 0; i < _memmap_entries; i++) {
+        uint64_t aligned_base = 0, aligned_top = 0;
+
         if (((base_revision >= 1 && base_revision < 3) || base_revision >= 4) && (
             _memmap[i].type == MEMMAP_RESERVED
          || _memmap[i].type == MEMMAP_BAD_MEMORY)) {
-            continue;
+            goto flush;
         }
 
         if (base_revision == 3 && (
@@ -215,7 +221,7 @@ static pagemap_t build_pagemap(int base_revision,
          && _memmap[i].type != MEMMAP_KERNEL_AND_MODULES
          && _memmap[i].type != MEMMAP_FRAMEBUFFER
          && _memmap[i].type != MEMMAP_EFI_RECLAIMABLE)) {
-            continue;
+            goto flush;
         }
 
         uint64_t base   = _memmap[i].base;
@@ -227,17 +233,35 @@ static pagemap_t build_pagemap(int base_revision,
         }
 
         if (base >= top) {
+            goto flush;
+        }
+
+        aligned_base = ALIGN_DOWN(base, 0x1000);
+        aligned_top  = ALIGN_UP(top, 0x1000);
+
+        if (aligned_base == pending_top && pending_top != 0) {
+            pending_top = aligned_top;
             continue;
         }
 
-        uint64_t aligned_base   = ALIGN_DOWN(base, 0x1000);
-        uint64_t aligned_top    = ALIGN_UP(top, 0x1000);
-        uint64_t aligned_length = aligned_top - aligned_base;
+flush:
+        if (pending_top > pending_base) {
+            uint64_t len = pending_top - pending_base;
+            if (base_revision == 0) {
+                map_pages(pagemap, pending_base, pending_base, VMM_FLAG_WRITE, len);
+            }
+            map_pages(pagemap, direct_map_offset + pending_base, pending_base, VMM_FLAG_WRITE, len);
+        }
+        pending_base = aligned_base;
+        pending_top = aligned_top;
+    }
 
+    if (pending_top > pending_base) {
+        uint64_t len = pending_top - pending_base;
         if (base_revision == 0) {
-            map_pages(pagemap, aligned_base, aligned_base, VMM_FLAG_WRITE, aligned_length);
+            map_pages(pagemap, pending_base, pending_base, VMM_FLAG_WRITE, len);
         }
-        map_pages(pagemap, direct_map_offset + aligned_base, aligned_base, VMM_FLAG_WRITE, aligned_length);
+        map_pages(pagemap, direct_map_offset + pending_base, pending_base, VMM_FLAG_WRITE, len);
     }
 
     // Map the framebuffer with appropriate permissions
tab: 248 wrap: offon