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