193dd2aa3SAndrew Jones /* 293dd2aa3SAndrew Jones * Initialize machine setup information 393dd2aa3SAndrew Jones * 493dd2aa3SAndrew Jones * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> 593dd2aa3SAndrew Jones * 693dd2aa3SAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 793dd2aa3SAndrew Jones */ 893dd2aa3SAndrew Jones #include "libcflat.h" 9716cea8aSPaolo Bonzini #include "fwcfg.h" 10716cea8aSPaolo Bonzini #include "alloc_phys.h" 1193dd2aa3SAndrew Jones 12716cea8aSPaolo Bonzini extern char edata; 13716cea8aSPaolo Bonzini 14716cea8aSPaolo Bonzini struct mbi_bootinfo { 15716cea8aSPaolo Bonzini u32 flags; 16716cea8aSPaolo Bonzini u32 mem_lower; 17716cea8aSPaolo Bonzini u32 mem_upper; 18716cea8aSPaolo Bonzini u32 boot_device; 19716cea8aSPaolo Bonzini u32 cmdline; 20716cea8aSPaolo Bonzini u32 mods_count; 21716cea8aSPaolo Bonzini u32 mods_addr; 22716cea8aSPaolo Bonzini u32 reserved[5]; /* 28-47 */ 23716cea8aSPaolo Bonzini u32 mmap_addr; 24716cea8aSPaolo Bonzini u32 reserved0[3]; /* 52-63 */ 25716cea8aSPaolo Bonzini u32 bootloader; 26716cea8aSPaolo Bonzini u32 reserved1[5]; /* 68-87 */ 27716cea8aSPaolo Bonzini u32 size; 28716cea8aSPaolo Bonzini }; 29716cea8aSPaolo Bonzini 30716cea8aSPaolo Bonzini struct mbi_module { 31716cea8aSPaolo Bonzini u32 start, end; 32716cea8aSPaolo Bonzini u32 cmdline; 33716cea8aSPaolo Bonzini u32 unused; 34716cea8aSPaolo Bonzini }; 3593dd2aa3SAndrew Jones 363c7d322eSAndrew Jones #define ENV_SIZE 16384 373c7d322eSAndrew Jones 38*06846df5SThomas Huth void setup_env(char *env, int size); 39*06846df5SThomas Huth void setup_multiboot(struct mbi_bootinfo *bootinfo); 40*06846df5SThomas Huth void setup_libcflat(void); 413c7d322eSAndrew Jones 4293dd2aa3SAndrew Jones char *initrd; 4393dd2aa3SAndrew Jones u32 initrd_size; 4493dd2aa3SAndrew Jones 453c7d322eSAndrew Jones static char env[ENV_SIZE]; 463c7d322eSAndrew Jones 47716cea8aSPaolo Bonzini void setup_multiboot(struct mbi_bootinfo *bootinfo) 4893dd2aa3SAndrew Jones { 49716cea8aSPaolo Bonzini struct mbi_module *mods; 5093dd2aa3SAndrew Jones 51cb67196aSPaolo Bonzini /* TODO: use e820 */ 52cb67196aSPaolo Bonzini u64 end_of_memory = bootinfo->mem_upper * 1024ull; 53cb67196aSPaolo Bonzini phys_alloc_init((uintptr_t) &edata, end_of_memory - (uintptr_t) &edata); 54cb67196aSPaolo Bonzini 55716cea8aSPaolo Bonzini if (bootinfo->mods_count != 1) 5693dd2aa3SAndrew Jones return; 5793dd2aa3SAndrew Jones 58716cea8aSPaolo Bonzini mods = (struct mbi_module *)(uintptr_t) bootinfo->mods_addr; 5993dd2aa3SAndrew Jones 60716cea8aSPaolo Bonzini initrd = (char *)(uintptr_t) mods->start; 61716cea8aSPaolo Bonzini initrd_size = mods->end - mods->start; 6293dd2aa3SAndrew Jones } 633c7d322eSAndrew Jones 64716cea8aSPaolo Bonzini void setup_libcflat(void) 653c7d322eSAndrew Jones { 663c7d322eSAndrew Jones if (initrd) { 673c7d322eSAndrew Jones /* environ is currently the only file in the initrd */ 683c7d322eSAndrew Jones u32 size = MIN(initrd_size, ENV_SIZE); 693c7d322eSAndrew Jones memcpy(env, initrd, size); 703c7d322eSAndrew Jones setup_env(env, size); 713c7d322eSAndrew Jones } 723c7d322eSAndrew Jones } 73