xref: /kvm-unit-tests/lib/x86/setup.c (revision e36a9c28fc8f8f59e0e30db244af0b17c6d04be9)
1 /*
2  * Initialize machine setup information
3  *
4  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
5  *
6  * This work is licensed under the terms of the GNU LGPL, version 2.
7  */
8 #include "libcflat.h"
9 #include "fwcfg.h"
10 #include "alloc_phys.h"
11 #include "argv.h"
12 
13 extern char edata;
14 
15 struct mbi_bootinfo {
16 	u32 flags;
17 	u32 mem_lower;
18 	u32 mem_upper;
19 	u32 boot_device;
20 	u32 cmdline;
21 	u32 mods_count;
22 	u32 mods_addr;
23 	u32 reserved[5];   /* 28-47 */
24 	u32 mmap_addr;
25 	u32 reserved0[3];  /* 52-63 */
26 	u32 bootloader;
27 	u32 reserved1[5];  /* 68-87 */
28 	u32 size;
29 };
30 
31 struct mbi_module {
32 	u32 start, end;
33 	u32 cmdline;
34 	u32 unused;
35 };
36 
37 #define ENV_SIZE 16384
38 
39 void setup_env(char *env, int size);
40 void setup_multiboot(struct mbi_bootinfo *bootinfo);
41 void setup_libcflat(void);
42 
43 char *initrd;
44 u32 initrd_size;
45 
46 static char env[ENV_SIZE];
47 
48 void setup_multiboot(struct mbi_bootinfo *bootinfo)
49 {
50 	struct mbi_module *mods;
51 
52 	/* TODO: use e820 */
53 	u64 end_of_memory = bootinfo->mem_upper * 1024ull;
54 	phys_alloc_init((uintptr_t) &edata, end_of_memory - (uintptr_t) &edata);
55 
56 	if (bootinfo->mods_count != 1)
57 		return;
58 
59 	mods = (struct mbi_module *)(uintptr_t) bootinfo->mods_addr;
60 
61 	initrd = (char *)(uintptr_t) mods->start;
62 	initrd_size = mods->end - mods->start;
63 }
64 
65 void setup_libcflat(void)
66 {
67 	if (initrd) {
68 		/* environ is currently the only file in the initrd */
69 		u32 size = MIN(initrd_size, ENV_SIZE);
70 		const char *str;
71 
72 		memcpy(env, initrd, size);
73 		setup_env(env, size);
74 		if ((str = getenv("BOOTLOADER")) && atol(str) != 0)
75 			add_setup_arg("bootloader");
76 	}
77 }
78