mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
Originally, vboot1 code used VbExMalloc() and VbExFree() since it needed to talk to EFI firmware that didn't have standard malloc() and free(). Now, coreboot and depthcharge implement them as wrappers around those standard calls. vboot2 code already calls them directly, so let vboot1 code do that too. BUG=chromium:611535 BRANCH=none TEST=make runtests; emerge-kevin coreboot depthcharge Change-Id: I49ad0e32e38d278dc3589bfaf494bcf0e4b0a4bd Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/400905
269 lines
7.2 KiB
C
269 lines
7.2 KiB
C
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* Tests for firmware display library.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "bmpblk_font.h"
|
|
#include "gbb_header.h"
|
|
#include "host_common.h"
|
|
#include "region.h"
|
|
#include "test_common.h"
|
|
#include "vboot_common.h"
|
|
#include "vboot_display.h"
|
|
#include "vboot_kernel.h"
|
|
#include "vboot_nvstorage.h"
|
|
|
|
/* Mock data */
|
|
static VbCommonParams cparams;
|
|
static VbNvContext vnc;
|
|
static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
|
|
static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
|
|
static char gbb_data[4096 + sizeof(GoogleBinaryBlockHeader)];
|
|
static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)gbb_data;
|
|
static BmpBlockHeader *bhdr;
|
|
static char debug_info[4096];
|
|
|
|
/* Reset mock data (for use before each test) */
|
|
static void ResetMocks(void)
|
|
{
|
|
int gbb_used;
|
|
|
|
memset(gbb_data, 0, sizeof(gbb_data));
|
|
gbb->major_version = GBB_MAJOR_VER;
|
|
gbb->minor_version = GBB_MINOR_VER;
|
|
gbb->flags = 0;
|
|
gbb_used = sizeof(GoogleBinaryBlockHeader);
|
|
|
|
gbb->hwid_offset = gbb_used;
|
|
strcpy(gbb_data + gbb->hwid_offset, "Test HWID");
|
|
gbb->hwid_size = strlen(gbb_data + gbb->hwid_offset) + 1;
|
|
gbb_used = (gbb_used + gbb->hwid_size + 7) & ~7;
|
|
|
|
gbb->bmpfv_offset = gbb_used;
|
|
bhdr = (BmpBlockHeader *)(gbb_data + gbb->bmpfv_offset);
|
|
gbb->bmpfv_size = sizeof(BmpBlockHeader);
|
|
gbb_used = (gbb_used + gbb->bmpfv_size + 7) & ~7;
|
|
memcpy(bhdr->signature, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE);
|
|
bhdr->major_version = BMPBLOCK_MAJOR_VERSION;
|
|
bhdr->minor_version = BMPBLOCK_MINOR_VERSION;
|
|
bhdr->number_of_localizations = 3;
|
|
|
|
memset(&cparams, 0, sizeof(cparams));
|
|
cparams.shared_data_size = sizeof(shared_data);
|
|
cparams.shared_data_blob = shared_data;
|
|
cparams.gbb_data = gbb;
|
|
cparams.gbb_size = sizeof(gbb_data);
|
|
|
|
/*
|
|
* Note, VbApiKernelFree() expects this to be allocated by
|
|
* malloc(), so we cannot just assign it staticly.
|
|
*/
|
|
cparams.gbb = malloc(sizeof(*gbb));
|
|
gbb->header_size = sizeof(*gbb);
|
|
gbb->rootkey_offset = gbb_used;
|
|
gbb->rootkey_size = 64;
|
|
gbb_used += 64;
|
|
gbb->recovery_key_offset = gbb_used;
|
|
gbb->recovery_key_size = 64;
|
|
gbb_used += 64;
|
|
memcpy(cparams.gbb, gbb, sizeof(*gbb));
|
|
|
|
memset(&vnc, 0, sizeof(vnc));
|
|
VbNvSetup(&vnc);
|
|
VbNvTeardown(&vnc); /* So CRC gets generated */
|
|
|
|
memset(&shared_data, 0, sizeof(shared_data));
|
|
VbSharedDataInit(shared, sizeof(shared_data));
|
|
|
|
*debug_info = 0;
|
|
}
|
|
|
|
/* Mocks */
|
|
|
|
VbError_t VbExDisplayDebugInfo(const char *info_str)
|
|
{
|
|
strncpy(debug_info, info_str, sizeof(debug_info));
|
|
debug_info[sizeof(debug_info) - 1] = '\0';
|
|
return VBERROR_SUCCESS;
|
|
}
|
|
|
|
/* Test displaying debug info */
|
|
static void DebugInfoTest(void)
|
|
{
|
|
char hwid[VB_REGION_HWID_LEN];
|
|
int i;
|
|
|
|
/* Recovery string should be non-null for any code */
|
|
for (i = 0; i < 0x100; i++)
|
|
TEST_PTR_NEQ(RecoveryReasonString(i), NULL, "Non-null reason");
|
|
|
|
/* HWID should come from the gbb */
|
|
ResetMocks();
|
|
VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
|
|
TEST_EQ(strcmp(hwid, "Test HWID"), 0, "HWID");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
cparams.gbb_size = 0;
|
|
VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
|
|
TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID bad gbb");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
cparams.gbb->hwid_size = 0;
|
|
VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
|
|
TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID missing");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
cparams.gbb->hwid_offset = cparams.gbb_size + 1;
|
|
VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
|
|
TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID past end");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
cparams.gbb->hwid_size = cparams.gbb_size;
|
|
VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
|
|
TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID overflow");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
/* Display debug info */
|
|
ResetMocks();
|
|
VbDisplayDebugInfo(&cparams, &vnc);
|
|
TEST_NEQ(*debug_info, '\0', "Some debug info was displayed");
|
|
VbApiKernelFree(&cparams);
|
|
}
|
|
|
|
/* Test localization */
|
|
static void LocalizationTest(void)
|
|
{
|
|
uint32_t count = 6;
|
|
|
|
ResetMocks();
|
|
cparams.gbb->bmpfv_size = 0;
|
|
TEST_EQ(VbGetLocalizationCount(&cparams, &count),
|
|
VBERROR_UNKNOWN, "VbGetLocalizationCount bad gbb");
|
|
TEST_EQ(count, 0, " count");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
bhdr->signature[0] ^= 0x5a;
|
|
TEST_EQ(VbGetLocalizationCount(&cparams, &count),
|
|
VBERROR_UNKNOWN, "VbGetLocalizationCount bad bmpfv");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
TEST_EQ(VbGetLocalizationCount(&cparams, &count), 0,
|
|
"VbGetLocalizationCount()");
|
|
TEST_EQ(count, 3, " count");
|
|
VbApiKernelFree(&cparams);
|
|
}
|
|
|
|
/* Test display key checking */
|
|
static void DisplayKeyTest(void)
|
|
{
|
|
uint32_t u;
|
|
|
|
ResetMocks();
|
|
VbCheckDisplayKey(&cparams, 'q', &vnc);
|
|
TEST_EQ(*debug_info, '\0', "DisplayKey q = does nothing");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
ResetMocks();
|
|
VbCheckDisplayKey(&cparams, '\t', &vnc);
|
|
TEST_NEQ(*debug_info, '\0', "DisplayKey tab = display");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
/* Toggle localization */
|
|
ResetMocks();
|
|
VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0);
|
|
VbNvTeardown(&vnc);
|
|
VbCheckDisplayKey(&cparams, VB_KEY_DOWN, &vnc);
|
|
VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
|
|
TEST_EQ(u, 2, "DisplayKey up");
|
|
VbCheckDisplayKey(&cparams, VB_KEY_LEFT, &vnc);
|
|
VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
|
|
TEST_EQ(u, 1, "DisplayKey left");
|
|
VbCheckDisplayKey(&cparams, VB_KEY_RIGHT, &vnc);
|
|
VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
|
|
TEST_EQ(u, 2, "DisplayKey right");
|
|
VbCheckDisplayKey(&cparams, VB_KEY_UP, &vnc);
|
|
VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
|
|
TEST_EQ(u, 0, "DisplayKey up");
|
|
VbApiKernelFree(&cparams);
|
|
|
|
/* Reset localization if localization count is invalid */
|
|
ResetMocks();
|
|
VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 1);
|
|
VbNvTeardown(&vnc);
|
|
bhdr->signature[0] ^= 0x5a;
|
|
VbCheckDisplayKey(&cparams, VB_KEY_UP, &vnc);
|
|
VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
|
|
TEST_EQ(u, 0, "DisplayKey invalid");
|
|
VbApiKernelFree(&cparams);
|
|
}
|
|
|
|
static void FontTest(void)
|
|
{
|
|
FontArrayHeader h;
|
|
FontArrayEntryHeader eh[3] = {
|
|
{
|
|
.ascii = 'A',
|
|
.info.original_size = 10,
|
|
},
|
|
{
|
|
.ascii = 'B',
|
|
.info.original_size = 20,
|
|
},
|
|
{
|
|
.ascii = 'C',
|
|
.info.original_size = 30,
|
|
},
|
|
};
|
|
FontArrayEntryHeader *eptr;
|
|
uint8_t buf[sizeof(h) + sizeof(eh)];
|
|
VbFont_t *fptr;
|
|
void *bufferptr;
|
|
uint32_t buffersize;
|
|
|
|
/* Create font data */
|
|
h.num_entries = ARRAY_SIZE(eh);
|
|
memcpy(buf, &h, sizeof(h));
|
|
eptr = (FontArrayEntryHeader *)(buf + sizeof(h));
|
|
memcpy(eptr, eh, sizeof(eh));
|
|
|
|
fptr = VbInternalizeFontData((FontArrayHeader *)buf);
|
|
TEST_PTR_EQ(fptr, buf, "Internalize");
|
|
|
|
TEST_PTR_EQ(VbFindFontGlyph(fptr, 'B', &bufferptr, &buffersize),
|
|
&eptr[1].info, "Glyph found");
|
|
TEST_EQ(buffersize, eptr[1].info.original_size, " size");
|
|
TEST_PTR_EQ(VbFindFontGlyph(fptr, 'X', &bufferptr, &buffersize),
|
|
&eptr[0].info, "Glyph not found");
|
|
TEST_EQ(buffersize, eptr[0].info.original_size, " size");
|
|
|
|
/* Test invalid rendering params */
|
|
VbRenderTextAtPos(NULL, 0, 0, 0, fptr);
|
|
VbRenderTextAtPos("ABC", 0, 0, 0, NULL);
|
|
|
|
VbDoneWithFontForNow(fptr);
|
|
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
DebugInfoTest();
|
|
LocalizationTest();
|
|
DisplayKeyTest();
|
|
FontTest();
|
|
|
|
return gTestSuccess ? 0 : 255;
|
|
}
|