Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/stand/efiboot Added BTINFO_EFIMEMMAP compactio...



details:   https://anonhg.NetBSD.org/src/rev/f44d7609cd6d
branches:  trunk
changeset: 1000578:f44d7609cd6d
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Mon Jul 29 11:28:51 2019 +0000

description:
Added BTINFO_EFIMEMMAP compaction support to x86 efiboot.

diffstat:

 sys/arch/i386/stand/efiboot/boot.c      |  11 ++-
 sys/arch/i386/stand/efiboot/efiboot.c   |   3 +-
 sys/arch/i386/stand/efiboot/efiboot.h   |   6 +-
 sys/arch/i386/stand/efiboot/efimemory.c |  90 ++++++++++++++++++++++++++++++--
 4 files changed, 97 insertions(+), 13 deletions(-)

diffs (214 lines):

diff -r 4b2e3feac42b -r f44d7609cd6d sys/arch/i386/stand/efiboot/boot.c
--- a/sys/arch/i386/stand/efiboot/boot.c        Mon Jul 29 11:11:19 2019 +0000
+++ b/sys/arch/i386/stand/efiboot/boot.c        Mon Jul 29 11:28:51 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot.c,v 1.12 2019/07/26 12:09:48 nonaka Exp $ */
+/*     $NetBSD: boot.c,v 1.13 2019/07/29 11:28:51 nonaka Exp $ */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -351,7 +351,7 @@
 #if LIBSA_ENABLE_LS_OP
               "ls [path]\n"
 #endif
-              "memmap [{sorted|unsorted}]\n"
+              "memmap [{sorted|unsorted|compact}]\n"
 #ifndef SMALL
               "menu (reenters boot menu, if defined in boot.cfg)\n"
 #endif
@@ -613,18 +613,21 @@
 command_memmap(char *arg)
 {
        bool sorted = true;
+       bool compact = false;
 
        if (*arg == '\0' || strcmp(arg, "sorted") == 0)
                /* Already sorted is true. */;
        else if (strcmp(arg, "unsorted") == 0)
                sorted = false;
+       else if (strcmp(arg, "compact") == 0)
+               compact = true;
        else {
                printf("invalid flag, "
-                   "must be 'sorted' or 'unsorted'.\n");
+                   "must be 'sorted', 'unsorted' or 'compact'.\n");
                return;
        }
 
-       efi_memory_show_map(sorted);
+       efi_memory_show_map(sorted, compact);
 }
 
 void
diff -r 4b2e3feac42b -r f44d7609cd6d sys/arch/i386/stand/efiboot/efiboot.c
--- a/sys/arch/i386/stand/efiboot/efiboot.c     Mon Jul 29 11:11:19 2019 +0000
+++ b/sys/arch/i386/stand/efiboot/efiboot.c     Mon Jul 29 11:28:51 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efiboot.c,v 1.8 2018/06/08 11:52:30 nonaka Exp $       */
+/*     $NetBSD: efiboot.c,v 1.9 2019/07/29 11:28:51 nonaka Exp $       */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -134,6 +134,7 @@
        }
        efi_cleanuped = true;
 
+       efi_memory_compact_map(desc, &NoEntries, DescriptorSize);
        allocsz = sizeof(struct btinfo_efimemmap) - 1
            + NoEntries * DescriptorSize;
        bim = alloc(allocsz);
diff -r 4b2e3feac42b -r f44d7609cd6d sys/arch/i386/stand/efiboot/efiboot.h
--- a/sys/arch/i386/stand/efiboot/efiboot.h     Mon Jul 29 11:11:19 2019 +0000
+++ b/sys/arch/i386/stand/efiboot/efiboot.h     Mon Jul 29 11:28:51 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efiboot.h,v 1.8 2018/04/11 10:32:09 nonaka Exp $       */
+/*     $NetBSD: efiboot.h,v 1.9 2019/07/29 11:28:51 nonaka Exp $       */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -80,9 +80,11 @@
 
 /* efimemory.c */
 void efi_memory_probe(void);
-void efi_memory_show_map(bool);
+void efi_memory_show_map(bool, bool);
 EFI_MEMORY_DESCRIPTOR *efi_memory_get_map(UINTN *, UINTN *, UINTN *, UINT32 *,
     bool);
+EFI_MEMORY_DESCRIPTOR *efi_memory_compact_map(EFI_MEMORY_DESCRIPTOR *, UINTN *,
+    UINTN);
 
 /* efinet.c */
 void efi_net_probe(void);
diff -r 4b2e3feac42b -r f44d7609cd6d sys/arch/i386/stand/efiboot/efimemory.c
--- a/sys/arch/i386/stand/efiboot/efimemory.c   Mon Jul 29 11:11:19 2019 +0000
+++ b/sys/arch/i386/stand/efiboot/efimemory.c   Mon Jul 29 11:28:51 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efimemory.c,v 1.6 2019/07/26 12:09:48 nonaka Exp $     */
+/*     $NetBSD: efimemory.c,v 1.7 2019/07/29 11:28:51 nonaka Exp $     */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -107,7 +107,7 @@
 efi_memory_get_map(UINTN *NoEntries, UINTN *MapKey, UINTN *DescriptorSize,
     UINT32 *DescriptorVersion, bool sorted)
 {
-       EFI_MEMORY_DESCRIPTOR *desc, *md, *next, *target, tmp;
+       EFI_MEMORY_DESCRIPTOR *desc, *md, *next, *target, *tmp;
        UINTN i, j;
 
        *NoEntries = 0;
@@ -119,17 +119,93 @@
        if (!sorted)
                return desc;
 
+       tmp = alloc(*DescriptorSize);
+       if (tmp == NULL)
+               return desc;
+
        for (i = 0, md = desc; i < *NoEntries - 1; i++, md = next) {
                target = next = NextMemoryDescriptor(md, *DescriptorSize);
                for (j = i + 1; j < *NoEntries; j++) {
                        if (md->PhysicalStart > target->PhysicalStart) {
-                               CopyMem(&tmp, md, sizeof(*md));
-                               CopyMem(md, target, sizeof(*md));
-                               CopyMem(target, &tmp, sizeof(*md));
+                               CopyMem(tmp, md, *DescriptorSize);
+                               CopyMem(md, target, *DescriptorSize);
+                               CopyMem(target, tmp, *DescriptorSize);
                        }
                        target = NextMemoryDescriptor(target, *DescriptorSize);
                }
        }
+       dealloc(tmp, *DescriptorSize);
+
+       return desc;
+}
+
+EFI_MEMORY_DESCRIPTOR *
+efi_memory_compact_map(EFI_MEMORY_DESCRIPTOR *desc, UINTN *NoEntries,
+    UINTN DescriptorSize)
+{
+       EFI_MEMORY_DESCRIPTOR *md, *next, *target, *tmp;
+       UINTN i, j;
+       UINT32 type;
+       bool first = true, do_compact;
+
+       for (i = 0, md = target = desc; i < *NoEntries; i++, md = next) {
+               type = md->Type;
+               switch (type) {
+               case EfiLoaderCode:
+               case EfiLoaderData:
+               case EfiBootServicesCode:
+               case EfiBootServicesData:
+               case EfiConventionalMemory:
+                       if ((md->Attribute & EFI_MEMORY_WB) != 0)
+                               type = EfiConventionalMemory;
+                       if (md->Attribute == target->Attribute) {
+                               do_compact = true;
+                               break;
+                       }
+                       /* FALLTHROUGH */
+               case EfiACPIReclaimMemory:
+               case EfiACPIMemoryNVS:
+               case EfiPersistentMemory:
+               case EfiReservedMemoryType:
+               case EfiRuntimeServicesCode:
+               case EfiRuntimeServicesData:
+               case EfiUnusableMemory:
+               case EfiMemoryMappedIO:
+               case EfiMemoryMappedIOPortSpace:
+               case EfiPalCode:
+               default:
+                       do_compact = false;
+                       break;
+               }
+
+               if (first) {
+                       first = false;
+               } else if (do_compact &&
+                   type == target->Type &&
+                   md->Attribute == target->Attribute &&
+                   md->PhysicalStart == target->PhysicalStart + target->NumberOfPages * EFI_PAGE_SIZE) {
+                       /* continuous region */
+                       target->NumberOfPages += md->NumberOfPages;
+
+                       tmp = md;
+                       for (j = i + 1; j < *NoEntries; j++) {
+                               next = NextMemoryDescriptor(md, DescriptorSize);
+                               CopyMem(md, next, DescriptorSize);
+                               md = next;
+                       }
+                       next = tmp;
+
+                       i--;
+                       (*NoEntries)--;
+                       continue;
+               } else {
+                       target = md;
+               }
+
+               target->Type = type;
+               next = NextMemoryDescriptor(md, DescriptorSize);
+       }
+
        return desc;
 }
 
@@ -273,7 +349,7 @@
 }
 
 void
-efi_memory_show_map(bool sorted)
+efi_memory_show_map(bool sorted, bool compact)
 {
        EFI_STATUS status;
        EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
@@ -292,6 +368,8 @@
 
        mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
            &DescriptorVersion, sorted);
+       if (compact)
+               efi_memory_compact_map(mdtop, &NoEntries, DescriptorSize);
 
        for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
                next = NextMemoryDescriptor(md, DescriptorSize);



Home | Main Index | Thread Index | Old Index