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