Index: sys/x86/xen/pv.c =================================================================== --- sys/x86/xen/pv.c +++ sys/x86/xen/pv.c @@ -94,7 +94,7 @@ /*--------------------------- Forward Declarations ---------------------------*/ static caddr_t xen_pvh_parse_preload_data(uint64_t); -static void xen_pvh_parse_memmap(caddr_t, vm_paddr_t *, int *); +static void pvh_parse_memmap(caddr_t, vm_paddr_t *, int *); /*---------------------------- Extern Declarations ---------------------------*/ /* @@ -108,7 +108,7 @@ .parse_preload_data = xen_pvh_parse_preload_data, .early_clock_source_init = xen_clock_init, .early_delay = xen_delay, - .parse_memmap = xen_pvh_parse_memmap, + .parse_memmap = pvh_parse_memmap, }; static struct bios_smap xen_smap[MAX_E820_ENTRIES]; @@ -395,6 +395,35 @@ return (kmdp); } +static void +pvh_parse_memmap_start_info(caddr_t kmdp, vm_paddr_t *physmap, + int *physmap_idx) +{ + const struct hvm_memmap_table_entry * entries; + size_t nentries; + struct bios_smap entry; + size_t i; + + /* Extract from HVM start_info. */ + entries = (struct hvm_memmap_table_entry *)(start_info->memmap_paddr + KERNBASE); + nentries = start_info->memmap_entries; + + /* Convert into E820 format and handle one by one. */ + for (i = 0; i < nentries; i++) { + entry.base = entries[i].addr; + entry.length = entries[i].size; + + /* + * Luckily for us, the XEN_HVM_MEMMAP_TYPE_* values exactly + * match the SMAP_TYPE_* values so we don't need to translate + * anything here. + */ + entry.type = entries[i].type; + + bios_add_smap_entries(&entry, 1, physmap, physmap_idx); + } +} + static void xen_pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) { @@ -416,3 +445,18 @@ bios_add_smap_entries(xen_smap, size, physmap, physmap_idx); } + +static void +pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) +{ + + /* + * If version >= 1 and memmap_paddr != 0, use the memory map provided + * in the start_info structure; if not, we're running under legacy + * Xen and need to use the Xen hypercall. + */ + if ((start_info->version >= 1) && (start_info->memmap_paddr != 0)) + pvh_parse_memmap_start_info(kmdp, physmap, physmap_idx); + else + xen_pvh_parse_memmap(kmdp, physmap, physmap_idx); +}