vboot_display.c revision fe510c06204c763e61aa36d2263c3b8b79c79879
10bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson * Use of this source code is governed by a BSD-style license that can be 3822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson * found in the LICENSE file. 4822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson * 5822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson * Display functions used in kernel selection. 6822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson */ 7822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 80a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson#include "bmpblk_font.h" 9822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "gbb_header.h" 10822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "utility.h" 11822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "vboot_api.h" 12822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "vboot_common.h" 13822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "vboot_display.h" 14822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#include "vboot_nvstorage.h" 15822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 16822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardsonstatic uint32_t disp_current_screen = VB_SCREEN_BLANK; 17822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardsonstatic uint32_t disp_width = 0, disp_height = 0; 18822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall SpanglerVbError_t VbGetLocalizationCount(VbCommonParams *cparams, uint32_t *count) 200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler GoogleBinaryBlockHeader *gbb = 220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (GoogleBinaryBlockHeader *)cparams->gbb_data; 230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler BmpBlockHeader *hdr; 240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Default to 0 on error */ 260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *count = 0; 270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Make sure bitmap data is inside the GBB and is non-zero in size */ 290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == gbb->bmpfv_size || 300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->bmpfv_offset > cparams->gbb_size || 310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->bmpfv_offset + gbb->bmpfv_size > cparams->gbb_size) { 320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_INVALID_GBB; 330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Sanity-check the bitmap block header */ 360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler hdr = (BmpBlockHeader *)(((uint8_t *)gbb) + gbb->bmpfv_offset); 370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if ((0 != Memcmp(hdr->signature, BMPBLOCK_SIGNATURE, 380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler BMPBLOCK_SIGNATURE_SIZE)) || 390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (hdr->major_version > BMPBLOCK_MAJOR_VERSION) || 400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ((hdr->major_version == BMPBLOCK_MAJOR_VERSION) && 410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (hdr->minor_version > BMPBLOCK_MINOR_VERSION))) { 420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_INVALID_BMPFV; 430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *count = hdr->number_of_localizations; 460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_SUCCESS; 470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler} 48822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spanglerchar *VbHWID(VbCommonParams *cparams) 500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler GoogleBinaryBlockHeader *gbb = 520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (GoogleBinaryBlockHeader *)cparams->gbb_data; 53822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == gbb->hwid_size || 550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->hwid_offset > cparams->gbb_size || 560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) { 570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbHWID(): invalid hwid offset/size\n")); 580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "{INVALID}"; 590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 60822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return (char *)((uint8_t *)gbb + gbb->hwid_offset); 620a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson} 630a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler/* 650bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * TODO: We could cache the font info to speed things up, by making the 660a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson * in-memory font structure distinct from the in-flash version. We'll do that 670a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson * Real Soon Now. Until then, we just repeat the same linear search every time. 680a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson */ 690a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardsontypedef FontArrayHeader VbFont_t; 700a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 71fe510c06204c763e61aa36d2263c3b8b79c79879Randall SpanglerVbFont_t *VbInternalizeFontData(FontArrayHeader *fonthdr) 720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Just return the raw data pointer for now. */ 740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return (VbFont_t *)fonthdr; 750a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson} 760a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 77fe510c06204c763e61aa36d2263c3b8b79c79879Randall Spanglervoid VbDoneWithFontForNow(VbFont_t *ptr) 780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Nothing. */ 800a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson} 810a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 82fe510c06204c763e61aa36d2263c3b8b79c79879Randall SpanglerImageInfo *VbFindFontGlyph(VbFont_t *font, uint32_t ascii, 83fe510c06204c763e61aa36d2263c3b8b79c79879Randall Spangler void **bufferptr, uint32_t *buffersize) 840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint8_t *ptr, *firstptr; 860bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t max; 870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t i; 880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler FontArrayEntryHeader *entry; 890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ptr = (uint8_t *)font; 910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler max = ((FontArrayHeader *)ptr)->num_entries; 920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ptr += sizeof(FontArrayHeader); 930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler firstptr = ptr; 940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * Simple linear search. 970bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * 980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * Note: We're assuming glpyhs are uncompressed. That's true because 990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * the bmpblk_font tool doesn't compress anything. The bmpblk_utility 1000bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * does, but it compresses the entire font blob at once, and we've 1010bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * already uncompressed that before we got here. 1020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 1030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for(i=0; i<max; i++) { 1040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler entry = (FontArrayEntryHeader *)ptr; 1050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (entry->ascii == ascii) { 1060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *bufferptr = ptr + sizeof(FontArrayEntryHeader); 1070bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *buffersize = entry->info.original_size; 1080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return &(entry->info); 1090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ptr += sizeof(FontArrayEntryHeader)+entry->info.compressed_size; 1110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 1140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * We must return something valid. We'll just use the first glyph in 1150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * the font structure (so it should be something distinct). 1160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 1170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler entry = (FontArrayEntryHeader *)firstptr; 1180bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *bufferptr = firstptr + sizeof(FontArrayEntryHeader); 1190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *buffersize = entry->info.original_size; 1200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return &(entry->info); 1210a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson} 1220a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 123fe510c06204c763e61aa36d2263c3b8b79c79879Randall Spanglervoid VbRenderTextAtPos(char *text, int right_to_left, 124fe510c06204c763e61aa36d2263c3b8b79c79879Randall Spangler uint32_t x, uint32_t y, VbFont_t *font) 1250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 1260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler int i; 1270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ImageInfo *image_info = 0; 1280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler void *buffer; 1290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t buffersize; 1300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t cur_x = x, cur_y = y; 1310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!text || !font) { 1330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG((" VbRenderTextAtPos: invalid args\n")); 1340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return; 1350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for (i=0; text[i]; i++) { 1380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (text[i] == '\n') { 1400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!image_info) 1410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info = VbFindFontGlyph(font, text[i], 1420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler &buffer, 1430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler &buffersize); 1440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler cur_x = x; 1450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler cur_y += image_info->height; 1460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler continue; 1470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info = VbFindFontGlyph(font, text[i], &buffer, 1500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler &buffersize); 1510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (right_to_left) 1530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler cur_x -= image_info->width; 1540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS != VbExDisplayImage(cur_x, cur_y, buffer, 1560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler buffersize)) { 1570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG((" VbRenderTextAtPos: " 1580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "can't display ascii 0x%x\n", text[i])); 1590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!right_to_left) 1620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler cur_x += image_info->width; 1630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1640a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson} 1650a9977e161ce6ad6b11935dfb05ae840bf758078Bill Richardson 166f2ad05f59ef644af8d6d28d002f89f6c88cde27fBill Richardson#define OUTBUF_LEN 128 167822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 1680bf6405a4b4ac1ce569363a45812767777e0f4ebRandall SpanglerVbError_t VbDisplayScreenFromGBB(VbCommonParams *cparams, uint32_t screen, 1690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvContext *vncptr) 1700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 1710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler GoogleBinaryBlockHeader *gbb = 1720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (GoogleBinaryBlockHeader *)cparams->gbb_data; 1730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler static uint8_t *bmpfv; 1740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler void *fullimage = NULL; 1750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler BmpBlockHeader *hdr; 1760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ScreenLayout *layout; 1770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ImageInfo *image_info; 1780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t screen_index; 1790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t localization = 0; 1800bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */ 1810bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t inoutsize; 1820bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t offset; 1830bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t i; 1840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbFont_t *font; 1850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler char *text_to_show; 1860bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler int rtol = 0; 1870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler char outbuf[OUTBUF_LEN] = ""; 1880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t used = 0; 1890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Make sure bitmap data is inside the GBB and is non-zero in size */ 1910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == gbb->bmpfv_size || 1920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->bmpfv_offset > cparams->gbb_size || 1930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->bmpfv_offset + gbb->bmpfv_size > cparams->gbb_size) { 1940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayScreenFromGBB(): " 1950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "invalid bmpfv offset/size\n")); 1960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_INVALID_GBB; 1970bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 1980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Copy bitmap data from GBB into RAM for speed */ 2000bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!bmpfv) { 201c92c81ecf517536d29da3cc75e4ea4d922cb28e2Simon Glass#ifdef COPY_BMP_DATA 2020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler bmpfv = (uint8_t *)VbExMalloc(gbb->bmpfv_size); 2030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler Memcpy(bmpfv, ((uint8_t *)gbb) + gbb->bmpfv_offset, 2040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->bmpfv_size); 205c92c81ecf517536d29da3cc75e4ea4d922cb28e2Simon Glass#else 2060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler bmpfv = ((uint8_t *)gbb) + gbb->bmpfv_offset; 207c92c81ecf517536d29da3cc75e4ea4d922cb28e2Simon Glass#endif 2080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 2090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Sanity-check the bitmap block header */ 2110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler hdr = (BmpBlockHeader *)bmpfv; 2120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if ((0 != Memcmp(hdr->signature, BMPBLOCK_SIGNATURE, 2130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler BMPBLOCK_SIGNATURE_SIZE)) || 2140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (hdr->major_version > BMPBLOCK_MAJOR_VERSION) || 2150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler ((hdr->major_version == BMPBLOCK_MAJOR_VERSION) && 2160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (hdr->minor_version > BMPBLOCK_MINOR_VERSION))) { 2170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayScreenFromGBB(): " 2180bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "invalid/too new bitmap header\n")); 2190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VBERROR_INVALID_BMPFV; 2200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler goto VbDisplayScreenFromGBB_exit; 2210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 2220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 2240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * Translate screen ID into index. Note that not all screens are in 2250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * the GBB. 2260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * 2270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * TODO: ensure screen IDs match indices? Having this translation here 2280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * is awful. 2290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 2300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler switch (screen) { 2310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_DEVELOPER_WARNING: 2320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_DEVELOPER_WARNING; 2330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_RECOVERY_REMOVE: 2350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_RECOVERY_REMOVE; 2360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_RECOVERY_NO_GOOD: 2380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_RECOVERY_NO_GOOD; 2390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_RECOVERY_INSERT: 2410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_RECOVERY_INSERT; 2420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_RECOVERY_TO_DEV: 2440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_RECOVERY_TO_DEV; 2450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_DEVELOPER_TO_NORM: 2470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_DEVELOPER_TO_NORM; 2480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_WAIT: 2500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_WAIT; 2510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_TO_NORM_CONFIRMED: 2530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index = SCREEN_TO_NORM_CONFIRMED; 2540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 2550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_BLANK: 2560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VB_SCREEN_DEVELOPER_EGG: 2570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler default: 2580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Screens which aren't in the GBB */ 2590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n", 2600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (int)screen)); 2610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VBERROR_INVALID_SCREEN_INDEX; 2620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler goto VbDisplayScreenFromGBB_exit; 2630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 2640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2650bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (screen_index >= hdr->number_of_screenlayouts) { 2660bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayScreenFromGBB(): " 2670bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "screen %d index %d not in the GBB\n", 2680bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (int)screen, (int)screen_index)); 2690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VBERROR_INVALID_SCREEN_INDEX; 2700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler goto VbDisplayScreenFromGBB_exit; 2710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 2720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Clip localization to number of localizations present in the GBB */ 2740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &localization); 2750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (localization >= hdr->number_of_localizations) { 2760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler localization = 0; 2770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, localization); 2780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 2790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2800bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 2810bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * Calculate offset of screen layout = start of screen stuff + correct 2820bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * locale + correct screen. 2830bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 2840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler offset = sizeof(BmpBlockHeader) + 2850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler localization * hdr->number_of_screenlayouts * 2860bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler sizeof(ScreenLayout) + 2870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler screen_index * sizeof(ScreenLayout); 2880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler layout = (ScreenLayout *)(bmpfv + offset); 2890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Display all bitmaps for the image */ 2910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for (i = 0; i < MAX_IMAGE_IN_LAYOUT; i++) { 2920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!layout->images[i].image_info_offset) 2930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler continue; 2940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 2950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler offset = layout->images[i].image_info_offset; 2960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info = (ImageInfo *)(bmpfv + offset); 2970bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler fullimage = bmpfv + offset + sizeof(ImageInfo); 2980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler inoutsize = image_info->original_size; 2990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (inoutsize && 3000bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info->compression != COMPRESS_NONE) { 3010bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler fullimage = VbExMalloc(inoutsize); 3020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VbExDecompress( 3030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler bmpfv + offset + sizeof(ImageInfo), 3040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info->compressed_size, 3050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info->compression, 3060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler fullimage, &inoutsize); 3070bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS != retval) { 3080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbExFree(fullimage); 3090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler goto VbDisplayScreenFromGBB_exit; 3100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler switch(image_info->format) { 3140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case FORMAT_BMP: 3150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VbExDisplayImage(layout->images[i].x, 3160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler layout->images[i].y, 3170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler fullimage, inoutsize); 3180bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 3190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case FORMAT_FONT: 3210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 3220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * The uncompressed blob is our font structure. Cache 3230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * it as needed. 3240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 3250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler font = VbInternalizeFontData(fullimage); 3260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* TODO: handle text in general here */ 3280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (TAG_HWID == image_info->tag || 3290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler TAG_HWID_RTOL == image_info->tag) { 3300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler text_to_show = VbHWID(cparams); 3310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler rtol = (TAG_HWID_RTOL == image_info->tag); 3320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } else { 3330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler text_to_show = ""; 3340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler rtol = 0; 3350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbRenderTextAtPos(text_to_show, rtol, 3380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler layout->images[i].x, 3390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler layout->images[i].y, font); 3400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbDoneWithFontForNow(font); 3420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler break; 3430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler default: 3450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayScreenFromGBB(): " 3460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "unsupported ImageFormat %d\n", 3470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler image_info->format)); 3480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VBERROR_INVALID_GBB; 3490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (COMPRESS_NONE != image_info->compression) 3520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbExFree(fullimage); 3530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS != retval) 3550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler goto VbDisplayScreenFromGBB_exit; 3560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Successful if all bitmaps displayed */ 3590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VBERROR_SUCCESS; 3600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* 3620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * If GBB flags is nonzero, complain because that's something that the 3630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * factory MUST fix before shipping. We only have to do this here, 3640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * because it's obvious that something is wrong if we're not displaying 3650bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * screens from the GBB. 3660bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler */ 3670bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1 && 3680bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (gbb->flags != 0)) { 3690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(outbuf + used, "gbb.flags is nonzero: 0x", 3700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler OUTBUF_LEN - used); 3710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(outbuf + used, OUTBUF_LEN - used, 3720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->flags, 16, 8); 3730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(outbuf + used, "\n", OUTBUF_LEN - used); 3740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (void)VbExDisplayDebugInfo(outbuf); 3750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 3760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 3770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbDisplayScreenFromGBB_exit: 3780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("leaving VbDisplayScreenFromGBB() with %d\n",retval)); 3790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return retval; 380822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson} 381822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 3820bf6405a4b4ac1ce569363a45812767777e0f4ebRandall SpanglerVbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen, int force, 3830bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvContext *vncptr) 3840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 3850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbError_t retval; 386822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 3870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Initialize display if necessary */ 3880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (!disp_width) { 3890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler retval = VbExDisplayInit(&disp_width, &disp_height); 3900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS != retval) 3910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return retval; 3920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 393822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 3940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* If requested screen is the same as the current one, we're done. */ 3950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (disp_current_screen == screen && 0 == force) 3960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_SUCCESS; 397822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 3980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* If the screen is blank, turn off the backlight; else turn it on. */ 3990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbExDisplayBacklight(VB_SCREEN_BLANK == screen ? 0 : 1); 400822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 4010bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Request the screen */ 4020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler disp_current_screen = screen; 403822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 4040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Look in the GBB first */ 4050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS == VbDisplayScreenFromGBB(cparams, screen, vncptr)) 4060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VBERROR_SUCCESS; 407822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 4080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* If screen wasn't in the GBB bitmaps, fall back to a default */ 4090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VbExDisplayScreen(screen); 410822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson} 411822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 4120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spanglerstatic void Uint8ToString(char *buf, uint8_t val) 4130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 4140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler const char *trans = "0123456789abcdef"; 4150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *buf++ = trans[val >> 4]; 4160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *buf = trans[val & 0xF]; 4175de6b40ca74f4a6724941068a15bb0cf261a2d01Bill Richardson} 4185de6b40ca74f4a6724941068a15bb0cf261a2d01Bill Richardson 4190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spanglerstatic void FillInSha1Sum(char *outbuf, VbPublicKey *key) 4200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 4210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint8_t *buf = ((uint8_t *)key) + key->key_offset; 4220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint64_t buflen = key->key_size; 4230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM); 4240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler int i; 4250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for (i = 0; i < SHA1_DIGEST_SIZE; i++) { 4260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler Uint8ToString(outbuf, digest[i]); 4270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler outbuf += 2; 4280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 4290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler *outbuf = '\0'; 4300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbExFree(digest); 4315de6b40ca74f4a6724941068a15bb0cf261a2d01Bill Richardson} 4325de6b40ca74f4a6724941068a15bb0cf261a2d01Bill Richardson 4330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spanglerconst char *RecoveryReasonString(uint8_t code) 4340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 4350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler switch(code) { 4360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_NOT_REQUESTED: 4370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Recovery not requested"; 4380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_LEGACY: 4390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Recovery requested from legacy utility"; 4400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_MANUAL: 4410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "recovery button pressed"; 4420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW: 4430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware failed signature check"; 4440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_S3_RESUME: 4450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "S3 resume failed"; 4460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_DEP_RO_TPM_ERROR: 4470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM error in read-only firmware"; 4480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_SHARED_DATA: 4490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Shared data error in read-only firmware"; 4500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TEST_S3: 4510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Test error from S3Resume()"; 4520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TEST_LFS: 4530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Test error from LoadFirmwareSetup()"; 4540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TEST_LF: 4550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Test error from LoadFirmware()"; 4560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NOT_DONE: 4570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware check not done"; 4580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_DEV_MISMATCH: 4590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware developer flag mismatch"; 4600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_REC_MISMATCH: 4610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware recovery flag mismatch"; 4620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 4630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBSD_LF_CHECK_VERIFY_KEYBLOCK: 4640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware unable to verify key block"; 4650bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_KEY_ROLLBACK: 4660bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware key version rollback detected"; 4670bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 4680bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBSD_LF_CHECK_DATA_KEY_PARSE: 4690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware unable to parse data key"; 4700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 4710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBSD_LF_CHECK_VERIFY_PREAMBLE: 4720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware unable to verify preamble"; 4730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_FW_ROLLBACK: 4740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware version rollback detected"; 4750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_GET_FW_BODY: 4760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware unable to get firmware body"; 4770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 4780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBSD_LF_CHECK_HASH_WRONG_SIZE: 4790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware hash is wrong size"; 4800bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_VERIFY_BODY: 4810bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware unable to verify firmware body"; 4820bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NO_RO_NORMAL: 4830bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware read-only normal path is not supported"; 4840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_FIRMWARE: 4850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Firmware problem outside of verified boot"; 4860bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TPM_REBOOT: 4870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM requires a system reboot (should be transient)"; 4880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_SOFTWARE_SYNC: 4890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync error"; 4900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_UNKNOWN_IMAGE: 4910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync unable to determine active EC image"; 4920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_DEP_EC_HASH: 4930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync error obtaining EC image hash"; 4940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_EXPECTED_IMAGE: 4950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync error " 4960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "obtaining expected EC image from BIOS"; 4975ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler case VBNV_RECOVERY_EC_EXPECTED_HASH: 4985ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler return "EC software sync error " 4995ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler "obtaining expected EC hash from BIOS"; 5005ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler case VBNV_RECOVERY_EC_HASH_MISMATCH: 5015ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler return "EC software sync error " 5025ca4ea087a3d67c2a639e8b9254f51f076bf85faRandall Spangler "comparing expected EC hash and image"; 5030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_UPDATE: 5040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync error updating EC"; 5050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_JUMP_RW: 5060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync unable to jump to EC-RW"; 5070bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_PROTECT: 5080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync protection error"; 5090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_UNSPECIFIED: 5100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Unspecified/unknown error in RO firmware"; 5110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_DEV_SCREEN: 5120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "User requested recovery from dev-mode warning screen"; 5130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_NO_OS: 5140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "No OS kernel detected (or kernel rollback attempt?)"; 5150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_INVALID_OS: 5160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "OS kernel failed signature check"; 5170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_DEP_RW_TPM_ERROR: 5180bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM error in rewritable firmware"; 5190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_DEV_MISMATCH: 5200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "RW firmware in dev mode, but dev switch is off"; 5210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_SHARED_DATA: 5220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Shared data error in rewritable firmware"; 5230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_TEST_LK: 5240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Test error from LoadKernel()"; 5250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_DEP_RW_NO_DISK: 5260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "No bootable disk found"; 5270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_TPM_E_FAIL: 5280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM error that was not fixed by reboot"; 5290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TPM_S_ERROR: 5300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM setup error in read-only firmware"; 5310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TPM_W_ERROR: 5320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM write error in read-only firmware"; 5330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TPM_L_ERROR: 5340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM lock error in read-only firmware"; 5350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RO_TPM_U_ERROR: 5360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM update error in read-only firmware"; 5370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_TPM_R_ERROR: 5380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM read error in rewritable firmware"; 5390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_TPM_W_ERROR: 5400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM write error in rewritable firmware"; 5410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_TPM_L_ERROR: 5420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "TPM lock error in rewritable firmware"; 5430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_HASH_FAILED: 5440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync unable to get EC image hash"; 5450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_EC_HASH_SIZE: 5460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "EC software sync invalid image hash size"; 5470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_LK_UNSPECIFIED: 5480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Unspecified error while trying to load kernel"; 5490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_NO_DISK: 5500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "No bootable storage device in system"; 5510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_NO_KERNEL: 5520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "No bootable kernel found on disk"; 5530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_RW_UNSPECIFIED: 5540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Unspecified/unknown error in RW firmware"; 5550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_KE_DM_VERITY: 5560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "DM-verity error"; 5570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_KE_UNSPECIFIED: 5580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Unspecified/unknown error in kernel"; 5590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_US_TEST: 5600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Recovery mode test from user-mode"; 5610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler case VBNV_RECOVERY_US_UNSPECIFIED: 5620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "Unspecified/unknown error in user-mode"; 5630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 5640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return "We have no idea what this means"; 565f2ad05f59ef644af8d6d28d002f89f6c88cde27fBill Richardson} 566f2ad05f59ef644af8d6d28d002f89f6c88cde27fBill Richardson 567822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson#define DEBUG_INFO_SIZE 512 568822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 5690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall SpanglerVbError_t VbDisplayDebugInfo(VbCommonParams *cparams, VbNvContext *vncptr) 5700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 5710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbSharedDataHeader *shared = 5720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (VbSharedDataHeader *)cparams->shared_data_blob; 5730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler GoogleBinaryBlockHeader *gbb = 5740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (GoogleBinaryBlockHeader *)cparams->gbb_data; 5750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler char buf[DEBUG_INFO_SIZE] = ""; 5760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler char sha1sum[SHA1_DIGEST_SIZE * 2 + 1]; 5770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t used = 0; 5780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t i; 5790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 5800bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Redisplay current screen to overwrite any previous debug output */ 5810bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbDisplayScreen(cparams, disp_current_screen, 1, vncptr); 5820bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 5830bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add hardware ID */ 5840bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "HWID: ", DEBUG_INFO_SIZE - used); 5850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == gbb->hwid_size || 5860bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->hwid_offset > cparams->gbb_size || 5870bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) { 5880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbDisplayDebugInfo(): invalid hwid offset/size\n")); 5890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 5900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "(INVALID)", DEBUG_INFO_SIZE - used); 591822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson } else { 5920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 5930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (char *)((uint8_t *)gbb + gbb->hwid_offset), 5940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler DEBUG_INFO_SIZE - used); 595822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson } 596822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 5970bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add recovery reason */ 5980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 5990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "\nrecovery_reason: 0x", DEBUG_INFO_SIZE - used); 6000bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6010bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler shared->recovery_reason, 16, 2); 6020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, " ", DEBUG_INFO_SIZE - used); 6030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 6040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler RecoveryReasonString(shared->recovery_reason), 6050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler DEBUG_INFO_SIZE - used); 6060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6070bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add VbSharedData flags */ 6080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\nVbSD.flags: 0x", DEBUG_INFO_SIZE - used); 6090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler shared->flags, 16, 8); 6110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add raw contents of VbNvStorage */ 6130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used); 6140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for (i = 0; i < VBNV_BLOCK_SIZE; i++) { 6150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, " ", DEBUG_INFO_SIZE - used); 6160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler vncptr->raw[i], 16, 2); 6180bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 6190bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add dev_boot_usb flag */ 6210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvGet(vncptr, VBNV_DEV_BOOT_USB, &i); 6220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\ndev_boot_usb: ", DEBUG_INFO_SIZE - used); 6230bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0); 6240bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add dev_boot_legacy flag */ 6260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvGet(vncptr, VBNV_DEV_BOOT_LEGACY, &i); 6270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 6280bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "\ndev_boot_legacy: ", DEBUG_INFO_SIZE - used); 6290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0); 6300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add dev_boot_signed_only flag */ 6320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvGet(vncptr, VBNV_DEV_BOOT_SIGNED_ONLY, &i); 6330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\ndev_boot_signed_only: ", 6340bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler DEBUG_INFO_SIZE - used); 6350bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0); 6360bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6370bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add TPM versions */ 6380bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\nTPM: fwver=0x", DEBUG_INFO_SIZE - used); 6390bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6400bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler shared->fw_version_tpm, 16, 8); 6410bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, " kernver=0x", DEBUG_INFO_SIZE - used); 6420bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6430bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler shared->kernel_version_tpm, 16, 8); 6440bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6450bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add GBB flags */ 6460bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\ngbb.flags: 0x", DEBUG_INFO_SIZE - used); 6470bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1) { 6480bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, 6490bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler gbb->flags, 16, 8); 6500bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } else { 6510bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 6520bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "0 (default)", DEBUG_INFO_SIZE - used); 6530bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 6540bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6550bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Add sha1sum for Root & Recovery keys */ 6560bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler FillInSha1Sum(sha1sum, 6570bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (VbPublicKey *)((uint8_t *)gbb + gbb->rootkey_offset)); 6580bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\ngbb.rootkey: ", DEBUG_INFO_SIZE - used); 6590bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used); 6600bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler FillInSha1Sum(sha1sum, 6610bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (VbPublicKey *)((uint8_t *)gbb + gbb->recovery_key_offset)); 6620bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 6630bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "\ngbb.recovery_key: ", DEBUG_INFO_SIZE - used); 6640bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used); 6650bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6660bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* If we're in dev-mode, show the kernel subkey that we expect, too. */ 6670bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == shared->recovery_reason) { 6680bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler FillInSha1Sum(sha1sum, &shared->kernel_subkey); 6690bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, 6700bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler "\nkernel_subkey: ", DEBUG_INFO_SIZE - used); 6710bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used); 6720bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 6730bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6740bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Make sure we finish with a newline */ 6750bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler used += Strncat(buf + used, "\n", DEBUG_INFO_SIZE - used); 6760bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6770bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* TODO: add more interesting data: 6780bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler * - Information on current disks */ 6790bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6800bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler buf[DEBUG_INFO_SIZE - 1] = '\0'; 6810bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VbExDisplayDebugInfo(buf); 682822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson} 683822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 684518d4f39b4ab5fa7d516de397795bc146250c51bBill Richardson#define MAGIC_WORD_LEN 5 6850bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler#define MAGIC_WORD "xyzzy" 686518d4f39b4ab5fa7d516de397795bc146250c51bBill Richardsonstatic uint8_t MagicBuffer[MAGIC_WORD_LEN]; 687518d4f39b4ab5fa7d516de397795bc146250c51bBill Richardson 6880bf6405a4b4ac1ce569363a45812767777e0f4ebRandall SpanglerVbError_t VbCheckDisplayKey(VbCommonParams *cparams, uint32_t key, 6890bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvContext *vncptr) 6900bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler{ 6910bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler int i; 6920bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6930bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Update key buffer */ 6940bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler for(i = 1; i < MAGIC_WORD_LEN; i++) 6950bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler MagicBuffer[i - 1] = MagicBuffer[i]; 6960bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Save as lower-case ASCII */ 6970bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler MagicBuffer[MAGIC_WORD_LEN - 1] = (key | 0x20) & 0xFF; 6980bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 6990bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if ('\t' == key) { 7000bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Tab = display debug info */ 7010bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VbDisplayDebugInfo(cparams, vncptr); 7020bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key || 7030bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VB_KEY_DOWN == key || VB_KEY_UP == key) { 7040bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Arrow keys = change localization */ 7050bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t loc = 0; 7060bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler uint32_t count = 0; 7070bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 7080bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &loc); 7090bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBERROR_SUCCESS != VbGetLocalizationCount(cparams, &count)) 7100bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler loc = 0; /* No localization count (bad GBB?) */ 7110bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler else if (VB_KEY_RIGHT == key || VB_KEY_UP == key) 7120bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler loc = (loc < count - 1 ? loc + 1 : 0); 7130bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler else 7140bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler loc = (loc > 0 ? loc - 1 : count - 1); 7150bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VBDEBUG(("VbCheckDisplayKey() - change localization to %d\n", 7160bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (int)loc)); 7170bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, loc); 718985e90e26320c73949d5dfbf218773f2cb744598Simon Glass 719be94d55d4f07c5052b04ac3982314e6e588fc361Randall Spangler#ifdef SAVE_LOCALE_IMMEDIATELY 7200bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbNvTeardown(vncptr); /* really only computes checksum */ 7210bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (vncptr->raw_changed) 7220bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler VbExNvStorageWrite(vncptr->raw); 723985e90e26320c73949d5dfbf218773f2cb744598Simon Glass#endif 724822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 7250bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler /* Force redraw of current screen */ 7260bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler return VbDisplayScreen(cparams, disp_current_screen, 1, vncptr); 7270bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 728822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson 7290bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (0 == Memcmp(MagicBuffer, MAGIC_WORD, MAGIC_WORD_LEN)) { 7300bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler if (VBEASTEREGG) 7310bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler (void)VbDisplayScreen(cparams, disp_current_screen, 7320bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler 1, vncptr); 7330bf6405a4b4ac1ce569363a45812767777e0f4ebRandall Spangler } 734518d4f39b4ab5fa7d516de397795bc146250c51bBill Richardson 735822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson return VBERROR_SUCCESS; 736822eca680fa9568396f9de79ab91a9e67f3a9aaeBill Richardson} 737