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" 11*03b1e457SNadav Amit #include "argv.h" 1293dd2aa3SAndrew Jones 13716cea8aSPaolo Bonzini extern char edata; 14716cea8aSPaolo Bonzini 15716cea8aSPaolo Bonzini struct mbi_bootinfo { 16716cea8aSPaolo Bonzini u32 flags; 17716cea8aSPaolo Bonzini u32 mem_lower; 18716cea8aSPaolo Bonzini u32 mem_upper; 19716cea8aSPaolo Bonzini u32 boot_device; 20716cea8aSPaolo Bonzini u32 cmdline; 21716cea8aSPaolo Bonzini u32 mods_count; 22716cea8aSPaolo Bonzini u32 mods_addr; 23716cea8aSPaolo Bonzini u32 reserved[5]; /* 28-47 */ 24716cea8aSPaolo Bonzini u32 mmap_addr; 25716cea8aSPaolo Bonzini u32 reserved0[3]; /* 52-63 */ 26716cea8aSPaolo Bonzini u32 bootloader; 27716cea8aSPaolo Bonzini u32 reserved1[5]; /* 68-87 */ 28716cea8aSPaolo Bonzini u32 size; 29716cea8aSPaolo Bonzini }; 30716cea8aSPaolo Bonzini 31716cea8aSPaolo Bonzini struct mbi_module { 32716cea8aSPaolo Bonzini u32 start, end; 33716cea8aSPaolo Bonzini u32 cmdline; 34716cea8aSPaolo Bonzini u32 unused; 35716cea8aSPaolo Bonzini }; 3693dd2aa3SAndrew Jones 373c7d322eSAndrew Jones #define ENV_SIZE 16384 383c7d322eSAndrew Jones 3906846df5SThomas Huth void setup_env(char *env, int size); 4006846df5SThomas Huth void setup_multiboot(struct mbi_bootinfo *bootinfo); 4106846df5SThomas Huth void setup_libcflat(void); 423c7d322eSAndrew Jones 4393dd2aa3SAndrew Jones char *initrd; 4493dd2aa3SAndrew Jones u32 initrd_size; 4593dd2aa3SAndrew Jones 463c7d322eSAndrew Jones static char env[ENV_SIZE]; 473c7d322eSAndrew Jones 48716cea8aSPaolo Bonzini void setup_multiboot(struct mbi_bootinfo *bootinfo) 4993dd2aa3SAndrew Jones { 50716cea8aSPaolo Bonzini struct mbi_module *mods; 5193dd2aa3SAndrew Jones 52cb67196aSPaolo Bonzini /* TODO: use e820 */ 53cb67196aSPaolo Bonzini u64 end_of_memory = bootinfo->mem_upper * 1024ull; 54cb67196aSPaolo Bonzini phys_alloc_init((uintptr_t) &edata, end_of_memory - (uintptr_t) &edata); 55cb67196aSPaolo Bonzini 56716cea8aSPaolo Bonzini if (bootinfo->mods_count != 1) 5793dd2aa3SAndrew Jones return; 5893dd2aa3SAndrew Jones 59716cea8aSPaolo Bonzini mods = (struct mbi_module *)(uintptr_t) bootinfo->mods_addr; 6093dd2aa3SAndrew Jones 61716cea8aSPaolo Bonzini initrd = (char *)(uintptr_t) mods->start; 62716cea8aSPaolo Bonzini initrd_size = mods->end - mods->start; 6393dd2aa3SAndrew Jones } 643c7d322eSAndrew Jones 65716cea8aSPaolo Bonzini void setup_libcflat(void) 663c7d322eSAndrew Jones { 673c7d322eSAndrew Jones if (initrd) { 683c7d322eSAndrew Jones /* environ is currently the only file in the initrd */ 693c7d322eSAndrew Jones u32 size = MIN(initrd_size, ENV_SIZE); 70*03b1e457SNadav Amit const char *str; 71*03b1e457SNadav Amit 723c7d322eSAndrew Jones memcpy(env, initrd, size); 733c7d322eSAndrew Jones setup_env(env, size); 74*03b1e457SNadav Amit if ((str = getenv("BOOTLOADER")) && atol(str) != 0) 75*03b1e457SNadav Amit add_setup_arg("bootloader"); 763c7d322eSAndrew Jones } 773c7d322eSAndrew Jones } 78