Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/bouyer-socketcan]: src/sys/arch/i386/stand/efiboot 1210367
details: https://anonhg.NetBSD.org/src/rev/4c1d84e1de56
branches: bouyer-socketcan
changeset: 820838:4c1d84e1de56
user: nonaka <nonaka%NetBSD.org@localhost>
date: Tue Feb 14 13:29:10 2017 +0000
description:
1210367
diffstat:
sys/arch/i386/stand/efiboot/efimemory.c | 336 ++++++++++++++++++++++++++++++++
1 files changed, 336 insertions(+), 0 deletions(-)
diffs (truncated from 340 to 300 lines):
diff -r d7cb5100a41b -r 4c1d84e1de56 sys/arch/i386/stand/efiboot/efimemory.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/efiboot/efimemory.c Tue Feb 14 13:29:10 2017 +0000
@@ -0,0 +1,336 @@
+/* $NetBSD: efimemory.c,v 1.4.6.2 2017/02/14 13:29:10 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "efiboot.h"
+
+#include <bootinfo.h>
+
+static const char *memtypes[] = {
+ "unknown",
+ "available",
+ "reserved",
+ "ACPI reclaimable",
+ "ACPI NVS",
+ "unusable",
+ "disabled",
+ "Persistent",
+ "undefined (8)",
+ "undefined (9)",
+ "undefined (10)",
+ "undefined (11)",
+ "Persistent (Legacy)"
+};
+
+static const char *efimemtypes[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode",
+ "PersistentMemory",
+};
+
+static int
+getmemtype(EFI_MEMORY_DESCRIPTOR *md)
+{
+
+ switch (md->Type) {
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ return (md->Attribute & EFI_MEMORY_WB) ?
+ BIM_Memory : BIM_Reserved;
+
+ case EfiACPIReclaimMemory:
+ return BIM_ACPI;
+
+ case EfiACPIMemoryNVS:
+ return BIM_NVS;
+
+ case EfiPersistentMemory:
+ return BIM_PMEM;
+
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiUnusableMemory:
+ case EfiMemoryMappedIO:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ case EfiMaxMemoryType:
+ default:
+ return BIM_Reserved;
+ }
+}
+
+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;
+ UINTN i, j;
+
+ *NoEntries = 0;
+ desc = LibMemoryMap(NoEntries, MapKey, DescriptorSize,
+ DescriptorVersion);
+ if (desc == NULL)
+ Panic(L"efi_memory_get_map failed");
+
+ if (!sorted)
+ 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));
+ }
+ target = NextMemoryDescriptor(target, *DescriptorSize);
+ }
+ }
+ return desc;
+}
+
+/*
+ * get memory size below 1MB
+ */
+int
+getbasemem(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ EFI_PHYSICAL_ADDRESS basemem = 0, epa;
+
+ mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, true);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+ if (getmemtype(md) != BIM_Memory)
+ continue;
+ if (md->PhysicalStart >= 1 * 1024 * 1024)
+ continue;
+ if (basemem != md->PhysicalStart)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ epa = md->PhysicalStart + MappingSize;
+ if (epa == 0 || epa > 1 * 1024 * 1024)
+ epa = 1 * 1024 * 1024;
+ basemem = epa;
+ }
+
+ FreePool(mdtop);
+
+ return basemem / 1024; /* KiB */
+}
+
+/*
+ * get memory size above 1MB below 4GB
+ */
+int
+getextmemx(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ EFI_PHYSICAL_ADDRESS extmem16m = 0; /* 0-16MB */
+ EFI_PHYSICAL_ADDRESS extmem4g = 0; /* 16MB-4GB */
+ EFI_PHYSICAL_ADDRESS pa, epa;
+ bool first16m = true, first4g = true;
+ int extmem;
+
+ mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, true);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+ if (getmemtype(md) == BIM_Reserved)
+ continue;
+ if (md->PhysicalStart >= 4 * 1024 * 1024 * 1024ULL)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ epa = md->PhysicalStart + MappingSize;
+ if (epa == 0 || epa > 4 * 1024 * 1024 * 1024LL)
+ epa = 4 * 1024 * 1024 * 1024LL;
+
+ if (epa <= 1 * 1024 * 1024)
+ continue;
+
+ pa = md->PhysicalStart;
+ if (pa < 16 * 1024 * 1024) {
+ if (first16m || extmem16m == pa) {
+ first16m = false;
+ if (epa >= 16 * 1024 * 1024) {
+ extmem16m = 16 * 1024 * 1024;
+ pa = 16 * 1024 * 1024;
+ } else
+ extmem16m = epa;
+ }
+ }
+ if (pa >= 16 * 1024 * 1024) {
+ if (first4g || extmem4g == pa) {
+ first4g = false;
+ extmem4g = epa;
+ }
+ }
+ }
+
+ FreePool(mdtop);
+
+ if (extmem16m > 1 * 1024 * 1024)
+ extmem16m -= 1 * 1024 * 1024; /* below 1MB */
+
+ extmem = extmem16m / 1024;
+ if (extmem == 15 * 1024)
+ extmem += extmem4g / 1024;
+ return extmem;
+}
+
+void
+efi_memory_probe(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, n, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ int memtype;
+
+ mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, false);
+
+ Print(L" mem[");
+ for (i = 0, n = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+
+ memtype = getmemtype(md);
+ if (memtype != BIM_Memory)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ if (MappingSize < 12 * 1024) /* XXX Why? from OpenBSD */
+ continue;
+
+ if (n++ > 0)
+ Print(L" ");
+ Print(L"0x%lx-0x%lx", md->PhysicalStart,
+ md->PhysicalStart + MappingSize - 1);
+ }
+ Print(L"]");
+
+ FreePool(mdtop);
+}
+
+void
+efi_memory_show_map(bool sorted)
+{
+ EFI_STATUS status;
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize;
+ UINT32 DescriptorVersion;
+ char memstr[32], efimemstr[32];
+ int memtype;
+ UINTN cols, rows, row = 0;
+
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+ ST->ConOut->Mode->Mode, &cols, &rows);
+ if (EFI_ERROR(status) || rows <= 2)
+ rows = 0;
+ else
+ rows -= 2;
+
+ mdtop = efi_memory_get_map(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, sorted);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+
+ memtype = getmemtype(md);
+ if (memtype >= __arraycount(memtypes))
+ snprintf(memstr, sizeof(memstr), "unknown (%d)",
+ memtype);
+ if (md->Type >= __arraycount(efimemtypes))
+ snprintf(efimemstr, sizeof(efimemstr), "unknown (%d)",
+ md->Type);
+ printf("%016" PRIxMAX "/%016" PRIxMAX ": %s [%s]\n",
+ (uintmax_t)md->PhysicalStart,
+ (uintmax_t)md->PhysicalStart +
Home |
Main Index |
Thread Index |
Old Index