root / tests / boot-order-test.c @ feature-archipelago
History | View | Annotate | Download (5.3 kB)
1 |
/*
|
---|---|
2 |
* Boot order test cases.
|
3 |
*
|
4 |
* Copyright (c) 2013 Red Hat Inc.
|
5 |
*
|
6 |
* Authors:
|
7 |
* Markus Armbruster <armbru@redhat.com>,
|
8 |
*
|
9 |
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 |
* See the COPYING file in the top-level directory.
|
11 |
*/
|
12 |
|
13 |
#include <string.h> |
14 |
#include <glib.h> |
15 |
#include "libqos/fw_cfg.h" |
16 |
#include "libqtest.h" |
17 |
|
18 |
#define NO_QEMU_PROTOS
|
19 |
#include "hw/nvram/fw_cfg.h" |
20 |
#undef NO_QEMU_PROTOS
|
21 |
|
22 |
typedef struct { |
23 |
const char *args; |
24 |
uint64_t expected_boot; |
25 |
uint64_t expected_reboot; |
26 |
} boot_order_test; |
27 |
|
28 |
static void test_a_boot_order(const char *machine, |
29 |
const char *test_args, |
30 |
uint64_t (*read_boot_order)(void),
|
31 |
uint64_t expected_boot, |
32 |
uint64_t expected_reboot) |
33 |
{ |
34 |
char *args;
|
35 |
uint64_t actual; |
36 |
|
37 |
args = g_strdup_printf("-nodefaults%s%s %s",
|
38 |
machine ? " -M " : "", |
39 |
machine ?: "",
|
40 |
test_args); |
41 |
qtest_start(args); |
42 |
actual = read_boot_order(); |
43 |
g_assert_cmphex(actual, ==, expected_boot); |
44 |
qmp_discard_response("{ 'execute': 'system_reset' }");
|
45 |
/*
|
46 |
* system_reset only requests reset. We get a RESET event after
|
47 |
* the actual reset completes. Need to wait for that.
|
48 |
*/
|
49 |
qmp_discard_response(""); /* HACK: wait for event */ |
50 |
actual = read_boot_order(); |
51 |
g_assert_cmphex(actual, ==, expected_reboot); |
52 |
qtest_quit(global_qtest); |
53 |
g_free(args); |
54 |
} |
55 |
|
56 |
static void test_boot_orders(const char *machine, |
57 |
uint64_t (*read_boot_order)(void),
|
58 |
const boot_order_test *tests)
|
59 |
{ |
60 |
int i;
|
61 |
|
62 |
for (i = 0; tests[i].args; i++) { |
63 |
test_a_boot_order(machine, tests[i].args, |
64 |
read_boot_order, |
65 |
tests[i].expected_boot, |
66 |
tests[i].expected_reboot); |
67 |
} |
68 |
} |
69 |
|
70 |
static uint8_t read_mc146818(uint16_t port, uint8_t reg)
|
71 |
{ |
72 |
outb(port, reg); |
73 |
return inb(port + 1); |
74 |
} |
75 |
|
76 |
static uint64_t read_boot_order_pc(void) |
77 |
{ |
78 |
uint8_t b1 = read_mc146818(0x70, 0x38); |
79 |
uint8_t b2 = read_mc146818(0x70, 0x3d); |
80 |
|
81 |
return b1 | (b2 << 8); |
82 |
} |
83 |
|
84 |
static const boot_order_test test_cases_pc[] = { |
85 |
{ "",
|
86 |
0x1230, 0x1230 }, |
87 |
{ "-no-fd-bootchk",
|
88 |
0x1231, 0x1231 }, |
89 |
{ "-boot c",
|
90 |
0x0200, 0x0200 }, |
91 |
{ "-boot nda",
|
92 |
0x3410, 0x3410 }, |
93 |
{ "-boot order=",
|
94 |
0, 0 }, |
95 |
{ "-boot order= -boot order=c",
|
96 |
0x0200, 0x0200 }, |
97 |
{ "-boot once=a",
|
98 |
0x0100, 0x1230 }, |
99 |
{ "-boot once=a -no-fd-bootchk",
|
100 |
0x0101, 0x1231 }, |
101 |
{ "-boot once=a,order=c",
|
102 |
0x0100, 0x0200 }, |
103 |
{ "-boot once=d -boot order=nda",
|
104 |
0x0300, 0x3410 }, |
105 |
{ "-boot once=a -boot once=b -boot once=c",
|
106 |
0x0200, 0x1230 }, |
107 |
{} |
108 |
}; |
109 |
|
110 |
static void test_pc_boot_order(void) |
111 |
{ |
112 |
test_boot_orders(NULL, read_boot_order_pc, test_cases_pc);
|
113 |
} |
114 |
|
115 |
static uint8_t read_m48t59(uint64_t addr, uint16_t reg)
|
116 |
{ |
117 |
writeb(addr, reg & 0xff);
|
118 |
writeb(addr + 1, reg >> 8); |
119 |
return readb(addr + 3); |
120 |
} |
121 |
|
122 |
static uint64_t read_boot_order_prep(void) |
123 |
{ |
124 |
return read_m48t59(0x80000000 + 0x74, 0x34); |
125 |
} |
126 |
|
127 |
static const boot_order_test test_cases_prep[] = { |
128 |
{ "", 'c', 'c' }, |
129 |
{ "-boot c", 'c', 'c' }, |
130 |
{ "-boot d", 'd', 'd' }, |
131 |
{} |
132 |
}; |
133 |
|
134 |
static void test_prep_boot_order(void) |
135 |
{ |
136 |
test_boot_orders("prep", read_boot_order_prep, test_cases_prep);
|
137 |
} |
138 |
|
139 |
static uint64_t read_boot_order_pmac(void) |
140 |
{ |
141 |
QFWCFG *fw_cfg = mm_fw_cfg_init(0xf0000510);
|
142 |
|
143 |
return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE);
|
144 |
} |
145 |
|
146 |
static const boot_order_test test_cases_fw_cfg[] = { |
147 |
{ "", 'c', 'c' }, |
148 |
{ "-boot c", 'c', 'c' }, |
149 |
{ "-boot d", 'd', 'd' }, |
150 |
{ "-boot once=d,order=c", 'd', 'c' }, |
151 |
{} |
152 |
}; |
153 |
|
154 |
static void test_pmac_oldworld_boot_order(void) |
155 |
{ |
156 |
test_boot_orders("g3beige", read_boot_order_pmac, test_cases_fw_cfg);
|
157 |
} |
158 |
|
159 |
static void test_pmac_newworld_boot_order(void) |
160 |
{ |
161 |
test_boot_orders("mac99", read_boot_order_pmac, test_cases_fw_cfg);
|
162 |
} |
163 |
|
164 |
static uint64_t read_boot_order_sun4m(void) |
165 |
{ |
166 |
QFWCFG *fw_cfg = mm_fw_cfg_init(0xd00000510ULL);
|
167 |
|
168 |
return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE);
|
169 |
} |
170 |
|
171 |
static void test_sun4m_boot_order(void) |
172 |
{ |
173 |
test_boot_orders("SS-5", read_boot_order_sun4m, test_cases_fw_cfg);
|
174 |
} |
175 |
|
176 |
static uint64_t read_boot_order_sun4u(void) |
177 |
{ |
178 |
QFWCFG *fw_cfg = io_fw_cfg_init(0x510);
|
179 |
|
180 |
return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE);
|
181 |
} |
182 |
|
183 |
static void test_sun4u_boot_order(void) |
184 |
{ |
185 |
test_boot_orders("sun4u", read_boot_order_sun4u, test_cases_fw_cfg);
|
186 |
} |
187 |
|
188 |
int main(int argc, char *argv[]) |
189 |
{ |
190 |
const char *arch = qtest_get_arch(); |
191 |
|
192 |
g_test_init(&argc, &argv, NULL);
|
193 |
|
194 |
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { |
195 |
qtest_add_func("boot-order/pc", test_pc_boot_order);
|
196 |
} else if (strcmp(arch, "ppc") == 0 || strcmp(arch, "ppc64") == 0) { |
197 |
qtest_add_func("boot-order/prep", test_prep_boot_order);
|
198 |
qtest_add_func("boot-order/pmac_oldworld",
|
199 |
test_pmac_oldworld_boot_order); |
200 |
qtest_add_func("boot-order/pmac_newworld",
|
201 |
test_pmac_newworld_boot_order); |
202 |
} else if (strcmp(arch, "sparc") == 0) { |
203 |
qtest_add_func("boot-order/sun4m", test_sun4m_boot_order);
|
204 |
} else if (strcmp(arch, "sparc64") == 0) { |
205 |
qtest_add_func("boot-order/sun4u", test_sun4u_boot_order);
|
206 |
} |
207 |
|
208 |
return g_test_run();
|
209 |
} |