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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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);