Home | History | Annotate | Line # | Download | only in efiboot
efimemory.c revision 1.7
      1  1.7  nonaka /*	$NetBSD: efimemory.c,v 1.7 2019/07/29 11:28:51 nonaka Exp $	*/
      2  1.1  nonaka 
      3  1.1  nonaka /*-
      4  1.1  nonaka  * Copyright (c) 2016 Kimihiro Nonaka <nonaka (at) netbsd.org>
      5  1.1  nonaka  * All rights reserved.
      6  1.1  nonaka  *
      7  1.1  nonaka  * Redistribution and use in source and binary forms, with or without
      8  1.1  nonaka  * modification, are permitted provided that the following conditions
      9  1.1  nonaka  * are met:
     10  1.1  nonaka  * 1. Redistributions of source code must retain the above copyright
     11  1.1  nonaka  *    notice, this list of conditions and the following disclaimer.
     12  1.1  nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  nonaka  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  nonaka  *    documentation and/or other materials provided with the distribution.
     15  1.1  nonaka  *
     16  1.1  nonaka  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     17  1.1  nonaka  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1  nonaka  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1  nonaka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     20  1.1  nonaka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  1.1  nonaka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  1.1  nonaka  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  1.1  nonaka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  1.1  nonaka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.1  nonaka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.1  nonaka  * SUCH DAMAGE.
     27  1.1  nonaka  */
     28  1.1  nonaka 
     29  1.1  nonaka #include "efiboot.h"
     30  1.1  nonaka 
     31  1.1  nonaka #include <bootinfo.h>
     32  1.1  nonaka 
     33  1.1  nonaka static const char *memtypes[] = {
     34  1.1  nonaka 	"unknown",
     35  1.1  nonaka 	"available",
     36  1.1  nonaka 	"reserved",
     37  1.1  nonaka 	"ACPI reclaimable",
     38  1.4  nonaka 	"ACPI NVS",
     39  1.4  nonaka 	"unusable",
     40  1.4  nonaka 	"disabled",
     41  1.4  nonaka 	"Persistent",
     42  1.4  nonaka 	"undefined (8)",
     43  1.4  nonaka 	"undefined (9)",
     44  1.4  nonaka 	"undefined (10)",
     45  1.4  nonaka 	"undefined (11)",
     46  1.4  nonaka 	"Persistent (Legacy)"
     47  1.1  nonaka };
     48  1.1  nonaka 
     49  1.1  nonaka static const char *efimemtypes[] = {
     50  1.1  nonaka 	"Reserved",
     51  1.1  nonaka 	"LoaderCode",
     52  1.1  nonaka 	"LoaderData",
     53  1.1  nonaka 	"BootServicesCode",
     54  1.1  nonaka 	"BootServicesData",
     55  1.1  nonaka 	"RuntimeServicesCode",
     56  1.1  nonaka 	"RuntimeServicesData",
     57  1.1  nonaka 	"ConventionalMemory",
     58  1.1  nonaka 	"UnusableMemory",
     59  1.1  nonaka 	"ACPIReclaimMemory",
     60  1.1  nonaka 	"ACPIMemoryNVS",
     61  1.1  nonaka 	"MemoryMappedIO",
     62  1.1  nonaka 	"MemoryMappedIOPortSpace",
     63  1.1  nonaka 	"PalCode",
     64  1.4  nonaka 	"PersistentMemory",
     65  1.1  nonaka };
     66  1.1  nonaka 
     67  1.6  nonaka #ifndef KERN_LOADSPACE_SIZE
     68  1.6  nonaka #define KERN_LOADSPACE_SIZE	(128 * 1024 * 1024)	/* 128MiB */
     69  1.6  nonaka #endif
     70  1.6  nonaka 
     71  1.1  nonaka static int
     72  1.1  nonaka getmemtype(EFI_MEMORY_DESCRIPTOR *md)
     73  1.1  nonaka {
     74  1.1  nonaka 
     75  1.1  nonaka 	switch (md->Type) {
     76  1.1  nonaka 	case EfiLoaderCode:
     77  1.1  nonaka 	case EfiLoaderData:
     78  1.1  nonaka 	case EfiBootServicesCode:
     79  1.1  nonaka 	case EfiBootServicesData:
     80  1.1  nonaka 	case EfiConventionalMemory:
     81  1.1  nonaka 		return (md->Attribute & EFI_MEMORY_WB) ?
     82  1.1  nonaka 		    BIM_Memory : BIM_Reserved;
     83  1.1  nonaka 
     84  1.1  nonaka 	case EfiACPIReclaimMemory:
     85  1.1  nonaka 		return BIM_ACPI;
     86  1.1  nonaka 
     87  1.1  nonaka 	case EfiACPIMemoryNVS:
     88  1.1  nonaka 		return BIM_NVS;
     89  1.1  nonaka 
     90  1.4  nonaka 	case EfiPersistentMemory:
     91  1.4  nonaka 		return BIM_PMEM;
     92  1.4  nonaka 
     93  1.1  nonaka 	case EfiReservedMemoryType:
     94  1.1  nonaka 	case EfiRuntimeServicesCode:
     95  1.1  nonaka 	case EfiRuntimeServicesData:
     96  1.1  nonaka 	case EfiUnusableMemory:
     97  1.1  nonaka 	case EfiMemoryMappedIO:
     98  1.1  nonaka 	case EfiMemoryMappedIOPortSpace:
     99  1.1  nonaka 	case EfiPalCode:
    100  1.1  nonaka 	case EfiMaxMemoryType:
    101  1.4  nonaka 	default:
    102  1.1  nonaka 		return BIM_Reserved;
    103  1.1  nonaka 	}
    104  1.1  nonaka }
    105  1.1  nonaka 
    106  1.3  nonaka EFI_MEMORY_DESCRIPTOR *
    107  1.3  nonaka efi_memory_get_map(UINTN *NoEntries, UINTN *MapKey, UINTN *DescriptorSize,
    108  1.3  nonaka     UINT32 *DescriptorVersion, bool sorted)
    109  1.1  nonaka {
    110  1.7  nonaka 	EFI_MEMORY_DESCRIPTOR *desc, *md, *next, *target, *tmp;
    111  1.1  nonaka 	UINTN i, j;
    112  1.1  nonaka 
    113  1.1  nonaka 	*NoEntries = 0;
    114  1.1  nonaka 	desc = LibMemoryMap(NoEntries, MapKey, DescriptorSize,
    115  1.1  nonaka 	    DescriptorVersion);
    116  1.1  nonaka 	if (desc == NULL)
    117  1.5  nonaka 		panic("efi_memory_get_map failed");
    118  1.1  nonaka 
    119  1.1  nonaka 	if (!sorted)
    120  1.1  nonaka 		return desc;
    121  1.1  nonaka 
    122  1.7  nonaka 	tmp = alloc(*DescriptorSize);
    123  1.7  nonaka 	if (tmp == NULL)
    124  1.7  nonaka 		return desc;
    125  1.7  nonaka 
    126  1.1  nonaka 	for (i = 0, md = desc; i < *NoEntries - 1; i++, md = next) {
    127  1.1  nonaka 		target = next = NextMemoryDescriptor(md, *DescriptorSize);
    128  1.1  nonaka 		for (j = i + 1; j < *NoEntries; j++) {
    129  1.1  nonaka 			if (md->PhysicalStart > target->PhysicalStart) {
    130  1.7  nonaka 				CopyMem(tmp, md, *DescriptorSize);
    131  1.7  nonaka 				CopyMem(md, target, *DescriptorSize);
    132  1.7  nonaka 				CopyMem(target, tmp, *DescriptorSize);
    133  1.1  nonaka 			}
    134  1.1  nonaka 			target = NextMemoryDescriptor(target, *DescriptorSize);
    135  1.1  nonaka 		}
    136  1.1  nonaka 	}
    137  1.7  nonaka 	dealloc(tmp, *DescriptorSize);
    138  1.7  nonaka 
    139  1.7  nonaka 	return desc;
    140  1.7  nonaka }
    141  1.7  nonaka 
    142  1.7  nonaka EFI_MEMORY_DESCRIPTOR *
    143  1.7  nonaka efi_memory_compact_map(EFI_MEMORY_DESCRIPTOR *desc, UINTN *NoEntries,
    144  1.7  nonaka     UINTN DescriptorSize)
    145  1.7  nonaka {
    146  1.7  nonaka 	EFI_MEMORY_DESCRIPTOR *md, *next, *target, *tmp;
    147  1.7  nonaka 	UINTN i, j;
    148  1.7  nonaka 	UINT32 type;
    149  1.7  nonaka 	bool first = true, do_compact;
    150  1.7  nonaka 
    151  1.7  nonaka 	for (i = 0, md = target = desc; i < *NoEntries; i++, md = next) {
    152  1.7  nonaka 		type = md->Type;
    153  1.7  nonaka 		switch (type) {
    154  1.7  nonaka 		case EfiLoaderCode:
    155  1.7  nonaka 		case EfiLoaderData:
    156  1.7  nonaka 		case EfiBootServicesCode:
    157  1.7  nonaka 		case EfiBootServicesData:
    158  1.7  nonaka 		case EfiConventionalMemory:
    159  1.7  nonaka 			if ((md->Attribute & EFI_MEMORY_WB) != 0)
    160  1.7  nonaka 				type = EfiConventionalMemory;
    161  1.7  nonaka 			if (md->Attribute == target->Attribute) {
    162  1.7  nonaka 				do_compact = true;
    163  1.7  nonaka 				break;
    164  1.7  nonaka 			}
    165  1.7  nonaka 			/* FALLTHROUGH */
    166  1.7  nonaka 		case EfiACPIReclaimMemory:
    167  1.7  nonaka 		case EfiACPIMemoryNVS:
    168  1.7  nonaka 		case EfiPersistentMemory:
    169  1.7  nonaka 		case EfiReservedMemoryType:
    170  1.7  nonaka 		case EfiRuntimeServicesCode:
    171  1.7  nonaka 		case EfiRuntimeServicesData:
    172  1.7  nonaka 		case EfiUnusableMemory:
    173  1.7  nonaka 		case EfiMemoryMappedIO:
    174  1.7  nonaka 		case EfiMemoryMappedIOPortSpace:
    175  1.7  nonaka 		case EfiPalCode:
    176  1.7  nonaka 		default:
    177  1.7  nonaka 			do_compact = false;
    178  1.7  nonaka 			break;
    179  1.7  nonaka 		}
    180  1.7  nonaka 
    181  1.7  nonaka 		if (first) {
    182  1.7  nonaka 			first = false;
    183  1.7  nonaka 		} else if (do_compact &&
    184  1.7  nonaka 		    type == target->Type &&
    185  1.7  nonaka 		    md->Attribute == target->Attribute &&
    186  1.7  nonaka 		    md->PhysicalStart == target->PhysicalStart + target->NumberOfPages * EFI_PAGE_SIZE) {
    187  1.7  nonaka 			/* continuous region */
    188  1.7  nonaka 			target->NumberOfPages += md->NumberOfPages;
    189  1.7  nonaka 
    190  1.7  nonaka 			tmp = md;
    191  1.7  nonaka 			for (j = i + 1; j < *NoEntries; j++) {
    192  1.7  nonaka 				next = NextMemoryDescriptor(md, DescriptorSize);
    193  1.7  nonaka 				CopyMem(md, next, DescriptorSize);
    194  1.7  nonaka 				md = next;
    195  1.7  nonaka 			}
    196  1.7  nonaka 			next = tmp;
    197  1.7  nonaka 
    198  1.7  nonaka 			i--;
    199  1.7  nonaka 			(*NoEntries)--;
    200  1.7  nonaka 			continue;
    201  1.7  nonaka 		} else {
    202  1.7  nonaka 			target = md;
    203  1.7  nonaka 		}
    204  1.7  nonaka 
    205  1.7  nonaka 		target->Type = type;
    206  1.7  nonaka 		next = NextMemoryDescriptor(md, DescriptorSize);
    207  1.7  nonaka 	}
    208  1.7  nonaka 
    209  1.1  nonaka 	return desc;
    210  1.1  nonaka }
    211  1.1  nonaka 
    212  1.1  nonaka /*
    213  1.1  nonaka  * get memory size below 1MB
    214  1.1  nonaka  */
    215  1.1  nonaka int
    216  1.1  nonaka getbasemem(void)
    217  1.1  nonaka {
    218  1.1  nonaka 	EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
    219  1.1  nonaka 	UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
    220  1.1  nonaka 	UINT32 DescriptorVersion;
    221  1.1  nonaka 	EFI_PHYSICAL_ADDRESS basemem = 0, epa;
    222  1.1  nonaka 
    223  1.3  nonaka 	mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
    224  1.1  nonaka 	    &DescriptorVersion, true);
    225  1.1  nonaka 
    226  1.1  nonaka 	for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
    227  1.1  nonaka 		next = NextMemoryDescriptor(md, DescriptorSize);
    228  1.1  nonaka 		if (getmemtype(md) != BIM_Memory)
    229  1.1  nonaka 			continue;
    230  1.1  nonaka 		if (md->PhysicalStart >= 1 * 1024 * 1024)
    231  1.1  nonaka 			continue;
    232  1.1  nonaka 		if (basemem != md->PhysicalStart)
    233  1.1  nonaka 			continue;
    234  1.1  nonaka 
    235  1.1  nonaka 		MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
    236  1.1  nonaka 		epa = md->PhysicalStart + MappingSize;
    237  1.1  nonaka 		if (epa == 0 || epa > 1 * 1024 * 1024)
    238  1.1  nonaka 			epa = 1 * 1024 * 1024;
    239  1.1  nonaka 		basemem = epa;
    240  1.1  nonaka 	}
    241  1.1  nonaka 
    242  1.1  nonaka 	FreePool(mdtop);
    243  1.1  nonaka 
    244  1.1  nonaka 	return basemem / 1024;	/* KiB */
    245  1.1  nonaka }
    246  1.1  nonaka 
    247  1.1  nonaka /*
    248  1.1  nonaka  * get memory size above 1MB below 4GB
    249  1.1  nonaka  */
    250  1.1  nonaka int
    251  1.1  nonaka getextmemx(void)
    252  1.1  nonaka {
    253  1.1  nonaka 	EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
    254  1.1  nonaka 	UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
    255  1.1  nonaka 	UINT32 DescriptorVersion;
    256  1.1  nonaka 	EFI_PHYSICAL_ADDRESS extmem16m = 0;	/* 0-16MB */
    257  1.1  nonaka 	EFI_PHYSICAL_ADDRESS extmem4g = 0;	/* 16MB-4GB */
    258  1.1  nonaka 	EFI_PHYSICAL_ADDRESS pa, epa;
    259  1.1  nonaka 	bool first16m = true, first4g = true;
    260  1.1  nonaka 	int extmem;
    261  1.1  nonaka 
    262  1.3  nonaka 	mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
    263  1.1  nonaka 	    &DescriptorVersion, true);
    264  1.1  nonaka 
    265  1.1  nonaka 	for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
    266  1.1  nonaka 		next = NextMemoryDescriptor(md, DescriptorSize);
    267  1.1  nonaka 		if (getmemtype(md) == BIM_Reserved)
    268  1.1  nonaka 			continue;
    269  1.1  nonaka 		if (md->PhysicalStart >= 4 * 1024 * 1024 * 1024ULL)
    270  1.1  nonaka 			continue;
    271  1.1  nonaka 
    272  1.1  nonaka 		MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
    273  1.1  nonaka 		epa = md->PhysicalStart + MappingSize;
    274  1.1  nonaka 		if (epa == 0 || epa > 4 * 1024 * 1024 * 1024LL)
    275  1.1  nonaka 			epa = 4 * 1024 * 1024 * 1024LL;
    276  1.1  nonaka 
    277  1.1  nonaka 		if (epa <= 1 * 1024 * 1024)
    278  1.1  nonaka 			continue;
    279  1.1  nonaka 
    280  1.1  nonaka 		pa = md->PhysicalStart;
    281  1.1  nonaka 		if (pa < 16 * 1024 * 1024) {
    282  1.1  nonaka 			if (first16m || extmem16m == pa) {
    283  1.1  nonaka 				first16m = false;
    284  1.1  nonaka 				if (epa >= 16 * 1024 * 1024) {
    285  1.1  nonaka 					extmem16m = 16 * 1024 * 1024;
    286  1.1  nonaka 					pa = 16 * 1024 * 1024;
    287  1.1  nonaka 				} else
    288  1.1  nonaka 					extmem16m = epa;
    289  1.1  nonaka 			}
    290  1.1  nonaka 		}
    291  1.1  nonaka 		if (pa >= 16 * 1024 * 1024) {
    292  1.1  nonaka 			if (first4g || extmem4g == pa) {
    293  1.1  nonaka 				first4g = false;
    294  1.1  nonaka 				extmem4g = epa;
    295  1.1  nonaka 			}
    296  1.1  nonaka 		}
    297  1.1  nonaka 	}
    298  1.1  nonaka 
    299  1.1  nonaka 	FreePool(mdtop);
    300  1.1  nonaka 
    301  1.1  nonaka 	if (extmem16m > 1 * 1024 * 1024)
    302  1.1  nonaka 		extmem16m -= 1 * 1024 * 1024;	/* below 1MB */
    303  1.1  nonaka 
    304  1.1  nonaka 	extmem = extmem16m / 1024;
    305  1.1  nonaka 	if (extmem == 15 * 1024)
    306  1.1  nonaka 		extmem += extmem4g / 1024;
    307  1.1  nonaka 	return extmem;
    308  1.1  nonaka }
    309  1.1  nonaka 
    310  1.1  nonaka void
    311  1.1  nonaka efi_memory_probe(void)
    312  1.1  nonaka {
    313  1.1  nonaka 	EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
    314  1.6  nonaka 	EFI_STATUS status;
    315  1.6  nonaka 	EFI_PHYSICAL_ADDRESS bouncebuf;
    316  1.1  nonaka 	UINTN i, n, NoEntries, MapKey, DescriptorSize, MappingSize;
    317  1.1  nonaka 	UINT32 DescriptorVersion;
    318  1.1  nonaka 	int memtype;
    319  1.1  nonaka 
    320  1.6  nonaka 	bouncebuf = EFI_ALLOCATE_MAX_ADDRESS;
    321  1.6  nonaka 	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
    322  1.6  nonaka 	    EfiLoaderData, EFI_SIZE_TO_PAGES(KERN_LOADSPACE_SIZE), &bouncebuf);
    323  1.6  nonaka 	if (EFI_ERROR(status))
    324  1.6  nonaka 		panic("couldn't allocate kernel space.");
    325  1.6  nonaka 	efi_loadaddr = bouncebuf;
    326  1.6  nonaka 
    327  1.3  nonaka 	mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
    328  1.1  nonaka 	    &DescriptorVersion, false);
    329  1.5  nonaka 	printf(" mem[");
    330  1.1  nonaka 	for (i = 0, n = 0, md = mdtop; i < NoEntries; i++, md = next) {
    331  1.1  nonaka 		next = NextMemoryDescriptor(md, DescriptorSize);
    332  1.1  nonaka 
    333  1.1  nonaka 		memtype = getmemtype(md);
    334  1.1  nonaka 		if (memtype != BIM_Memory)
    335  1.1  nonaka 			continue;
    336  1.1  nonaka 
    337  1.1  nonaka 		MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
    338  1.1  nonaka 		if (MappingSize < 12 * 1024)	/* XXX Why? from OpenBSD */
    339  1.1  nonaka 			continue;
    340  1.1  nonaka 
    341  1.1  nonaka 		if (n++ > 0)
    342  1.5  nonaka 			printf(" ");
    343  1.5  nonaka 		printf("0x%" PRIxMAX "-0x%" PRIxMAX, (uintmax_t)md->PhysicalStart,
    344  1.5  nonaka 		    (uintmax_t)(md->PhysicalStart + MappingSize - 1));
    345  1.1  nonaka 	}
    346  1.5  nonaka 	printf("]\n");
    347  1.1  nonaka 
    348  1.1  nonaka 	FreePool(mdtop);
    349  1.1  nonaka }
    350  1.1  nonaka 
    351  1.1  nonaka void
    352  1.7  nonaka efi_memory_show_map(bool sorted, bool compact)
    353  1.1  nonaka {
    354  1.1  nonaka 	EFI_STATUS status;
    355  1.1  nonaka 	EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
    356  1.1  nonaka 	UINTN i, NoEntries, MapKey, DescriptorSize;
    357  1.1  nonaka 	UINT32 DescriptorVersion;
    358  1.1  nonaka 	char memstr[32], efimemstr[32];
    359  1.1  nonaka 	int memtype;
    360  1.1  nonaka 	UINTN cols, rows, row = 0;
    361  1.1  nonaka 
    362  1.1  nonaka 	status = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
    363  1.1  nonaka 	    ST->ConOut->Mode->Mode, &cols, &rows);
    364  1.1  nonaka 	if (EFI_ERROR(status) || rows <= 2)
    365  1.1  nonaka 		rows = 0;
    366  1.1  nonaka 	else
    367  1.1  nonaka 		rows -= 2;
    368  1.1  nonaka 
    369  1.3  nonaka 	mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
    370  1.1  nonaka 	    &DescriptorVersion, sorted);
    371  1.7  nonaka 	if (compact)
    372  1.7  nonaka 		efi_memory_compact_map(mdtop, &NoEntries, DescriptorSize);
    373  1.1  nonaka 
    374  1.1  nonaka 	for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
    375  1.1  nonaka 		next = NextMemoryDescriptor(md, DescriptorSize);
    376  1.1  nonaka 
    377  1.1  nonaka 		memtype = getmemtype(md);
    378  1.1  nonaka 		if (memtype >= __arraycount(memtypes))
    379  1.1  nonaka 			snprintf(memstr, sizeof(memstr), "unknown (%d)",
    380  1.1  nonaka 			    memtype);
    381  1.1  nonaka 		if (md->Type >= __arraycount(efimemtypes))
    382  1.1  nonaka 			snprintf(efimemstr, sizeof(efimemstr), "unknown (%d)",
    383  1.1  nonaka 			    md->Type);
    384  1.1  nonaka 		printf("%016" PRIxMAX "/%016" PRIxMAX ": %s [%s]\n",
    385  1.1  nonaka 		    (uintmax_t)md->PhysicalStart,
    386  1.1  nonaka 		    (uintmax_t)md->PhysicalStart +
    387  1.1  nonaka 		      md->NumberOfPages * EFI_PAGE_SIZE - 1,
    388  1.1  nonaka 		    memtype >= __arraycount(memtypes) ?
    389  1.1  nonaka 		      memstr : memtypes[memtype],
    390  1.1  nonaka 		    md->Type >= __arraycount(efimemtypes) ?
    391  1.1  nonaka 		      efimemstr : efimemtypes[md->Type]);
    392  1.1  nonaka 
    393  1.2     roy 		if (++row >= rows) {
    394  1.1  nonaka 			row = 0;
    395  1.5  nonaka 			printf("Press Any Key to continue :");
    396  1.1  nonaka 			(void) awaitkey(-1, 0);
    397  1.5  nonaka 			printf("\n");
    398  1.1  nonaka 		}
    399  1.1  nonaka 	}
    400  1.1  nonaka 
    401  1.1  nonaka 	FreePool(mdtop);
    402  1.1  nonaka }
    403  1.1  nonaka 
    404  1.1  nonaka void
    405  1.1  nonaka vpbcopy(const void *va, void *pa, size_t n)
    406  1.1  nonaka {
    407  1.1  nonaka 	memmove(pa, va, n);
    408  1.1  nonaka }
    409  1.1  nonaka 
    410  1.1  nonaka void
    411  1.1  nonaka pvbcopy(const void *pa, void *va, size_t n)
    412  1.1  nonaka {
    413  1.1  nonaka 	memmove(va, pa, n);
    414  1.1  nonaka }
    415  1.1  nonaka 
    416  1.1  nonaka void
    417  1.1  nonaka pbzero(void *pa, size_t n)
    418  1.1  nonaka {
    419  1.1  nonaka 	memset(pa, 0, n);
    420  1.1  nonaka }
    421  1.1  nonaka 
    422  1.1  nonaka physaddr_t
    423  1.1  nonaka vtophys(void *va)
    424  1.1  nonaka {
    425  1.1  nonaka 	return (physaddr_t)va;
    426  1.1  nonaka }
    427