blob: adbeaa9f7ab0038012756c41a33e4fe16c4d0d1b [file] [log] [blame]
Randall Spangler0bf64052013-01-28 15:00:56 -08001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Bill Richardson822eca62011-08-22 14:06:38 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Display functions used in kernel selection.
6 */
7
Bill Richardson0c3ba242013-03-29 11:09:30 -07008#include "sysincludes.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -07009#include "2sysincludes.h"
Bill Richardson0c3ba242013-03-29 11:09:30 -070010
Randall Spangler7c3ae422016-05-11 13:50:18 -070011#include "2common.h"
12#include "2sha.h"
Bill Richardson0a9977e2011-08-22 16:03:59 -070013#include "bmpblk_font.h"
Simon Glass527ba812013-07-25 08:48:47 -060014#include "gbb_access.h"
Bill Richardson822eca62011-08-22 14:06:38 -070015#include "gbb_header.h"
Simon Glass527ba812013-07-25 08:48:47 -060016#include "region.h"
Bill Richardson822eca62011-08-22 14:06:38 -070017#include "utility.h"
18#include "vboot_api.h"
19#include "vboot_common.h"
20#include "vboot_display.h"
21#include "vboot_nvstorage.h"
22
23static uint32_t disp_current_screen = VB_SCREEN_BLANK;
24static uint32_t disp_width = 0, disp_height = 0;
25
Daisuke Nojiribe5eca92015-10-06 17:03:08 -070026__attribute__((weak))
27VbError_t VbExGetLocalizationCount(uint32_t *count) {
28 return VBERROR_UNKNOWN;
29}
30
Randall Spangler0bf64052013-01-28 15:00:56 -080031VbError_t VbGetLocalizationCount(VbCommonParams *cparams, uint32_t *count)
32{
Simon Glass527ba812013-07-25 08:48:47 -060033 BmpBlockHeader hdr;
34 VbError_t ret;
Bill Richardson822eca62011-08-22 14:06:38 -070035
Randall Spangler0bf64052013-01-28 15:00:56 -080036 /* Default to 0 on error */
37 *count = 0;
Bill Richardson822eca62011-08-22 14:06:38 -070038
Daisuke Nojiribe5eca92015-10-06 17:03:08 -070039 /* First try to get the count from GBB */
Simon Glass527ba812013-07-25 08:48:47 -060040 ret = VbGbbReadBmpHeader(cparams, &hdr);
Daisuke Nojiribe5eca92015-10-06 17:03:08 -070041 if (ret == VBERROR_SUCCESS) {
42 *count = hdr.number_of_localizations;
Simon Glass527ba812013-07-25 08:48:47 -060043 return ret;
Daisuke Nojiribe5eca92015-10-06 17:03:08 -070044 }
Bill Richardson822eca62011-08-22 14:06:38 -070045
Daisuke Nojiribe5eca92015-10-06 17:03:08 -070046 /* If GBB is broken or missing, fallback to the callback */
47 return VbExGetLocalizationCount(count);
Bill Richardson822eca62011-08-22 14:06:38 -070048}
49
Randall Spangler0bf64052013-01-28 15:00:56 -080050/*
51 * TODO: We could cache the font info to speed things up, by making the
Bill Richardson0a9977e2011-08-22 16:03:59 -070052 * in-memory font structure distinct from the in-flash version. We'll do that
53 * Real Soon Now. Until then, we just repeat the same linear search every time.
54 */
Bill Richardson0a9977e2011-08-22 16:03:59 -070055
Randall Spanglerfe510c02013-02-06 17:10:55 -080056VbFont_t *VbInternalizeFontData(FontArrayHeader *fonthdr)
Randall Spangler0bf64052013-01-28 15:00:56 -080057{
58 /* Just return the raw data pointer for now. */
59 return (VbFont_t *)fonthdr;
Bill Richardson0a9977e2011-08-22 16:03:59 -070060}
61
Randall Spanglerfe510c02013-02-06 17:10:55 -080062void VbDoneWithFontForNow(VbFont_t *ptr)
Randall Spangler0bf64052013-01-28 15:00:56 -080063{
64 /* Nothing. */
Bill Richardson0a9977e2011-08-22 16:03:59 -070065}
66
Randall Spanglerfe510c02013-02-06 17:10:55 -080067ImageInfo *VbFindFontGlyph(VbFont_t *font, uint32_t ascii,
68 void **bufferptr, uint32_t *buffersize)
Randall Spangler0bf64052013-01-28 15:00:56 -080069{
70 uint8_t *ptr, *firstptr;
71 uint32_t max;
72 uint32_t i;
73 FontArrayEntryHeader *entry;
Bill Richardson0a9977e2011-08-22 16:03:59 -070074
Randall Spangler0bf64052013-01-28 15:00:56 -080075 ptr = (uint8_t *)font;
76 max = ((FontArrayHeader *)ptr)->num_entries;
77 ptr += sizeof(FontArrayHeader);
78 firstptr = ptr;
Bill Richardson0a9977e2011-08-22 16:03:59 -070079
Randall Spangler0bf64052013-01-28 15:00:56 -080080 /*
81 * Simple linear search.
82 *
83 * Note: We're assuming glpyhs are uncompressed. That's true because
84 * the bmpblk_font tool doesn't compress anything. The bmpblk_utility
85 * does, but it compresses the entire font blob at once, and we've
86 * already uncompressed that before we got here.
87 */
88 for(i=0; i<max; i++) {
89 entry = (FontArrayEntryHeader *)ptr;
90 if (entry->ascii == ascii) {
91 *bufferptr = ptr + sizeof(FontArrayEntryHeader);
92 *buffersize = entry->info.original_size;
93 return &(entry->info);
94 }
95 ptr += sizeof(FontArrayEntryHeader)+entry->info.compressed_size;
96 }
Bill Richardson0a9977e2011-08-22 16:03:59 -070097
Randall Spangler0bf64052013-01-28 15:00:56 -080098 /*
99 * We must return something valid. We'll just use the first glyph in
100 * the font structure (so it should be something distinct).
101 */
102 entry = (FontArrayEntryHeader *)firstptr;
103 *bufferptr = firstptr + sizeof(FontArrayEntryHeader);
104 *buffersize = entry->info.original_size;
105 return &(entry->info);
Bill Richardson0a9977e2011-08-22 16:03:59 -0700106}
107
Aaron Durbin9d7d0cb2013-02-26 09:02:02 -0600108void VbRenderTextAtPos(const char *text, int right_to_left,
Randall Spanglerfe510c02013-02-06 17:10:55 -0800109 uint32_t x, uint32_t y, VbFont_t *font)
Randall Spangler0bf64052013-01-28 15:00:56 -0800110{
111 int i;
112 ImageInfo *image_info = 0;
113 void *buffer;
114 uint32_t buffersize;
115 uint32_t cur_x = x, cur_y = y;
Bill Richardson0a9977e2011-08-22 16:03:59 -0700116
Randall Spangler0bf64052013-01-28 15:00:56 -0800117 if (!text || !font) {
118 VBDEBUG((" VbRenderTextAtPos: invalid args\n"));
119 return;
120 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700121
Randall Spangler0bf64052013-01-28 15:00:56 -0800122 for (i=0; text[i]; i++) {
Bill Richardson0a9977e2011-08-22 16:03:59 -0700123
Randall Spangler0bf64052013-01-28 15:00:56 -0800124 if (text[i] == '\n') {
125 if (!image_info)
126 image_info = VbFindFontGlyph(font, text[i],
127 &buffer,
128 &buffersize);
129 cur_x = x;
130 cur_y += image_info->height;
131 continue;
132 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700133
Randall Spangler0bf64052013-01-28 15:00:56 -0800134 image_info = VbFindFontGlyph(font, text[i], &buffer,
135 &buffersize);
Bill Richardson0a9977e2011-08-22 16:03:59 -0700136
Randall Spangler0bf64052013-01-28 15:00:56 -0800137 if (right_to_left)
138 cur_x -= image_info->width;
Bill Richardson0a9977e2011-08-22 16:03:59 -0700139
Randall Spangler0bf64052013-01-28 15:00:56 -0800140 if (VBERROR_SUCCESS != VbExDisplayImage(cur_x, cur_y, buffer,
141 buffersize)) {
142 VBDEBUG((" VbRenderTextAtPos: "
143 "can't display ascii 0x%x\n", text[i]));
144 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700145
Randall Spangler0bf64052013-01-28 15:00:56 -0800146 if (!right_to_left)
147 cur_x += image_info->width;
148 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700149}
150
Randall Spangler0bf64052013-01-28 15:00:56 -0800151VbError_t VbDisplayScreenFromGBB(VbCommonParams *cparams, uint32_t screen,
Daisuke Nojiri93543792015-10-06 16:50:33 -0700152 VbNvContext *vncptr, uint32_t localization)
Randall Spangler0bf64052013-01-28 15:00:56 -0800153{
Simon Glass527ba812013-07-25 08:48:47 -0600154 char *fullimage = NULL;
155 BmpBlockHeader hdr;
Randall Spangler0bf64052013-01-28 15:00:56 -0800156 uint32_t screen_index;
Randall Spangler0bf64052013-01-28 15:00:56 -0800157 VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */
158 uint32_t inoutsize;
Randall Spangler0bf64052013-01-28 15:00:56 -0800159 uint32_t i;
160 VbFont_t *font;
Aaron Durbin9d7d0cb2013-02-26 09:02:02 -0600161 const char *text_to_show;
Randall Spangler0bf64052013-01-28 15:00:56 -0800162 int rtol = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600163 VbError_t ret;
Bill Richardson822eca62011-08-22 14:06:38 -0700164
Simon Glass527ba812013-07-25 08:48:47 -0600165 ret = VbGbbReadBmpHeader(cparams, &hdr);
166 if (ret)
167 return ret;
Bill Richardson822eca62011-08-22 14:06:38 -0700168
Randall Spangler0bf64052013-01-28 15:00:56 -0800169 /*
170 * Translate screen ID into index. Note that not all screens are in
171 * the GBB.
172 *
173 * TODO: ensure screen IDs match indices? Having this translation here
174 * is awful.
175 */
176 switch (screen) {
177 case VB_SCREEN_DEVELOPER_WARNING:
178 screen_index = SCREEN_DEVELOPER_WARNING;
179 break;
180 case VB_SCREEN_RECOVERY_REMOVE:
181 screen_index = SCREEN_RECOVERY_REMOVE;
182 break;
183 case VB_SCREEN_RECOVERY_NO_GOOD:
184 screen_index = SCREEN_RECOVERY_NO_GOOD;
185 break;
186 case VB_SCREEN_RECOVERY_INSERT:
187 screen_index = SCREEN_RECOVERY_INSERT;
188 break;
189 case VB_SCREEN_RECOVERY_TO_DEV:
190 screen_index = SCREEN_RECOVERY_TO_DEV;
191 break;
192 case VB_SCREEN_DEVELOPER_TO_NORM:
193 screen_index = SCREEN_DEVELOPER_TO_NORM;
194 break;
195 case VB_SCREEN_WAIT:
196 screen_index = SCREEN_WAIT;
197 break;
198 case VB_SCREEN_TO_NORM_CONFIRMED:
199 screen_index = SCREEN_TO_NORM_CONFIRMED;
200 break;
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700201 case VB_SCREEN_OS_BROKEN:
202 screen_index = SCREEN_OS_BROKEN;
203 break;
Randall Spangler0bf64052013-01-28 15:00:56 -0800204 case VB_SCREEN_BLANK:
205 case VB_SCREEN_DEVELOPER_EGG:
206 default:
207 /* Screens which aren't in the GBB */
208 VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n",
209 (int)screen));
210 retval = VBERROR_INVALID_SCREEN_INDEX;
211 goto VbDisplayScreenFromGBB_exit;
212 }
Bill Richardson822eca62011-08-22 14:06:38 -0700213
Simon Glass527ba812013-07-25 08:48:47 -0600214 if (screen_index >= hdr.number_of_screenlayouts) {
Randall Spangler0bf64052013-01-28 15:00:56 -0800215 VBDEBUG(("VbDisplayScreenFromGBB(): "
216 "screen %d index %d not in the GBB\n",
217 (int)screen, (int)screen_index));
218 retval = VBERROR_INVALID_SCREEN_INDEX;
219 goto VbDisplayScreenFromGBB_exit;
220 }
Bill Richardson822eca62011-08-22 14:06:38 -0700221
Randall Spangler0bf64052013-01-28 15:00:56 -0800222 /* Clip localization to number of localizations present in the GBB */
Simon Glass527ba812013-07-25 08:48:47 -0600223 if (localization >= hdr.number_of_localizations) {
Randall Spangler0bf64052013-01-28 15:00:56 -0800224 localization = 0;
225 VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, localization);
Bill Richardsonb64f0972014-05-28 15:49:23 -0700226 VbNvSet(vncptr, VBNV_BACKUP_NVRAM_REQUEST, 1);
Randall Spangler0bf64052013-01-28 15:00:56 -0800227 }
Bill Richardson822eca62011-08-22 14:06:38 -0700228
Randall Spangler0bf64052013-01-28 15:00:56 -0800229 /* Display all bitmaps for the image */
230 for (i = 0; i < MAX_IMAGE_IN_LAYOUT; i++) {
Simon Glass527ba812013-07-25 08:48:47 -0600231 ScreenLayout layout;
232 ImageInfo image_info;
233 char hwid[256];
Yoshiki Iguchi8fa13ad2013-08-29 05:10:33 +0000234
Simon Glass527ba812013-07-25 08:48:47 -0600235 ret = VbGbbReadImage(cparams, localization, screen_index,
236 i, &layout, &image_info,
237 &fullimage, &inoutsize);
238 if (ret == VBERROR_NO_IMAGE_PRESENT) {
239 continue;
240 } else if (ret) {
241 retval = ret;
242 goto VbDisplayScreenFromGBB_exit;
Randall Spangler0bf64052013-01-28 15:00:56 -0800243 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700244
Simon Glass527ba812013-07-25 08:48:47 -0600245 switch(image_info.format) {
Randall Spangler0bf64052013-01-28 15:00:56 -0800246 case FORMAT_BMP:
Hung-Te Lin5e8f1db2014-05-09 20:40:15 +0800247 if (i == 0) {
248 /**
249 * In current version GBB bitmaps, first image
250 * is always the background.
251 */
252 ret = VbExDisplaySetDimension(
253 image_info.width,
254 image_info.height);
Hung-Te Lin8f7b7052014-05-21 11:15:57 +0800255 if (ret) {
Hung-Te Lin5e8f1db2014-05-09 20:40:15 +0800256 VBDEBUG(("VbExDisplaySetDimension"
Hung-Te Lin8f7b7052014-05-21 11:15:57 +0800257 "(%d,%d): failed (%#x).\n",
Hung-Te Lin5e8f1db2014-05-09 20:40:15 +0800258 image_info.width,
Hung-Te Lin8f7b7052014-05-21 11:15:57 +0800259 image_info.height, ret));
Hung-Te Lin5e8f1db2014-05-09 20:40:15 +0800260 }
261 }
262
Simon Glass527ba812013-07-25 08:48:47 -0600263 retval = VbExDisplayImage(layout.images[i].x,
264 layout.images[i].y,
Randall Spangler0bf64052013-01-28 15:00:56 -0800265 fullimage, inoutsize);
266 break;
Bill Richardson0a9977e2011-08-22 16:03:59 -0700267
Randall Spangler0bf64052013-01-28 15:00:56 -0800268 case FORMAT_FONT:
269 /*
270 * The uncompressed blob is our font structure. Cache
271 * it as needed.
272 */
Simon Glass527ba812013-07-25 08:48:47 -0600273 font = VbInternalizeFontData(
274 (FontArrayHeader *)fullimage);
Bill Richardson0a9977e2011-08-22 16:03:59 -0700275
Randall Spangler0bf64052013-01-28 15:00:56 -0800276 /* TODO: handle text in general here */
Simon Glass527ba812013-07-25 08:48:47 -0600277 if (TAG_HWID == image_info.tag ||
278 TAG_HWID_RTOL == image_info.tag) {
279 VbRegionReadHWID(cparams, hwid, sizeof(hwid));
280 text_to_show = hwid;
281 rtol = (TAG_HWID_RTOL == image_info.tag);
Randall Spangler0bf64052013-01-28 15:00:56 -0800282 } else {
283 text_to_show = "";
284 rtol = 0;
285 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700286
Randall Spangler0bf64052013-01-28 15:00:56 -0800287 VbRenderTextAtPos(text_to_show, rtol,
Simon Glass527ba812013-07-25 08:48:47 -0600288 layout.images[i].x,
289 layout.images[i].y, font);
Bill Richardson0a9977e2011-08-22 16:03:59 -0700290
Randall Spangler0bf64052013-01-28 15:00:56 -0800291 VbDoneWithFontForNow(font);
292 break;
Bill Richardson0a9977e2011-08-22 16:03:59 -0700293
Randall Spangler0bf64052013-01-28 15:00:56 -0800294 default:
295 VBDEBUG(("VbDisplayScreenFromGBB(): "
296 "unsupported ImageFormat %d\n",
Simon Glass527ba812013-07-25 08:48:47 -0600297 image_info.format));
Randall Spangler0bf64052013-01-28 15:00:56 -0800298 retval = VBERROR_INVALID_GBB;
299 }
Bill Richardson0a9977e2011-08-22 16:03:59 -0700300
Randall Spangler559a1102016-10-18 14:41:22 -0700301 free(fullimage);
Bill Richardson822eca62011-08-22 14:06:38 -0700302
Randall Spangler0bf64052013-01-28 15:00:56 -0800303 if (VBERROR_SUCCESS != retval)
304 goto VbDisplayScreenFromGBB_exit;
305 }
Bill Richardson822eca62011-08-22 14:06:38 -0700306
Randall Spangler0bf64052013-01-28 15:00:56 -0800307 /* Successful if all bitmaps displayed */
308 retval = VBERROR_SUCCESS;
Bill Richardsonec35beb2011-09-14 10:42:54 -0700309
Simon Glass527ba812013-07-25 08:48:47 -0600310 VbRegionCheckVersion(cparams);
Bill Richardsonec35beb2011-09-14 10:42:54 -0700311
Randall Spangler0bf64052013-01-28 15:00:56 -0800312 VbDisplayScreenFromGBB_exit:
313 VBDEBUG(("leaving VbDisplayScreenFromGBB() with %d\n",retval));
314 return retval;
Bill Richardson822eca62011-08-22 14:06:38 -0700315}
316
Daisuke Nojiriffc446b2015-11-16 11:47:28 -0800317/*
318 * This is the deprecated display screen function. This should be called only
319 * if bmpblk.bin is found in GBB. New devices store graphics data in cbfs
320 * and screens are rendered by Depthcharge (chromium:502066).
321 */
322static VbError_t VbDisplayScreenLegacy(VbCommonParams *cparams, uint32_t screen,
323 int force, VbNvContext *vncptr,
324 uint32_t locale)
Randall Spangler0bf64052013-01-28 15:00:56 -0800325{
326 VbError_t retval;
Bill Richardson822eca62011-08-22 14:06:38 -0700327
Randall Spangler0bf64052013-01-28 15:00:56 -0800328 /* Initialize display if necessary */
329 if (!disp_width) {
330 retval = VbExDisplayInit(&disp_width, &disp_height);
331 if (VBERROR_SUCCESS != retval)
332 return retval;
333 }
Bill Richardson822eca62011-08-22 14:06:38 -0700334
Randall Spangler0bf64052013-01-28 15:00:56 -0800335 /* If the screen is blank, turn off the backlight; else turn it on. */
336 VbExDisplayBacklight(VB_SCREEN_BLANK == screen ? 0 : 1);
Bill Richardson822eca62011-08-22 14:06:38 -0700337
Randall Spangler0bf64052013-01-28 15:00:56 -0800338 /* Look in the GBB first */
Simon Glass527ba812013-07-25 08:48:47 -0600339 if (VBERROR_SUCCESS == VbDisplayScreenFromGBB(cparams, screen,
Daisuke Nojiri93543792015-10-06 16:50:33 -0700340 vncptr, locale))
Randall Spangler0bf64052013-01-28 15:00:56 -0800341 return VBERROR_SUCCESS;
Bill Richardson822eca62011-08-22 14:06:38 -0700342
Randall Spangler0bf64052013-01-28 15:00:56 -0800343 /* If screen wasn't in the GBB bitmaps, fall back to a default */
Daisuke Nojiri93543792015-10-06 16:50:33 -0700344 return VbExDisplayScreen(screen, locale);
Bill Richardson822eca62011-08-22 14:06:38 -0700345}
346
Daisuke Nojiriffc446b2015-11-16 11:47:28 -0800347VbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen,
348 int force, VbNvContext *vncptr)
349{
350 uint32_t locale;
351 GoogleBinaryBlockHeader *gbb = cparams->gbb;
Daisuke Nojiriff9c2b22016-04-21 14:54:45 -0700352 VbError_t rv;
353
354 /* If requested screen is the same as the current one, we're done. */
355 if (disp_current_screen == screen && !force)
356 return VBERROR_SUCCESS;
Daisuke Nojiriffc446b2015-11-16 11:47:28 -0800357
358 /* Read the locale last saved */
359 VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &locale);
360
Daisuke Nojiriff9c2b22016-04-21 14:54:45 -0700361 if (gbb->bmpfv_size == 0)
362 rv = VbExDisplayScreen(screen, locale);
363 else
364 rv = VbDisplayScreenLegacy(cparams, screen, force, vncptr,
365 locale);
Duncan Laurie933c4e72016-01-29 09:45:51 -0800366
Daisuke Nojiriff9c2b22016-04-21 14:54:45 -0700367 if (rv == VBERROR_SUCCESS)
Duncan Laurie933c4e72016-01-29 09:45:51 -0800368 /* Keep track of the currently displayed screen */
Daisuke Nojiriff9c2b22016-04-21 14:54:45 -0700369 disp_current_screen = screen;
Daisuke Nojiriffc446b2015-11-16 11:47:28 -0800370
Daisuke Nojiriff9c2b22016-04-21 14:54:45 -0700371 return rv;
Daisuke Nojiriffc446b2015-11-16 11:47:28 -0800372}
373
Randall Spangler0bf64052013-01-28 15:00:56 -0800374static void Uint8ToString(char *buf, uint8_t val)
375{
376 const char *trans = "0123456789abcdef";
377 *buf++ = trans[val >> 4];
378 *buf = trans[val & 0xF];
Bill Richardson5de6b402011-09-01 14:47:05 -0700379}
380
Randall Spangler0bf64052013-01-28 15:00:56 -0800381static void FillInSha1Sum(char *outbuf, VbPublicKey *key)
382{
383 uint8_t *buf = ((uint8_t *)key) + key->key_offset;
384 uint64_t buflen = key->key_size;
Randall Spangler7c3ae422016-05-11 13:50:18 -0700385 uint8_t digest[VB2_SHA1_DIGEST_SIZE];
Randall Spangler0bf64052013-01-28 15:00:56 -0800386 int i;
Randall Spangler7c3ae422016-05-11 13:50:18 -0700387
388 vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
389 for (i = 0; i < sizeof(digest); i++) {
Randall Spangler0bf64052013-01-28 15:00:56 -0800390 Uint8ToString(outbuf, digest[i]);
391 outbuf += 2;
392 }
393 *outbuf = '\0';
Bill Richardson5de6b402011-09-01 14:47:05 -0700394}
395
Randall Spangler0bf64052013-01-28 15:00:56 -0800396const char *RecoveryReasonString(uint8_t code)
397{
398 switch(code) {
399 case VBNV_RECOVERY_NOT_REQUESTED:
400 return "Recovery not requested";
401 case VBNV_RECOVERY_LEGACY:
402 return "Recovery requested from legacy utility";
403 case VBNV_RECOVERY_RO_MANUAL:
404 return "recovery button pressed";
405 case VBNV_RECOVERY_RO_INVALID_RW:
406 return "RW firmware failed signature check";
407 case VBNV_RECOVERY_RO_S3_RESUME:
408 return "S3 resume failed";
409 case VBNV_RECOVERY_DEP_RO_TPM_ERROR:
410 return "TPM error in read-only firmware";
411 case VBNV_RECOVERY_RO_SHARED_DATA:
412 return "Shared data error in read-only firmware";
413 case VBNV_RECOVERY_RO_TEST_S3:
414 return "Test error from S3Resume()";
415 case VBNV_RECOVERY_RO_TEST_LFS:
416 return "Test error from LoadFirmwareSetup()";
417 case VBNV_RECOVERY_RO_TEST_LF:
418 return "Test error from LoadFirmware()";
419 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NOT_DONE:
420 return "RW firmware check not done";
421 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_DEV_MISMATCH:
422 return "RW firmware developer flag mismatch";
423 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_REC_MISMATCH:
424 return "RW firmware recovery flag mismatch";
425 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
426 VBSD_LF_CHECK_VERIFY_KEYBLOCK:
427 return "RW firmware unable to verify key block";
428 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_KEY_ROLLBACK:
429 return "RW firmware key version rollback detected";
430 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
431 VBSD_LF_CHECK_DATA_KEY_PARSE:
432 return "RW firmware unable to parse data key";
433 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
434 VBSD_LF_CHECK_VERIFY_PREAMBLE:
435 return "RW firmware unable to verify preamble";
436 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_FW_ROLLBACK:
437 return "RW firmware version rollback detected";
438 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_GET_FW_BODY:
439 return "RW firmware unable to get firmware body";
440 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
441 VBSD_LF_CHECK_HASH_WRONG_SIZE:
442 return "RW firmware hash is wrong size";
443 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_VERIFY_BODY:
444 return "RW firmware unable to verify firmware body";
445 case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NO_RO_NORMAL:
446 return "RW firmware read-only normal path is not supported";
447 case VBNV_RECOVERY_RO_FIRMWARE:
448 return "Firmware problem outside of verified boot";
449 case VBNV_RECOVERY_RO_TPM_REBOOT:
450 return "TPM requires a system reboot (should be transient)";
451 case VBNV_RECOVERY_EC_SOFTWARE_SYNC:
452 return "EC software sync error";
453 case VBNV_RECOVERY_EC_UNKNOWN_IMAGE:
454 return "EC software sync unable to determine active EC image";
455 case VBNV_RECOVERY_DEP_EC_HASH:
456 return "EC software sync error obtaining EC image hash";
457 case VBNV_RECOVERY_EC_EXPECTED_IMAGE:
458 return "EC software sync error "
459 "obtaining expected EC image from BIOS";
Randall Spangler5ca4ea02013-02-04 15:00:09 -0800460 case VBNV_RECOVERY_EC_EXPECTED_HASH:
461 return "EC software sync error "
462 "obtaining expected EC hash from BIOS";
463 case VBNV_RECOVERY_EC_HASH_MISMATCH:
464 return "EC software sync error "
465 "comparing expected EC hash and image";
Randall Spangler0bf64052013-01-28 15:00:56 -0800466 case VBNV_RECOVERY_EC_UPDATE:
467 return "EC software sync error updating EC";
468 case VBNV_RECOVERY_EC_JUMP_RW:
469 return "EC software sync unable to jump to EC-RW";
470 case VBNV_RECOVERY_EC_PROTECT:
471 return "EC software sync protection error";
Julius Wernerdc8ec102015-02-10 14:34:01 -0800472 case VBNV_RECOVERY_VB2_SECDATA_INIT:
473 return "Secure NVRAM (TPM) initialization error";
474 case VBNV_RECOVERY_VB2_GBB_HEADER:
475 return "Error parsing GBB header";
476 case VBNV_RECOVERY_VB2_TPM_CLEAR_OWNER:
477 return "Error trying to clear TPM owner";
478 case VBNV_RECOVERY_VB2_DEV_SWITCH:
479 return "Error reading or updating developer switch";
480 case VBNV_RECOVERY_VB2_FW_SLOT:
481 return "Error selecting RW firmware slot";
Randall Spangler0bf64052013-01-28 15:00:56 -0800482 case VBNV_RECOVERY_RO_UNSPECIFIED:
483 return "Unspecified/unknown error in RO firmware";
484 case VBNV_RECOVERY_RW_DEV_SCREEN:
485 return "User requested recovery from dev-mode warning screen";
486 case VBNV_RECOVERY_RW_NO_OS:
487 return "No OS kernel detected (or kernel rollback attempt?)";
488 case VBNV_RECOVERY_RW_INVALID_OS:
489 return "OS kernel failed signature check";
490 case VBNV_RECOVERY_DEP_RW_TPM_ERROR:
491 return "TPM error in rewritable firmware";
492 case VBNV_RECOVERY_RW_DEV_MISMATCH:
493 return "RW firmware in dev mode, but dev switch is off";
494 case VBNV_RECOVERY_RW_SHARED_DATA:
495 return "Shared data error in rewritable firmware";
496 case VBNV_RECOVERY_RW_TEST_LK:
497 return "Test error from LoadKernel()";
498 case VBNV_RECOVERY_DEP_RW_NO_DISK:
499 return "No bootable disk found";
500 case VBNV_RECOVERY_TPM_E_FAIL:
501 return "TPM error that was not fixed by reboot";
502 case VBNV_RECOVERY_RO_TPM_S_ERROR:
503 return "TPM setup error in read-only firmware";
504 case VBNV_RECOVERY_RO_TPM_W_ERROR:
505 return "TPM write error in read-only firmware";
506 case VBNV_RECOVERY_RO_TPM_L_ERROR:
507 return "TPM lock error in read-only firmware";
508 case VBNV_RECOVERY_RO_TPM_U_ERROR:
509 return "TPM update error in read-only firmware";
510 case VBNV_RECOVERY_RW_TPM_R_ERROR:
511 return "TPM read error in rewritable firmware";
512 case VBNV_RECOVERY_RW_TPM_W_ERROR:
513 return "TPM write error in rewritable firmware";
514 case VBNV_RECOVERY_RW_TPM_L_ERROR:
515 return "TPM lock error in rewritable firmware";
516 case VBNV_RECOVERY_EC_HASH_FAILED:
517 return "EC software sync unable to get EC image hash";
518 case VBNV_RECOVERY_EC_HASH_SIZE:
519 return "EC software sync invalid image hash size";
520 case VBNV_RECOVERY_LK_UNSPECIFIED:
521 return "Unspecified error while trying to load kernel";
522 case VBNV_RECOVERY_RW_NO_DISK:
523 return "No bootable storage device in system";
524 case VBNV_RECOVERY_RW_NO_KERNEL:
525 return "No bootable kernel found on disk";
Furquan Shaikh3479e842015-06-04 09:07:49 -0700526 case VBNV_RECOVERY_RW_BCB_ERROR:
527 return "BCB partition error on disk";
Furquan Shaikhf8438712015-06-20 14:17:42 -0700528 case VBNV_RECOVERY_FW_FASTBOOT:
529 return "Fastboot-mode requested in firmware";
Randall Spangler0bf64052013-01-28 15:00:56 -0800530 case VBNV_RECOVERY_RW_UNSPECIFIED:
531 return "Unspecified/unknown error in RW firmware";
532 case VBNV_RECOVERY_KE_DM_VERITY:
533 return "DM-verity error";
534 case VBNV_RECOVERY_KE_UNSPECIFIED:
535 return "Unspecified/unknown error in kernel";
536 case VBNV_RECOVERY_US_TEST:
537 return "Recovery mode test from user-mode";
Furquan Shaikh3479e842015-06-04 09:07:49 -0700538 case VBNV_RECOVERY_BCB_USER_MODE:
539 return "User-mode requested recovery via BCB";
Furquan Shaikhf29dbbc2015-08-18 21:19:28 -0700540 case VBNV_RECOVERY_US_FASTBOOT:
541 return "User-mode requested fastboot mode";
Randall Spangler0bf64052013-01-28 15:00:56 -0800542 case VBNV_RECOVERY_US_UNSPECIFIED:
543 return "Unspecified/unknown error in user-mode";
544 }
545 return "We have no idea what this means";
Bill Richardsonf2ad05f2011-09-28 14:42:36 -0700546}
547
Bill Richardson822eca62011-08-22 14:06:38 -0700548#define DEBUG_INFO_SIZE 512
549
Randall Spangler0bf64052013-01-28 15:00:56 -0800550VbError_t VbDisplayDebugInfo(VbCommonParams *cparams, VbNvContext *vncptr)
551{
552 VbSharedDataHeader *shared =
553 (VbSharedDataHeader *)cparams->shared_data_blob;
Simon Glass527ba812013-07-25 08:48:47 -0600554 GoogleBinaryBlockHeader *gbb = cparams->gbb;
Randall Spangler0bf64052013-01-28 15:00:56 -0800555 char buf[DEBUG_INFO_SIZE] = "";
Randall Spangler7c3ae422016-05-11 13:50:18 -0700556 char sha1sum[VB2_SHA1_DIGEST_SIZE * 2 + 1];
Simon Glass527ba812013-07-25 08:48:47 -0600557 char hwid[256];
Randall Spangler0bf64052013-01-28 15:00:56 -0800558 uint32_t used = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600559 VbPublicKey *key;
560 VbError_t ret;
Randall Spangler0bf64052013-01-28 15:00:56 -0800561 uint32_t i;
Bill Richardson822eca62011-08-22 14:06:38 -0700562
Randall Spangler0bf64052013-01-28 15:00:56 -0800563 /* Redisplay current screen to overwrite any previous debug output */
564 VbDisplayScreen(cparams, disp_current_screen, 1, vncptr);
Bill Richardson822eca62011-08-22 14:06:38 -0700565
Randall Spangler0bf64052013-01-28 15:00:56 -0800566 /* Add hardware ID */
Simon Glass527ba812013-07-25 08:48:47 -0600567 VbRegionReadHWID(cparams, hwid, sizeof(hwid));
Bill Richardson5fed2a62013-03-04 15:11:38 -0800568 used += StrnAppend(buf + used, "HWID: ", DEBUG_INFO_SIZE - used);
Simon Glass527ba812013-07-25 08:48:47 -0600569 used += StrnAppend(buf + used, hwid, DEBUG_INFO_SIZE - used);
Bill Richardson822eca62011-08-22 14:06:38 -0700570
Julius Wernerdc8ec102015-02-10 14:34:01 -0800571 /* Add recovery reason and subcode */
572 VbNvGet(vncptr, VBNV_RECOVERY_SUBCODE, &i);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800573 used += StrnAppend(buf + used,
Randall Spangler0bf64052013-01-28 15:00:56 -0800574 "\nrecovery_reason: 0x", DEBUG_INFO_SIZE - used);
575 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
576 shared->recovery_reason, 16, 2);
Julius Wernerdc8ec102015-02-10 14:34:01 -0800577 used += StrnAppend(buf + used, " / 0x", DEBUG_INFO_SIZE - used);
578 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 16, 2);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800579 used += StrnAppend(buf + used, " ", DEBUG_INFO_SIZE - used);
580 used += StrnAppend(buf + used,
Randall Spangler0bf64052013-01-28 15:00:56 -0800581 RecoveryReasonString(shared->recovery_reason),
582 DEBUG_INFO_SIZE - used);
Bill Richardsonf2ad05f2011-09-28 14:42:36 -0700583
Randall Spangler0bf64052013-01-28 15:00:56 -0800584 /* Add VbSharedData flags */
Bill Richardson5fed2a62013-03-04 15:11:38 -0800585 used += StrnAppend(buf + used, "\nVbSD.flags: 0x", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800586 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
587 shared->flags, 16, 8);
Bill Richardson822eca62011-08-22 14:06:38 -0700588
Randall Spangler0bf64052013-01-28 15:00:56 -0800589 /* Add raw contents of VbNvStorage */
Bill Richardson5fed2a62013-03-04 15:11:38 -0800590 used += StrnAppend(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800591 for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
Bill Richardson5fed2a62013-03-04 15:11:38 -0800592 used += StrnAppend(buf + used, " ", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800593 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
594 vncptr->raw[i], 16, 2);
595 }
Bill Richardson822eca62011-08-22 14:06:38 -0700596
Randall Spangler0bf64052013-01-28 15:00:56 -0800597 /* Add dev_boot_usb flag */
598 VbNvGet(vncptr, VBNV_DEV_BOOT_USB, &i);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800599 used += StrnAppend(buf + used, "\ndev_boot_usb: ", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800600 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
Bill Richardson822eca62011-08-22 14:06:38 -0700601
Randall Spangler0bf64052013-01-28 15:00:56 -0800602 /* Add dev_boot_legacy flag */
603 VbNvGet(vncptr, VBNV_DEV_BOOT_LEGACY, &i);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800604 used += StrnAppend(buf + used,
Randall Spangler0bf64052013-01-28 15:00:56 -0800605 "\ndev_boot_legacy: ", DEBUG_INFO_SIZE - used);
606 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
Bill Richardson822eca62011-08-22 14:06:38 -0700607
Mary Ruthven12a55f22015-10-06 10:42:31 -0700608 /* Add dev_default_boot flag */
609 VbNvGet(vncptr, VBNV_DEV_DEFAULT_BOOT, &i);
610 used += StrnAppend(buf + used,
611 "\ndev_default_boot: ", DEBUG_INFO_SIZE - used);
612 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
613
Randall Spangler0bf64052013-01-28 15:00:56 -0800614 /* Add dev_boot_signed_only flag */
615 VbNvGet(vncptr, VBNV_DEV_BOOT_SIGNED_ONLY, &i);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800616 used += StrnAppend(buf + used, "\ndev_boot_signed_only: ",
Randall Spangler0bf64052013-01-28 15:00:56 -0800617 DEBUG_INFO_SIZE - used);
618 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
Stefan Reinauera2326ee2012-08-23 15:06:45 -0700619
Furquan Shaikh9101df22015-05-14 12:53:19 -0700620 /* Add dev_boot_fastboot_full_cap flag */
621 VbNvGet(vncptr, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &i);
622 used += StrnAppend(buf + used, "\ndev_boot_fastboot_full_cap: ",
623 DEBUG_INFO_SIZE - used);
624 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
625
Randall Spangler0bf64052013-01-28 15:00:56 -0800626 /* Add TPM versions */
Bill Richardson5fed2a62013-03-04 15:11:38 -0800627 used += StrnAppend(buf + used, "\nTPM: fwver=0x", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800628 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
629 shared->fw_version_tpm, 16, 8);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800630 used += StrnAppend(buf + used, " kernver=0x", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800631 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
632 shared->kernel_version_tpm, 16, 8);
Bill Richardsonfa9d7782011-11-09 09:11:34 -0800633
Randall Spangler0bf64052013-01-28 15:00:56 -0800634 /* Add GBB flags */
Bill Richardson5fed2a62013-03-04 15:11:38 -0800635 used += StrnAppend(buf + used, "\ngbb.flags: 0x", DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800636 if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1) {
637 used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
638 gbb->flags, 16, 8);
639 } else {
Bill Richardson5fed2a62013-03-04 15:11:38 -0800640 used += StrnAppend(buf + used,
Randall Spangler0bf64052013-01-28 15:00:56 -0800641 "0 (default)", DEBUG_INFO_SIZE - used);
642 }
Bill Richardson822eca62011-08-22 14:06:38 -0700643
Randall Spangler0bf64052013-01-28 15:00:56 -0800644 /* Add sha1sum for Root & Recovery keys */
Simon Glass527ba812013-07-25 08:48:47 -0600645 ret = VbGbbReadRootKey(cparams, &key);
646 if (!ret) {
647 FillInSha1Sum(sha1sum, key);
Randall Spangler559a1102016-10-18 14:41:22 -0700648 free(key);
Simon Glass527ba812013-07-25 08:48:47 -0600649 used += StrnAppend(buf + used, "\ngbb.rootkey: ",
650 DEBUG_INFO_SIZE - used);
651 used += StrnAppend(buf + used, sha1sum,
652 DEBUG_INFO_SIZE - used);
653 }
654
655 ret = VbGbbReadRecoveryKey(cparams, &key);
656 if (!ret) {
657 FillInSha1Sum(sha1sum, key);
Randall Spangler559a1102016-10-18 14:41:22 -0700658 free(key);
Simon Glass527ba812013-07-25 08:48:47 -0600659 used += StrnAppend(buf + used, "\ngbb.recovery_key: ",
660 DEBUG_INFO_SIZE - used);
661 used += StrnAppend(buf + used, sha1sum,
662 DEBUG_INFO_SIZE - used);
663 }
Bill Richardson822eca62011-08-22 14:06:38 -0700664
Randall Spangler0bf64052013-01-28 15:00:56 -0800665 /* If we're in dev-mode, show the kernel subkey that we expect, too. */
666 if (0 == shared->recovery_reason) {
667 FillInSha1Sum(sha1sum, &shared->kernel_subkey);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800668 used += StrnAppend(buf + used,
Randall Spangler0bf64052013-01-28 15:00:56 -0800669 "\nkernel_subkey: ", DEBUG_INFO_SIZE - used);
Bill Richardson5fed2a62013-03-04 15:11:38 -0800670 used += StrnAppend(buf + used, sha1sum, DEBUG_INFO_SIZE - used);
Randall Spangler0bf64052013-01-28 15:00:56 -0800671 }
Bill Richardson5de6b402011-09-01 14:47:05 -0700672
Randall Spangler0bf64052013-01-28 15:00:56 -0800673 /* Make sure we finish with a newline */
Bill Richardson5fed2a62013-03-04 15:11:38 -0800674 used += StrnAppend(buf + used, "\n", DEBUG_INFO_SIZE - used);
Bill Richardson5de6b402011-09-01 14:47:05 -0700675
Randall Spangler0bf64052013-01-28 15:00:56 -0800676 /* TODO: add more interesting data:
677 * - Information on current disks */
Bill Richardson822eca62011-08-22 14:06:38 -0700678
Randall Spangler0bf64052013-01-28 15:00:56 -0800679 buf[DEBUG_INFO_SIZE - 1] = '\0';
680 return VbExDisplayDebugInfo(buf);
Bill Richardson822eca62011-08-22 14:06:38 -0700681}
682
Bill Richardson518d4f32011-09-13 15:28:55 -0700683#define MAGIC_WORD_LEN 5
Randall Spangler0bf64052013-01-28 15:00:56 -0800684#define MAGIC_WORD "xyzzy"
Bill Richardson518d4f32011-09-13 15:28:55 -0700685static uint8_t MagicBuffer[MAGIC_WORD_LEN];
686
Randall Spangler0bf64052013-01-28 15:00:56 -0800687VbError_t VbCheckDisplayKey(VbCommonParams *cparams, uint32_t key,
688 VbNvContext *vncptr)
689{
690 int i;
Bill Richardson518d4f32011-09-13 15:28:55 -0700691
Randall Spangler0bf64052013-01-28 15:00:56 -0800692 /* Update key buffer */
693 for(i = 1; i < MAGIC_WORD_LEN; i++)
694 MagicBuffer[i - 1] = MagicBuffer[i];
695 /* Save as lower-case ASCII */
696 MagicBuffer[MAGIC_WORD_LEN - 1] = (key | 0x20) & 0xFF;
Bill Richardson822eca62011-08-22 14:06:38 -0700697
Randall Spangler0bf64052013-01-28 15:00:56 -0800698 if ('\t' == key) {
699 /* Tab = display debug info */
700 return VbDisplayDebugInfo(cparams, vncptr);
701 } else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key ||
702 VB_KEY_DOWN == key || VB_KEY_UP == key) {
703 /* Arrow keys = change localization */
704 uint32_t loc = 0;
705 uint32_t count = 0;
Bill Richardson822eca62011-08-22 14:06:38 -0700706
Randall Spangler0bf64052013-01-28 15:00:56 -0800707 VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &loc);
708 if (VBERROR_SUCCESS != VbGetLocalizationCount(cparams, &count))
709 loc = 0; /* No localization count (bad GBB?) */
710 else if (VB_KEY_RIGHT == key || VB_KEY_UP == key)
711 loc = (loc < count - 1 ? loc + 1 : 0);
712 else
713 loc = (loc > 0 ? loc - 1 : count - 1);
714 VBDEBUG(("VbCheckDisplayKey() - change localization to %d\n",
715 (int)loc));
716 VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, loc);
Bill Richardsonb64f0972014-05-28 15:49:23 -0700717 VbNvSet(vncptr, VBNV_BACKUP_NVRAM_REQUEST, 1);
Simon Glass985e90e2012-09-06 14:57:54 -0700718
Randall Spanglerbe94d552012-09-24 10:16:15 -0700719#ifdef SAVE_LOCALE_IMMEDIATELY
Randall Spangler0bf64052013-01-28 15:00:56 -0800720 VbNvTeardown(vncptr); /* really only computes checksum */
721 if (vncptr->raw_changed)
722 VbExNvStorageWrite(vncptr->raw);
Simon Glass985e90e2012-09-06 14:57:54 -0700723#endif
Bill Richardson822eca62011-08-22 14:06:38 -0700724
Randall Spangler0bf64052013-01-28 15:00:56 -0800725 /* Force redraw of current screen */
726 return VbDisplayScreen(cparams, disp_current_screen, 1, vncptr);
727 }
Bill Richardson822eca62011-08-22 14:06:38 -0700728
Randall Spangler664096b2016-10-13 16:16:41 -0700729 if (0 == memcmp(MagicBuffer, MAGIC_WORD, MAGIC_WORD_LEN)) {
Randall Spangler0bf64052013-01-28 15:00:56 -0800730 if (VBEASTEREGG)
731 (void)VbDisplayScreen(cparams, disp_current_screen,
732 1, vncptr);
733 }
Bill Richardson518d4f32011-09-13 15:28:55 -0700734
Bill Richardson822eca62011-08-22 14:06:38 -0700735 return VBERROR_SUCCESS;
736}