xref: /kvm-unit-tests/lib/x86/fwcfg.c (revision 82147b77199bbfec2c61c97685cfb34f3f97c889)
1 #include "fwcfg.h"
2 #include "smp.h"
3 #include "libcflat.h"
4 
5 static struct spinlock lock;
6 
7 static long fw_override[FW_CFG_NUM_ENTRIES];
8 static bool fw_override_done;
9 
10 bool no_test_device;
11 
read_cfg_override(void)12 static void read_cfg_override(void)
13 {
14 	const char *str;
15 	int i;
16 
17 	/* Initialize to negative value that would be considered as invalid */
18 	for (i = 0; i < FW_CFG_NUM_ENTRIES; i++)
19 		fw_override[i] = -1;
20 
21 	if ((str = getenv("NR_CPUS")))
22 		fw_override[FW_CFG_NB_CPUS] = atol(str);
23 
24 	/* MEMSIZE is in megabytes */
25 	if ((str = getenv("MEMSIZE")))
26 		fw_override[FW_CFG_RAM_SIZE] = atol(str) * 1024 * 1024;
27 
28 	if ((str = getenv("TEST_DEVICE")))
29 		no_test_device = !atol(str);
30 
31 	if ((str = getenv("MEMLIMIT")))
32 		fw_override[FW_CFG_MAX_RAM] = atol(str) * 1024 * 1024;
33 
34 
35     fw_override_done = true;
36 }
37 
fwcfg_get_u(uint16_t index,int bytes)38 static uint64_t fwcfg_get_u(uint16_t index, int bytes)
39 {
40     uint64_t r = 0;
41     uint8_t b;
42     int i;
43 
44     if (!fw_override_done)
45         read_cfg_override();
46 
47     if (index < FW_CFG_NUM_ENTRIES && fw_override[index] >= 0)
48 	    return fw_override[index];
49 
50     spin_lock(&lock);
51     asm volatile ("out %0, %1" : : "a"(index), "d"((uint16_t)BIOS_CFG_IOPORT));
52     for (i = 0; i < bytes; ++i) {
53         asm volatile ("in %1, %0" : "=a"(b) : "d"((uint16_t)(BIOS_CFG_IOPORT + 1)));
54         r |= (uint64_t)b << (i * 8);
55     }
56     spin_unlock(&lock);
57     return r;
58 }
59 
fwcfg_get_u8(unsigned index)60 uint8_t fwcfg_get_u8(unsigned index)
61 {
62     return fwcfg_get_u(index, 1);
63 }
64 
fwcfg_get_u16(unsigned index)65 uint16_t fwcfg_get_u16(unsigned index)
66 {
67     return fwcfg_get_u(index, 2);
68 }
69 
fwcfg_get_u32(unsigned index)70 uint32_t fwcfg_get_u32(unsigned index)
71 {
72     return fwcfg_get_u(index, 4);
73 }
74 
fwcfg_get_u64(unsigned index)75 uint64_t fwcfg_get_u64(unsigned index)
76 {
77     return fwcfg_get_u(index, 8);
78 }
79 
fwcfg_get_nb_cpus(void)80 unsigned fwcfg_get_nb_cpus(void)
81 {
82     return fwcfg_get_u16(FW_CFG_NB_CPUS);
83 }
84