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);

Reply via email to