blob: 2853c86359a9dc6a5bacd9e0bc2665856e67c9c5 [file] [log] [blame]
Bill Richardson791c95f2011-09-30 15:23:15 -07001/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for vboot_api_firmware
6 */
7
8#include <stdio.h>
9#include <stddef.h>
10#include <stdlib.h>
11
12#include "crc32.h"
13#include "host_common.h"
14#include "rollback_index.h"
15#include "test_common.h"
16#include "vboot_common.h"
17#include "vboot_nvstorage.h"
18#include "vboot_struct.h"
19#include "load_kernel_fw.h"
20#include "gbb_header.h"
21#include "vboot_display.h"
22
23
24/* Expected results */
25
26#define MAX_NOTE_EVENTS 10
27
28typedef struct {
29 uint16_t msec;
30 uint16_t freq;
31 uint32_t time;
32} note_event_t;
33
34typedef struct {
35 char *name;
36 uint32_t gbb_flags;
37 VbError_t beep_return;
38 uint32_t keypress_key;
39 int keypress_at_count;
40 int num_events;
41 note_event_t notes[MAX_NOTE_EVENTS];
42} test_case_t;
43
44test_case_t test[] = {
45
46 { "VbBootDeveloperSoundTest( fast, background )",
47 0x00000001, VBERROR_SUCCESS,
48 0, 0,
49 3,
50 {
51 {0, 0, 0}, // probing for capability
52 {0, 0, 0}, // starts with no sound
53 {0, 0, 2000}, // off and return at 2 seconds
54 }},
55
56 { "VbBootDeveloperSoundTest( normal, background )",
57 0x00000000, VBERROR_SUCCESS,
58 0, 0,
59 7,
60 {
61 {0, 0, 0}, // probing for capability
62 {0, 0, 0}, // starts with no sound
63 {0, 400, 20000}, // starts first beep at 20 seconds
64 {0, 0, 20250}, // stops 250ms later
65 {0, 400, 20500}, // starts second beep
66 {0, 0, 20750}, // stops 250ms later
67 {0, 0, 30000}, // off and return at 30 seconds
68 }},
69
70 { "VbBootDeveloperSoundTest( fast, no background )",
71 0x00000001, VBERROR_NO_BACKGROUND_SOUND,
72 0, 0,
73 2,
74 {
75 {0, 0, 0}, // probing for capability
76 {0, 0, 2000}, // off and return at 2 seconds
77 }},
78
79 { "VbBootDeveloperSoundTest( normal, no background )",
80 0x00000000, VBERROR_NO_BACKGROUND_SOUND,
81 0, 0,
82 4,
83 {
84 {0, 0, 0}, // probing for capability
85 {250, 400, 20000}, // first beep at 20 seconds
86 {250, 400, 20510}, // second beep shortly after
87 {0, 0, 30020}, // off and return at 30 seconds
88 }},
89
90
91 // Now with some keypresses
92
93 { "VbBootDeveloperSoundTest( normal, background, Ctrl-D )",
94 0x00000000, VBERROR_SUCCESS,
95 4, 10000, // Ctrl-D at 10 seconds
96 3,
97 {
98 {0, 0, 0}, // probing for capability
99 {0, 0, 0}, // starts with no sound
100 {0, 0, 10000}, // sees Ctrl-D, sound off, return
101 }},
102
103 { "VbBootDeveloperSoundTest( normal, no background, Ctrl-D )",
104 0x00000000, VBERROR_NO_BACKGROUND_SOUND,
105 4, 20400, // Ctrl-D between beeps
106 3,
107 {
108 {0, 0, 0}, // probing for capability
109 {250, 400, 20000}, // first beep at 20 seconds
110 {0, 0, 20400}, // sees Ctrl-D, sound off, return
111 }},
112
113 { "VbBootDeveloperSoundTest( normal, background, Ctrl-U not allowed )",
114 0x00000000, VBERROR_SUCCESS,
115 21, 10000, // Ctrl-U at 10 seconds
116 10,
117 {
118 {0, 0, 0}, // probing for capability
119 {0, 0, 0}, // starts with no sound
120 {0, 0, 10000}, // sees Ctrl-U, turns sound off
121 {120, 400, 10000}, // complains about Ctrl-U (one beep)
122 // waits 120ms...
123 {120, 400, 10240}, // complains about Ctrl-U (two beeps)
124 // original sequence is now shifted...
125 {0, 400, 20360}, // starts first beep at 20 seconds
126 {0, 0, 20610}, // stops 250ms later
127 {0, 400, 20860}, // starts second beep
128 {0, 0, 21110}, // stops 250ms later
129 {0, 0, 30360}, // returns at 30 seconds + 360ms
130 }},
131
132
133
134
135};
136
137
138/* Mock data */
139static VbCommonParams cparams;
140static LoadKernelParams lkparams;
141static VbNvContext vnc;
142static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
143static VbSharedDataHeader* shared = (VbSharedDataHeader*)shared_data;
144static GoogleBinaryBlockHeader gbb;
145static int current_time;
146static int current_event;
147static int max_events;
148static int matched_events;
149static int kbd_fire_at;
150static uint32_t kbd_fire_key;
151static VbError_t beep_return;
152static note_event_t *expected_event;
153
154
155/* Reset mock data (for use before each test) */
156static void ResetMocks(void) {
157
158 Memset(&cparams, 0, sizeof(cparams));
159 cparams.shared_data_size = sizeof(shared_data);
160 cparams.shared_data_blob = shared_data;
161 cparams.gbb_data = &gbb;
162
163 Memset(&lkparams, 0, sizeof(lkparams));
164
165 Memset(&vnc, 0, sizeof(vnc));
166 VbNvSetup(&vnc);
167 VbNvTeardown(&vnc); /* So CRC gets generated */
168
169 Memset(&shared_data, 0, sizeof(shared_data));
170 VbSharedDataInit(shared, sizeof(shared_data));
171 shared->fw_keyblock_flags = 0xABCDE0;
172
173 Memset(&gbb, 0, sizeof(gbb));
174 gbb.major_version = GBB_MAJOR_VER;
175 gbb.minor_version = GBB_MINOR_VER;
176 gbb.flags = 0;
177
178 current_time = 0;
179 current_event = 0;
180 kbd_fire_at = 0;
181 kbd_fire_key = 0;
182
183 beep_return = VBERROR_SUCCESS;
184
185 matched_events = 0;
186 max_events = 0;
187}
188
189/****************************************************************************/
190/* Mocked verification functions */
191
192VbError_t VbExNvStorageRead(uint8_t* buf) {
193 Memcpy(buf, vnc.raw, sizeof(vnc.raw));
194 return VBERROR_SUCCESS;
195}
196
197VbError_t VbExNvStorageWrite(const uint8_t* buf) {
198 Memcpy(vnc.raw, buf, sizeof(vnc.raw));
199 return VBERROR_SUCCESS;
200}
201
202VbError_t VbExDiskGetInfo(VbDiskInfo** infos_ptr, uint32_t* count,
203 uint32_t disk_flags) {
204 return VBERROR_UNKNOWN;
205}
206
207VbError_t VbExDiskFreeInfo(VbDiskInfo* infos,
208 VbExDiskHandle_t preserve_handle) {
209 return VBERROR_SUCCESS;
210}
211
212VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
213 uint64_t lba_count, void* buffer) {
214 return VBERROR_UNKNOWN;
215}
216
217VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
218 uint64_t lba_count, const void* buffer) {
219 return VBERROR_UNKNOWN;
220}
221
222uint32_t VbExIsShutdownRequested(void) {
223 return 0;
224}
225
226uint32_t VbExKeyboardRead(void) {
227 uint32_t tmp;
228 if (kbd_fire_key && current_time >= kbd_fire_at) {
229 VBDEBUG((" VbExKeyboardRead() - returning %d at %d msec\n",
230 kbd_fire_key, current_time));
231 tmp = kbd_fire_key;
232 kbd_fire_key = 0;
233 return tmp;
234 }
235 return 0;
236}
237
238void VbExSleepMs(uint32_t msec) {
239 current_time += msec;
240}
241
242VbError_t VbExBeep(uint32_t msec, uint32_t frequency) {
243 VBDEBUG(("VbExBeep(%d, %d) at %d msec\n", msec, frequency, current_time));
244
245 if (current_event < max_events &&
246 msec == expected_event[current_event].msec &&
247 frequency == expected_event[current_event].freq &&
248 current_time == expected_event[current_event].time ) {
249 matched_events++;
250 }
251
252 current_time += msec;
253 current_event++;
254 return beep_return;
255}
256
257VbError_t VbExDisplayScreen(uint32_t screen_type) {
258 switch(screen_type) {
259 case VB_SCREEN_BLANK:
260 VBDEBUG(("VbExDisplayScreen(BLANK)\n"));
261 break;
262 case VB_SCREEN_DEVELOPER_WARNING:
263 VBDEBUG(("VbExDisplayScreen(DEV)\n"));
264 break;
265 case VB_SCREEN_DEVELOPER_EGG:
266 VBDEBUG(("VbExDisplayScreen(EGG)\n"));
267 break;
268 case VB_SCREEN_RECOVERY_REMOVE:
269 VBDEBUG(("VbExDisplayScreen(REMOVE)\n"));
270 break;
271 case VB_SCREEN_RECOVERY_INSERT:
272 VBDEBUG(("VbExDisplayScreen(INSERT)\n"));
273 break;
274 case VB_SCREEN_RECOVERY_NO_GOOD:
275 VBDEBUG(("VbExDisplayScreen(NO_GOOD)\n"));
276 break;
277 default:
278 VBDEBUG(("VbExDisplayScreen(%d)\n", screen_type));
279 }
280
281 VBDEBUG((" current_time is %d msec\n", current_time));
282
283 return VBERROR_SUCCESS;
284}
285
286
287/****************************************************************************/
288
289VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p);
290
291
292static void VbBootDeveloperSoundTest(void) {
293 int i;
294 int num_tests = sizeof(test) / sizeof(test_case_t);
295
296 for (i=0; i<num_tests; i++) {
297 VBDEBUG(("STARTING %s ...\n", test[i].name));
298 ResetMocks();
299 gbb.flags = test[i].gbb_flags;
300 beep_return = test[i].beep_return;
301 kbd_fire_key = test[i].keypress_key;
302 kbd_fire_at = test[i].keypress_at_count;
303 max_events = test[i].num_events;
304 expected_event = test[i].notes;
305 (void) VbBootDeveloper(&cparams, &lkparams);
306 VBDEBUG(("INFO: matched %d total %d expected %d\n",
307 matched_events, current_event, test[i].num_events));
308 TEST_EQ(matched_events, test[i].num_events, test[i].name);
309 TEST_EQ(current_event, test[i].num_events, test[i].name);
310 }
311}
312
313
314/* disable MSVC warnings on unused arguments */
315__pragma(warning (disable: 4100))
316
317int main(int argc, char* argv[]) {
318 int error_code = 0;
319
320 VbBootDeveloperSoundTest();
321
322 if (!gTestSuccess)
323 error_code = 255;
324
325 return error_code;
326}