Module Name: src Committed By: nonaka Date: Mon Jul 29 11:28:51 UTC 2019
Modified Files: src/sys/arch/i386/stand/efiboot: boot.c efiboot.c efiboot.h efimemory.c Log Message: Added BTINFO_EFIMEMMAP compaction support to x86 efiboot. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/arch/i386/stand/efiboot/boot.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/i386/stand/efiboot/efiboot.c \ src/sys/arch/i386/stand/efiboot/efiboot.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/i386/stand/efiboot/efimemory.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/efiboot/boot.c diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.12 src/sys/arch/i386/stand/efiboot/boot.c:1.13 --- src/sys/arch/i386/stand/efiboot/boot.c:1.12 Fri Jul 26 12:09:48 2019 +++ src/sys/arch/i386/stand/efiboot/boot.c Mon Jul 29 11:28:51 2019 @@ -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 <non...@netbsd.org> @@ -351,7 +351,7 @@ command_help(char *arg) #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 @@ void 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 Index: src/sys/arch/i386/stand/efiboot/efiboot.c diff -u src/sys/arch/i386/stand/efiboot/efiboot.c:1.8 src/sys/arch/i386/stand/efiboot/efiboot.c:1.9 --- src/sys/arch/i386/stand/efiboot/efiboot.c:1.8 Fri Jun 8 11:52:30 2018 +++ src/sys/arch/i386/stand/efiboot/efiboot.c Mon Jul 29 11:28:51 2019 @@ -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 <non...@netbsd.org> @@ -134,6 +134,7 @@ efi_cleanup(void) } efi_cleanuped = true; + efi_memory_compact_map(desc, &NoEntries, DescriptorSize); allocsz = sizeof(struct btinfo_efimemmap) - 1 + NoEntries * DescriptorSize; bim = alloc(allocsz); Index: src/sys/arch/i386/stand/efiboot/efiboot.h diff -u src/sys/arch/i386/stand/efiboot/efiboot.h:1.8 src/sys/arch/i386/stand/efiboot/efiboot.h:1.9 --- src/sys/arch/i386/stand/efiboot/efiboot.h:1.8 Wed Apr 11 10:32:09 2018 +++ src/sys/arch/i386/stand/efiboot/efiboot.h Mon Jul 29 11:28:51 2019 @@ -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 <non...@netbsd.org> @@ -80,9 +80,11 @@ void efi_disk_show(void); /* 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); Index: src/sys/arch/i386/stand/efiboot/efimemory.c diff -u src/sys/arch/i386/stand/efiboot/efimemory.c:1.6 src/sys/arch/i386/stand/efiboot/efimemory.c:1.7 --- src/sys/arch/i386/stand/efiboot/efimemory.c:1.6 Fri Jul 26 12:09:48 2019 +++ src/sys/arch/i386/stand/efiboot/efimemory.c Mon Jul 29 11:28:51 2019 @@ -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 <non...@netbsd.org> @@ -107,7 +107,7 @@ EFI_MEMORY_DESCRIPTOR * 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 @@ efi_memory_get_map(UINTN *NoEntries, UIN 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 @@ efi_memory_probe(void) } 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 @@ efi_memory_show_map(bool sorted) 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);