[PATCH v7 07/19] xen: implement hook to fetch e820 memory map
Roger Pau Monne
roger.pau at citrix.com
Thu Dec 19 18:55:28 UTC 2013
---
sys/amd64/amd64/machdep.c | 50 ++++++++++++++++++++++++++----------------
sys/amd64/include/pc/bios.h | 2 +
sys/amd64/include/sysarch.h | 1 +
sys/x86/xen/pv.c | 26 ++++++++++++++++++++++
4 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index a2dcb90..6bbfe5a 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -177,11 +177,15 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
/* 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_delay_init = i8254_init,
.early_delay = i8254_delay,
+ .parse_memmap = native_parse_memmap,
};
/*
@@ -1418,21 +1422,12 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
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++) {
@@ -1449,6 +1444,29 @@ add_smap_entries(struct bios_smap *smapbase, vm_paddr_t *physmap,
}
}
+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
@@ -1466,19 +1484,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
diff --git a/sys/amd64/include/pc/bios.h b/sys/amd64/include/pc/bios.h
index e7d568e..92d4265 100644
--- a/sys/amd64/include/pc/bios.h
+++ b/sys/amd64/include/pc/bios.h
@@ -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_ */
diff --git a/sys/amd64/include/sysarch.h b/sys/amd64/include/sysarch.h
index 60fa635..084223e 100644
--- a/sys/amd64/include/sysarch.h
+++ b/sys/amd64/include/sysarch.h
@@ -15,6 +15,7 @@ struct init_ops {
caddr_t (*parse_preload_data)(u_int64_t);
void (*early_delay_init)(void);
void (*early_delay)(int);
+ void (*parse_memmap)(caddr_t, vm_paddr_t *, int *);
};
extern struct init_ops init_ops;
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index f8d8cfa..db576e0 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -37,12 +37,17 @@ __FBSDID("$FreeBSD$");
#include <machine/sysarch.h>
#include <machine/clock.h>
+#include <machine/pc/bios.h>
#include <xen/xen-os.h>
#include <xen/pv.h>
+#include <xen/hypervisor.h>
+
+#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. */
@@ -50,6 +55,7 @@ struct init_ops xen_init_ops = {
.parse_preload_data = xen_pv_parse_preload_data,
.early_delay_init = xen_delay_init,
.early_delay = xen_delay,
+ .parse_memmap = xen_pv_parse_memmap,
};
static struct
@@ -70,6 +76,8 @@ static struct
{NULL, 0}
};
+static struct bios_smap xen_smap[MAX_E820_ENTRIES];
+
/*
* Functions to convert the "extra" parameters passed by Xen
* into FreeBSD boot options (from the i386 Xen port).
@@ -109,6 +117,24 @@ xen_pv_parse_preload_data(u_int64_t modulep)
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);
+}
+
void
xen_pv_set_init_ops(void)
{
--
1.7.7.5 (Apple Git-26)
More information about the freebsd-current
mailing list