From owner-svn-src-head@FreeBSD.ORG Sat Sep 13 03:10:03 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2213AED7; Sat, 13 Sep 2014 03:10:03 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 02417E29; Sat, 13 Sep 2014 03:10:03 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8D3A2Hx031104; Sat, 13 Sep 2014 03:10:02 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8D3A2OF031100; Sat, 13 Sep 2014 03:10:02 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201409130310.s8D3A2OF031100@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Sat, 13 Sep 2014 03:10:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r271495 - in head: sbin/sysctl sys/amd64/amd64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Sep 2014 03:10:03 -0000 Author: jhb Date: Sat Sep 13 03:10:02 2014 New Revision: 271495 URL: http://svnweb.freebsd.org/changeset/base/271495 Log: Add a sysctl to export the EFI memory map along with a handler in the sysctl(8) binary to format it. Reviewed by: emaste MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D771 Modified: head/sbin/sysctl/sysctl.c head/sys/amd64/amd64/machdep.c Modified: head/sbin/sysctl/sysctl.c ============================================================================== --- head/sbin/sysctl/sysctl.c Sat Sep 13 02:18:54 2014 (r271494) +++ head/sbin/sysctl/sysctl.c Sat Sep 13 03:10:02 2014 (r271495) @@ -48,6 +48,11 @@ static const char rcsid[] = #include #include +#ifdef __amd64__ +#include +#include +#endif + #if defined(__amd64__) || defined(__i386__) #include #endif @@ -545,6 +550,91 @@ S_vmtotal(size_t l2, void *p) return (0); } +#ifdef __amd64__ +#define efi_next_descriptor(ptr, size) \ + ((struct efi_md *)(((uint8_t *) ptr) + size)) + +static int +S_efi_map(size_t l2, void *p) +{ + struct efi_map_header *efihdr; + struct efi_md *map; + const char *type; + size_t efisz; + int ndesc, i; + + static const char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode" + }; + + /* + * Memory map data provided by UEFI via the GetMemoryMap + * Boot Services API. + */ + if (l2 < sizeof(*efihdr)) { + warnx("S_efi_map length less than header"); + return (1); + } + efihdr = p; + efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; + map = (struct efi_md *)((uint8_t *)efihdr + efisz); + + if (efihdr->descriptor_size == 0) + return (0); + if (l2 != efisz + efihdr->memory_size) { + warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz + + efihdr->memory_size); + return (1); + } + ndesc = efihdr->memory_size / efihdr->descriptor_size; + + printf("\n%23s %12s %12s %8s %4s", + "Type", "Physical", "Virtual", "#Pages", "Attr"); + + for (i = 0; i < ndesc; i++, + map = efi_next_descriptor(map, efihdr->descriptor_size)) { + if (map->md_type <= EFI_MD_TYPE_PALCODE) + type = types[map->md_type]; + else + type = ""; + printf("\n%23s %012lx %12p %08lx ", type, map->md_phys, + map->md_virt, map->md_pages); + if (map->md_attr & EFI_MD_ATTR_UC) + printf("UC "); + if (map->md_attr & EFI_MD_ATTR_WC) + printf("WC "); + if (map->md_attr & EFI_MD_ATTR_WT) + printf("WT "); + if (map->md_attr & EFI_MD_ATTR_WB) + printf("WB "); + if (map->md_attr & EFI_MD_ATTR_UCE) + printf("UCE "); + if (map->md_attr & EFI_MD_ATTR_WP) + printf("WP "); + if (map->md_attr & EFI_MD_ATTR_RP) + printf("RP "); + if (map->md_attr & EFI_MD_ATTR_XP) + printf("XP "); + if (map->md_attr & EFI_MD_ATTR_RT) + printf("RUNTIME"); + } + return (0); +} +#endif + #if defined(__amd64__) || defined(__i386__) static int S_bios_smap_xattr(size_t l2, void *p) @@ -818,6 +908,10 @@ show_var(int *oid, int nlen) func = S_loadavg; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; +#ifdef __amd64__ + else if (strcmp(fmt, "S,efi_map_header") == 0) + func = S_efi_map; +#endif #if defined(__amd64__) || defined(__i386__) else if (strcmp(fmt, "S,bios_smap_xattr") == 0) func = S_bios_smap_xattr; Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Sat Sep 13 02:18:54 2014 (r271494) +++ head/sys/amd64/amd64/machdep.c Sat Sep 13 03:10:02 2014 (r271495) @@ -2124,6 +2124,26 @@ smap_sysctl_handler(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_machdep, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0, smap_sysctl_handler, "S,bios_smap_xattr", "Raw BIOS SMAP data"); +static int +efi_map_sysctl_handler(SYSCTL_HANDLER_ARGS) +{ + struct efi_map_header *efihdr; + caddr_t kmdp; + uint32_t efisize; + + kmdp = preload_search_by_type("elf kernel"); + if (kmdp == NULL) + kmdp = preload_search_by_type("elf64 kernel"); + efihdr = (struct efi_map_header *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_EFI_MAP); + if (efihdr == NULL) + return (0); + efisize = *((uint32_t *)efihdr - 1); + return (SYSCTL_OUT(req, efihdr, efisize)); +} +SYSCTL_PROC(_machdep, OID_AUTO, efi_map, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0, + efi_map_sysctl_handler, "S,efi_map_header", "Raw EFI Memory Map"); + void spinlock_enter(void) {