Date: Tue, 11 Mar 2014 10:23:03 +0000 (UTC) From: Roger Pau Monné <royger@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r263009 - in head/sys: amd64/amd64 amd64/include/pc x86/include x86/xen Message-ID: <201403111023.s2BAN3px022768@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: royger Date: Tue Mar 11 10:23:03 2014 New Revision: 263009 URL: http://svnweb.freebsd.org/changeset/base/263009 Log: xen: implement hook to fetch and parse e820 memory map e820 memory map is fetched using a hypercall under Xen PVH, so add a hook to init_ops in oder to diverge from bare metal and implement a Xen variant. Approved by: gibbs Sponsored by: Citrix Systems R&D x86/include/init.h: - Add a parse_memmap hook to init_ops, that will be called to fetch and parse the memory map. amd64/amd64/machdep.c: - Decouple the fetch and the parse of the memmap, so the parse function can be shared with Xen code. - Move code around in order to implement the parse_memmap hook. amd64/include/pc/bios.h: - Declare bios_add_smap_entries (implemented in machdep.c). x86/xen/pv.c: - Implement fetching of e820 memmap when running as a PVH guest by using the XENMEM_memory_map hypercall. Modified: head/sys/amd64/amd64/machdep.c head/sys/amd64/include/pc/bios.h head/sys/x86/include/init.h head/sys/x86/xen/pv.c Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Tue Mar 11 10:20:42 2014 (r263008) +++ head/sys/amd64/amd64/machdep.c Tue Mar 11 10:23:03 2014 (r263009) @@ -169,11 +169,15 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, /* Preload data parse function */ static caddr_t native_parse_preload_data(u_int64_t); +/* Native function to fetch and parse the e820 map */ +static void native_parse_memmap(caddr_t, vm_paddr_t *, int *); + /* Default init_ops implementation. */ struct init_ops init_ops = { .parse_preload_data = native_parse_preload_data, .early_clock_source_init = i8254_init, .early_delay = i8254_delay, + .parse_memmap = native_parse_memmap, }; /* @@ -1403,21 +1407,12 @@ add_physmap_entry(uint64_t base, uint64_ return (1); } -static void -add_smap_entries(struct bios_smap *smapbase, vm_paddr_t *physmap, - int *physmap_idx) +void +bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize, + vm_paddr_t *physmap, int *physmap_idx) { struct bios_smap *smap, *smapend; - u_int32_t smapsize; - /* - * Memory map from INT 15:E820. - * - * subr_module.c says: - * "Consumer may safely assume that size value precedes data." - * ie: an int32_t immediately precedes smap. - */ - smapsize = *((u_int32_t *)smapbase - 1); smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); for (smap = smapbase; smap < smapend; smap++) { @@ -1434,6 +1429,29 @@ add_smap_entries(struct bios_smap *smapb } } +static void +native_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) +{ + struct bios_smap *smap; + u_int32_t size; + + /* + * Memory map from INT 15:E820. + * + * subr_module.c says: + * "Consumer may safely assume that size value precedes data." + * ie: an int32_t immediately precedes smap. + */ + + smap = (struct bios_smap *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_SMAP); + if (smap == NULL) + panic("No BIOS smap info from loader!"); + size = *((u_int32_t *)smap - 1); + + bios_add_smap_entries(smap, size, physmap, physmap_idx); +} + /* * Populate the (physmap) array with base/bound pairs describing the * available physical memory in the system, then test this memory and @@ -1451,19 +1469,13 @@ getmemsize(caddr_t kmdp, u_int64_t first vm_paddr_t pa, physmap[PHYSMAP_SIZE]; u_long physmem_start, physmem_tunable, memtest; pt_entry_t *pte; - struct bios_smap *smapbase; quad_t dcons_addr, dcons_size; bzero(physmap, sizeof(physmap)); basemem = 0; physmap_idx = 0; - smapbase = (struct bios_smap *)preload_search_info(kmdp, - MODINFO_METADATA | MODINFOMD_SMAP); - if (smapbase == NULL) - panic("No BIOS smap info from loader!"); - - add_smap_entries(smapbase, physmap, &physmap_idx); + init_ops.parse_memmap(kmdp, physmap, &physmap_idx); /* * Find the 'base memory' segment for SMP Modified: head/sys/amd64/include/pc/bios.h ============================================================================== --- head/sys/amd64/include/pc/bios.h Tue Mar 11 10:20:42 2014 (r263008) +++ head/sys/amd64/include/pc/bios.h Tue Mar 11 10:23:03 2014 (r263009) @@ -106,6 +106,8 @@ struct bios_oem { int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen); uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen, int sigofs); +void bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize, + vm_paddr_t *physmap, int *physmap_idx); #endif #endif /* _MACHINE_PC_BIOS_H_ */ Modified: head/sys/x86/include/init.h ============================================================================== --- head/sys/x86/include/init.h Tue Mar 11 10:20:42 2014 (r263008) +++ head/sys/x86/include/init.h Tue Mar 11 10:23:03 2014 (r263009) @@ -38,6 +38,7 @@ struct init_ops { caddr_t (*parse_preload_data)(u_int64_t); void (*early_clock_source_init)(void); void (*early_delay)(int); + void (*parse_memmap)(caddr_t, vm_paddr_t *, int *); }; extern struct init_ops init_ops; Modified: head/sys/x86/xen/pv.c ============================================================================== --- head/sys/x86/xen/pv.c Tue Mar 11 10:20:42 2014 (r263008) +++ head/sys/x86/xen/pv.c Tue Mar 11 10:23:03 2014 (r263009) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_param.h> #include <x86/init.h> +#include <machine/pc/bios.h> #include <xen/xen-os.h> #include <xen/hypervisor.h> @@ -60,8 +61,11 @@ extern u_int64_t hammer_time(u_int64_t, /* Xen initial function */ uint64_t hammer_time_xen(start_info_t *, uint64_t); +#define MAX_E820_ENTRIES 128 + /*--------------------------- Forward Declarations ---------------------------*/ static caddr_t xen_pv_parse_preload_data(u_int64_t); +static void xen_pv_parse_memmap(caddr_t, vm_paddr_t *, int *); /*-------------------------------- Global Data -------------------------------*/ /* Xen init_ops implementation. */ @@ -69,8 +73,11 @@ struct init_ops xen_init_ops = { .parse_preload_data = xen_pv_parse_preload_data, .early_clock_source_init = xen_clock_init, .early_delay = xen_delay, + .parse_memmap = xen_pv_parse_memmap, }; +static struct bios_smap xen_smap[MAX_E820_ENTRIES]; + /*-------------------------------- Xen PV init -------------------------------*/ /* * First function called by the Xen PVH boot sequence. @@ -189,3 +196,21 @@ xen_pv_parse_preload_data(u_int64_t modu return (NULL); } + +static void +xen_pv_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) +{ + struct xen_memory_map memmap; + u_int32_t size; + int rc; + + /* Fetch the E820 map from Xen */ + memmap.nr_entries = MAX_E820_ENTRIES; + set_xen_guest_handle(memmap.buffer, xen_smap); + rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); + if (rc) + panic("unable to fetch Xen E820 memory map"); + size = memmap.nr_entries * sizeof(xen_smap[0]); + + bios_add_smap_entries(xen_smap, size, physmap, physmap_idx); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403111023.s2BAN3px022768>