ret
+/*
+ * Copy E820 map obtained from BIOS to a buffer allocated by Xen.
+ * Input: %rdi: target address of e820 entry array
+ * %esi: maximum number of entries to copy
+ * Output: %eax: number of entries copied
+ */
+ .code64
+ENTRY(e820map_copy)
+ mov %esi, %eax
+ lea e820map(%rip), %rsi
+ mov e820nr(%rip), %ecx
+ cmp %ecx, %eax
+ cmova %ecx, %eax # number of entries to move
+ imul $5, %eax, %ecx
+ rep movsl # do the move
+ ret
+
.align 4
-GLOBAL(e820map)
+e820map:
.fill E820MAX*20,1,0
-GLOBAL(e820nr)
+e820nr:
.long 0
GLOBAL(lowmem_kb)
.long 0
boolean_param("e820-verbose", e820_verbose);
struct e820map e820;
+struct e820map __initdata e820_raw;
/*
* This function checks if the entire range <start,end> is mapped with type.
x = e820.nr_map;
- if (x == E820MAX) {
+ if (x == ARRAY_SIZE(e820.map)) {
printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
return;
}
static struct e820entry *overlap_list[E820MAX] __initdata;
static struct e820entry new_bios[E820MAX] __initdata;
-static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
+static int __init sanitize_e820_map(struct e820entry *biosmap,
+ unsigned int *pnr_map)
{
struct change_member *change_tmp;
unsigned long current_type, last_type;
change_point[chgidx]->addr - last_addr;
/* move forward only if the new size was non-zero */
if (new_bios[new_bios_entry].size != 0)
- if (++new_bios_entry >= E820MAX)
+ if (++new_bios_entry >= ARRAY_SIZE(new_bios))
break; /* no more space left for new bios entries */
}
if (current_type != 0) {
}
}
-static void __init machine_specific_memory_setup(
- struct e820entry *raw, unsigned int *raw_nr)
+static void __init machine_specific_memory_setup(struct e820map *raw)
{
unsigned long mpt_limit, ro_mpt_limit;
uint64_t top_of_ram, size;
int i;
- char nr = (char)*raw_nr;
- sanitize_e820_map(raw, &nr);
- *raw_nr = nr;
- (void)copy_e820_map(raw, nr);
+ sanitize_e820_map(raw->map, &raw->nr_map);
+ copy_e820_map(raw->map, raw->nr_map);
if ( opt_mem )
clip_to_limit(opt_mem, NULL);
return e820_change_range_type(e820, s, e, E820_RAM, E820_RESERVED);
}
-unsigned long __init init_e820(
- const char *str, struct e820entry *raw, unsigned int *raw_nr)
+unsigned long __init init_e820(const char *str, struct e820map *raw)
{
if ( e820_verbose )
{
printk("Initial %s RAM map:\n", str);
- print_e820_memory_map(raw, *raw_nr);
+ print_e820_memory_map(raw->map, raw->nr_map);
}
- machine_specific_memory_setup(raw, raw_nr);
+ machine_specific_memory_setup(raw);
printk("%s RAM map:\n", str);
print_e820_memory_map(e820.map, e820.nr_map);
unsigned int i;
/* Populate E820 table and check trampoline area availability. */
- e = e820map - 1;
- for ( e820nr = i = 0; i < map_size; i += desc_size )
+ e = e820_raw.map - 1;
+ for ( e820_raw.nr_map = i = 0; i < map_size; i += desc_size )
{
EFI_MEMORY_DESCRIPTOR *desc = map + i;
u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
type = E820_NVS;
break;
}
- if ( e820nr && type == e->type &&
+ if ( e820_raw.nr_map && type == e->type &&
desc->PhysicalStart == e->addr + e->size )
e->size += len;
- else if ( !len || e820nr >= E820MAX )
+ else if ( !len || e820_raw.nr_map >= ARRAY_SIZE(e820_raw.map) )
continue;
else
{
e->addr = desc->PhysicalStart;
e->size = len;
e->type = type;
- ++e820nr;
+ ++e820_raw.nr_map;
}
}
}
else if ( efi_enabled(EFI_BOOT) )
memmap_type = "EFI";
- else if ( e820_raw_nr != 0 )
+ else if ( (e820_raw.nr_map =
+ copy_bios_e820(e820_raw.map,
+ ARRAY_SIZE(e820_raw.map))) != 0 )
{
memmap_type = "Xen-e820";
}
else if ( mbi->flags & MBI_MEMMAP )
{
memmap_type = "Multiboot-e820";
- while ( (bytes < mbi->mmap_length) && (e820_raw_nr < E820MAX) )
+ while ( bytes < mbi->mmap_length &&
+ e820_raw.nr_map < ARRAY_SIZE(e820_raw.map) )
{
memory_map_t *map = __va(mbi->mmap_addr + bytes);
map->length_high = 0;
}
- e820_raw[e820_raw_nr].addr =
+ e820_raw.map[e820_raw.nr_map].addr =
((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
- e820_raw[e820_raw_nr].size =
+ e820_raw.map[e820_raw.nr_map].size =
((u64)map->length_high << 32) | (u64)map->length_low;
- e820_raw[e820_raw_nr].type = map->type;
- e820_raw_nr++;
+ e820_raw.map[e820_raw.nr_map].type = map->type;
+ e820_raw.nr_map++;
bytes += map->size + 4;
}
else if ( bootsym(lowmem_kb) )
{
memmap_type = "Xen-e801";
- e820_raw[0].addr = 0;
- e820_raw[0].size = bootsym(lowmem_kb) << 10;
- e820_raw[0].type = E820_RAM;
- e820_raw[1].addr = 0x100000;
- e820_raw[1].size = bootsym(highmem_kb) << 10;
- e820_raw[1].type = E820_RAM;
- e820_raw_nr = 2;
+ e820_raw.map[0].addr = 0;
+ e820_raw.map[0].size = bootsym(lowmem_kb) << 10;
+ e820_raw.map[0].type = E820_RAM;
+ e820_raw.map[1].addr = 0x100000;
+ e820_raw.map[1].size = bootsym(highmem_kb) << 10;
+ e820_raw.map[1].type = E820_RAM;
+ e820_raw.nr_map = 2;
}
else if ( mbi->flags & MBI_MEMLIMITS )
{
memmap_type = "Multiboot-e801";
- e820_raw[0].addr = 0;
- e820_raw[0].size = mbi->mem_lower << 10;
- e820_raw[0].type = E820_RAM;
- e820_raw[1].addr = 0x100000;
- e820_raw[1].size = mbi->mem_upper << 10;
- e820_raw[1].type = E820_RAM;
- e820_raw_nr = 2;
+ e820_raw.map[0].addr = 0;
+ e820_raw.map[0].size = mbi->mem_lower << 10;
+ e820_raw.map[0].type = E820_RAM;
+ e820_raw.map[1].addr = 0x100000;
+ e820_raw.map[1].size = mbi->mem_upper << 10;
+ e820_raw.map[1].type = E820_RAM;
+ e820_raw.nr_map = 2;
}
else
panic("Bootloader provided no memory information.");
/* Sanitise the raw E820 map to produce a final clean version. */
- max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+ max_page = raw_max_page = init_e820(memmap_type, &e820_raw);
/* Create a temporary copy of the E820 map. */
memcpy(&boot_e820, &e820, sizeof(e820));
uint32_t orig_type, uint32_t new_type);
extern int e820_add_range(
struct e820map *, uint64_t s, uint64_t e, uint32_t type);
-extern unsigned long init_e820(const char *, struct e820entry *, unsigned int *);
+extern unsigned long init_e820(const char *, struct e820map *);
extern struct e820map e820;
+extern struct e820map e820_raw;
/* These symbols live in the boot trampoline. */
-extern struct e820entry e820map[];
-extern unsigned int e820nr;
extern unsigned int lowmem_kb, highmem_kb;
+unsigned int e820map_copy(struct e820entry *map, unsigned int limit);
-#define e820_raw bootsym(e820map)
-#define e820_raw_nr bootsym(e820nr)
+#define copy_bios_e820 bootsym(e820map_copy)
#endif /*__E820_HEADER*/