xref: /kvm-unit-tests/lib/x86/setup.c (revision 03b1e4570f9678c59a1fdcd0428d21681541602e)
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