x86: make btinfo_memmap from btinfo_efimemmap for to reduce mem_cluster_cnt.

should fix PR/51953.
This commit is contained in:
nonaka 2017-02-14 13:23:50 +00:00
parent 72128ffa3a
commit 218e65dc4f
4 changed files with 141 additions and 107 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_machdep.c,v 1.16 2017/02/09 11:56:40 nonaka Exp $ */ /* $NetBSD: acpi_machdep.c,v 1.17 2017/02/14 13:23:50 nonaka Exp $ */
/* /*
* Copyright 2001 Wasabi Systems, Inc. * Copyright 2001 Wasabi Systems, Inc.
@ -40,7 +40,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.16 2017/02/09 11:56:40 nonaka Exp $"); __KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.17 2017/02/14 13:23:50 nonaka Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -366,62 +366,36 @@ acpi_md_ncpus(void)
static bool static bool
acpi_md_mcfg_validate(uint64_t addr, int bus_start, int *bus_end) acpi_md_mcfg_validate(uint64_t addr, int bus_start, int *bus_end)
{ {
union { struct btinfo_memmap *bim;
struct btinfo_common *common;
struct btinfo_memmap *bios;
struct btinfo_efimemmap *efi;
} bim;
uint64_t size, mapaddr, mapsize; uint64_t size, mapaddr, mapsize;
uint32_t type; uint32_t type;
int i, n, num; int i, n;
bool efimemmap;
bim.common = lookup_bootinfo(BTINFO_EFIMEMMAP); #ifndef XEN
if (bim.common == NULL) { if (lookup_bootinfo(BTINFO_EFIMEMMAP) != NULL)
bim.common = lookup_bootinfo(BTINFO_MEMMAP); bim = efi_get_e820memmap();
if (bim.common == NULL) else
return false; #endif
} bim = lookup_bootinfo(BTINFO_MEMMAP);
efimemmap = bim.common->type == BTINFO_EFIMEMMAP; if (bim == NULL)
num = efimemmap ? bim.efi->num : bim.bios->num; return false;
size = *bus_end - bus_start + 1; size = *bus_end - bus_start + 1;
size *= ACPIMCFG_SIZE_PER_BUS; size *= ACPIMCFG_SIZE_PER_BUS;
for (i = 0; i < num; i++) { for (i = 0; i < bim->num; i++) {
#ifndef XEN mapaddr = bim->entry[i].addr;
if (efimemmap) { mapsize = bim->entry[i].size;
struct efi_md *md = (struct efi_md *) type = bim->entry[i].type;
(bim.efi->memmap + bim.efi->size * i);
mapaddr = md->md_phys;
mapsize = md->md_pages * EFI_PAGE_SIZE;
type = efi_getbiosmemtype(md->md_type, md->md_attr);
aprint_debug("MCFG: MEMMAP: " aprint_debug("MCFG: MEMMAP: 0x%016" PRIx64
"p0x%016" PRIx64 "-0x%016" PRIx64 "-0x%016" PRIx64 ", size=0x%016" PRIx64
", v0x%016" PRIx64 "-0x%016" PRIx64 ", type=%d(%s)\n",
", size=0x%016" PRIx64 ", attr=0x%016" PRIx64 mapaddr, mapaddr + mapsize - 1, mapsize, type,
", type=%d(%s)\n", (type == BIM_Memory) ? "Memory" :
mapaddr, mapaddr + mapsize - 1, (type == BIM_Reserved) ? "Reserved" :
md->md_virt, md->md_virt + mapsize - 1, (type == BIM_ACPI) ? "ACPI" :
size, md->md_attr, md->md_type, (type == BIM_NVS) ? "NVS" :
efi_getmemtype_str(md->md_type)); "unknown");
} else
#endif
{
mapaddr = bim.bios->entry[i].addr;
mapsize = bim.bios->entry[i].size;
type = bim.bios->entry[i].type;
aprint_debug("MCFG: MEMMAP: 0x%016" PRIx64
"-0x%016" PRIx64 ", size=0x%016" PRIx64
", type=%d(%s)\n",
mapaddr, mapaddr + mapsize - 1, mapsize, type,
(type == BIM_Memory) ? "Memory" :
(type == BIM_Reserved) ? "Reserved" :
(type == BIM_ACPI) ? "ACPI" :
(type == BIM_NVS) ? "NVS" :
"unknown");
}
switch (type) { switch (type) {
case BIM_ACPI: case BIM_ACPI:

View File

@ -1,4 +1,4 @@
/* $NetBSD: efi.h,v 1.3 2017/02/09 11:56:40 nonaka Exp $ */ /* $NetBSD: efi.h,v 1.4 2017/02/14 13:23:50 nonaka Exp $ */
/*- /*-
* Copyright (c) 2004 Marcel Moolenaar * Copyright (c) 2004 Marcel Moolenaar
@ -165,6 +165,9 @@ paddr_t efi_getcfgtblpa(const struct uuid*);
void *efi_getcfgtbl(const struct uuid*); void *efi_getcfgtbl(const struct uuid*);
int efi_getbiosmemtype(uint32_t, uint64_t); int efi_getbiosmemtype(uint32_t, uint64_t);
const char *efi_getmemtype_str(uint32_t); const char *efi_getmemtype_str(uint32_t);
struct btinfo_memmap;
struct btinfo_memmap *efi_get_e820memmap(void);
/* /*
void efi_boot_finish(void); void efi_boot_finish(void);
int efi_boot_minimal(uint64_t); int efi_boot_minimal(uint64_t);

View File

@ -1,4 +1,5 @@
/* $NetBSD: efi.c,v 1.6 2017/01/26 01:35:51 nonaka Exp $ */ /* $NetBSD: efi.c,v 1.7 2017/02/14 13:23:50 nonaka Exp $ */
/*- /*-
* Copyright (c) 2016 The NetBSD Foundation, Inc. * Copyright (c) 2016 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
@ -24,8 +25,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.6 2017/01/26 01:35:51 nonaka Exp $"); __KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.7 2017/02/14 13:23:50 nonaka Exp $");
#include <sys/kmem.h> #include <sys/kmem.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -65,6 +68,10 @@ bool efi_uuideq(const struct uuid *, const struct uuid *);
static bool efi_is32bit = false; static bool efi_is32bit = false;
static struct efi_systbl *efi_systbl_va = NULL; static struct efi_systbl *efi_systbl_va = NULL;
static struct efi_cfgtbl *efi_cfgtblhead_va = NULL; static struct efi_cfgtbl *efi_cfgtblhead_va = NULL;
static struct efi_e820memmap {
struct btinfo_memmap bim;
struct bi_memmap_entry entry[VM_PHYSSEG_MAX - 1];
} efi_e820memmap;
/* /*
* Map a physical address (PA) to a newly allocated virtual address (VA). * Map a physical address (PA) to a newly allocated virtual address (VA).
@ -349,3 +356,75 @@ efi_getmemtype_str(uint32_t type)
return efimemtypes[type]; return efimemtypes[type];
return "unknown"; return "unknown";
} }
struct btinfo_memmap *
efi_get_e820memmap(void)
{
struct btinfo_efimemmap *efimm;
struct bi_memmap_entry *entry;
struct efi_md *md;
uint64_t addr, size;
uint64_t start_addr, end_addr;
uint32_t i;
int n, type, seg_type = -1;
if (efi_e820memmap.bim.common.type == BTINFO_MEMMAP)
return &efi_e820memmap.bim;
efimm = lookup_bootinfo(BTINFO_EFIMEMMAP);
if (efimm == NULL)
return NULL;
for (n = 0, i = 0; i < efimm->num; i++) {
md = (struct efi_md *)(efimm->memmap + efimm->size * i);
addr = md->md_phys;
size = md->md_pages * EFI_PAGE_SIZE;
type = efi_getbiosmemtype(md->md_type, md->md_attr);
#ifdef DEBUG_MEMLOAD
printf("MEMMAP: p0x%016" PRIx64 "-0x%016" PRIx64
", v0x%016" PRIx64 "-0x%016" PRIx64
", size=0x%016" PRIx64 ", attr=0x%016" PRIx64
", type=%d(%s)\n",
addr, addr + size - 1,
md->md_virt, md->md_virt + size - 1,
size, md->md_attr, md->md_type,
efi_getmemtype_str(md->md_type));
#endif
if (seg_type == -1) {
/* first entry */
} else if (seg_type == type && end_addr == addr) {
/* continuous region */
end_addr = addr + size;
continue;
} else {
entry = &efi_e820memmap.bim.entry[n];
entry->addr = start_addr;
entry->size = end_addr - start_addr;
entry->type = seg_type;
if (++n == VM_PHYSSEG_MAX)
break;
}
start_addr = addr;
end_addr = addr + size;
seg_type = type;
}
if (i > 0 && n < VM_PHYSSEG_MAX) {
entry = &efi_e820memmap.bim.entry[n];
entry->addr = start_addr;
entry->size = end_addr - start_addr;
entry->type = seg_type;
++n;
} else if (n == VM_PHYSSEG_MAX) {
printf("WARNING: too many memory segments"
"(increase VM_PHYSSEG_MAX)\n");
}
efi_e820memmap.bim.num = n;
efi_e820memmap.bim.common.len =
(intptr_t)&efi_e820memmap.bim.entry[n] - (intptr_t)&efi_e820memmap;
efi_e820memmap.bim.common.type = BTINFO_MEMMAP;
return &efi_e820memmap.bim;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: x86_machdep.c,v 1.87 2017/02/10 10:39:36 maxv Exp $ */ /* $NetBSD: x86_machdep.c,v 1.88 2017/02/14 13:23:50 nonaka Exp $ */
/*- /*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.87 2017/02/10 10:39:36 maxv Exp $"); __KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.88 2017/02/14 13:23:50 nonaka Exp $");
#include "opt_modular.h" #include "opt_modular.h"
#include "opt_physmem.h" #include "opt_physmem.h"
@ -630,62 +630,36 @@ x86_add_cluster(uint64_t seg_start, uint64_t seg_end, uint32_t type)
} }
static int static int
x86_parse_clusters(struct btinfo_common *bi) x86_parse_clusters(struct btinfo_memmap *bim)
{ {
union {
struct btinfo_common *common;
struct btinfo_memmap *bios;
struct btinfo_efimemmap *efi;
} bim;
uint64_t seg_start, seg_end; uint64_t seg_start, seg_end;
uint64_t addr, size; uint64_t addr, size;
uint32_t type; uint32_t type;
int x, num; int x;
bool efimemmap;
KASSERT(bi != NULL); KASSERT(bim != NULL);
bim.common = bi; KASSERT(bim->num > 0);
efimemmap = bi->type == BTINFO_EFIMEMMAP;
num = efimemmap ? bim.efi->num : bim.bios->num;
KASSERT(num > 0);
#ifdef DEBUG_MEMLOAD #ifdef DEBUG_MEMLOAD
printf("MEMMAP: %s MEMORY MAP (%d ENTRIES):\n", printf("MEMMAP: %s MEMORY MAP (%d ENTRIES):\n",
efimemmap ? "UEFI" : "BIOS", num); lookup_bootinfo(BTINFO_EFIMEMMAP) != NULL ? "UEFI" : "BIOS",
bim->num);
#endif #endif
for (x = 0; x < num; x++) { for (x = 0; x < bim->num; x++) {
if (efimemmap) { addr = bim->entry[x].addr;
struct efi_md *md = (struct efi_md *) size = bim->entry[x].size;
(bim.efi->memmap + bim.efi->size * x); type = bim->entry[x].type;
addr = md->md_phys;
size = md->md_pages * EFI_PAGE_SIZE;
type = efi_getbiosmemtype(md->md_type, md->md_attr);
#ifdef DEBUG_MEMLOAD #ifdef DEBUG_MEMLOAD
printf("MEMMAP: p0x%016" PRIx64 "-0x%016" PRIx64 printf("MEMMAP: 0x%016" PRIx64 "-0x%016" PRIx64
", v0x%016" PRIx64 "-0x%016" PRIx64 ", size=0x%016" PRIx64 ", type=%d(%s)\n",
", size=0x%016" PRIx64 ", attr=0x%016" PRIx64 addr, addr + size - 1, size, type,
", type=%d(%s)\n", (type == BIM_Memory) ? "Memory" :
addr, addr + size - 1, (type == BIM_Reserved) ? "Reserved" :
md->md_virt, md->md_virt + size - 1, (type == BIM_ACPI) ? "ACPI" :
size, md->md_attr, md->md_type, (type == BIM_NVS) ? "NVS" :
efi_getmemtype_str(md->md_type)); "unknown");
#endif #endif
} else {
addr = bim.bios->entry[x].addr;
size = bim.bios->entry[x].size;
type = bim.bios->entry[x].type;
#ifdef DEBUG_MEMLOAD
printf("MEMMAP: 0x%016" PRIx64 "-0x%016" PRIx64
", size=0x%016" PRIx64 ", type=%d(%s)\n",
addr, addr + size - 1, size, type,
(type == BIM_Memory) ? "Memory" :
(type == BIM_Reserved) ? "Reserved" :
(type == BIM_ACPI) ? "ACPI" :
(type == BIM_NVS) ? "NVS" :
"unknown");
#endif
}
/* If the segment is not memory, skip it. */ /* If the segment is not memory, skip it. */
switch (type) { switch (type) {
@ -842,7 +816,7 @@ x86_load_region(uint64_t seg_start, uint64_t seg_end)
void void
init_x86_clusters(void) init_x86_clusters(void)
{ {
struct btinfo_memmap *bim = NULL; struct btinfo_memmap *bim;
struct btinfo_efimemmap *biem; struct btinfo_efimemmap *biem;
/* /*
@ -852,18 +826,22 @@ init_x86_clusters(void)
#ifdef i386 #ifdef i386
extern int biosmem_implicit; extern int biosmem_implicit;
biem = lookup_bootinfo(BTINFO_EFIMEMMAP); biem = lookup_bootinfo(BTINFO_EFIMEMMAP);
if (biem == NULL) if (biem != NULL)
bim = efi_get_e820memmap();
else
bim = lookup_bootinfo(BTINFO_MEMMAP); bim = lookup_bootinfo(BTINFO_MEMMAP);
if ((biosmem_implicit || (biosbasemem == 0 && biosextmem == 0)) && if ((biosmem_implicit || (biosbasemem == 0 && biosextmem == 0)) &&
((bim != NULL && bim->num > 0) || (biem != NULL && biem->num > 0))) bim != NULL && bim->num > 0)
x86_parse_clusters(biem != NULL ? &biem->common : &bim->common); x86_parse_clusters(bim);
#else #else
#if !defined(REALBASEMEM) && !defined(REALEXTMEM) #if !defined(REALBASEMEM) && !defined(REALEXTMEM)
biem = lookup_bootinfo(BTINFO_EFIMEMMAP); biem = lookup_bootinfo(BTINFO_EFIMEMMAP);
if (biem == NULL) if (biem != NULL)
bim = efi_get_e820memmap();
else
bim = lookup_bootinfo(BTINFO_MEMMAP); bim = lookup_bootinfo(BTINFO_MEMMAP);
if ((bim != NULL && bim->num > 0) || (biem != NULL && biem->num > 0)) if (bim != NULL && bim->num > 0)
x86_parse_clusters(biem != NULL ? &biem->common : &bim->common); x86_parse_clusters(bim);
#else #else
(void)bim, (void)biem; (void)bim, (void)biem;
#endif #endif