tests: Add lib/cbmem_stage_cache-test test case

Signed-off-by: Jakub Czapiga <jacz@semihalf.com>
Change-Id: Ie6851b9473b225beb5ba51e26f44e21ea5919a64
Reviewed-on: https://review.coreboot.org/c/coreboot/+/54916
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
This commit is contained in:
Jakub Czapiga 2021-05-25 15:46:37 +02:00 committed by Patrick Georgi
parent 35efba2bc0
commit db4b21a1d0
2 changed files with 204 additions and 0 deletions

View File

@ -30,6 +30,7 @@ tests-y += coreboot_table-test
tests-y += rtc-test
tests-y += spd_cache-ddr3-test
tests-y += spd_cache-ddr4-test
tests-y += cbmem_stage_cache-test
string-test-srcs += tests/lib/string-test.c
string-test-srcs += src/lib/string.c
@ -167,3 +168,12 @@ spd_cache-ddr4-test-config += CONFIG_SPD_CACHE_FMAP_NAME=\"RW_SPD_CACHE\" \
CONFIG_DIMM_MAX=4 CONFIG_DIMM_SPD_SIZE=512 \
CONFIG_BOOT_DEVICE_MEMORY_MAPPED=1
spd_cache-ddr4-test-cflags += -D__TEST_SPD_CACHE_DDR=4
cbmem_stage_cache-test-srcs += tests/lib/cbmem_stage_cache-test.c
cbmem_stage_cache-test-srcs += tests/stubs/console.c
cbmem_stage_cache-test-srcs += src/lib/cbmem_stage_cache.c
cbmem_stage_cache-test-srcs += src/lib/imd_cbmem.c
cbmem_stage_cache-test-srcs += src/lib/imd.c
cbmem_stage_cache-test-cflags += -I 3rdparty/vboot/firmware/include
cbmem_stage_cache-test-cflags += -I $(src)/commonlib/include
cbmem_stage_cache-test-config += CONFIG_CBMEM_STAGE_CACHE=1

View File

@ -0,0 +1,194 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <tests/test.h>
#include <cbmem.h>
#include <commonlib/cbmem_id.h>
#include <stage_cache.h>
#define CBMEM_SIZE (32 * KiB)
/* CBMEM top pointer used by implementation. */
extern uintptr_t _cbmem_top_ptr;
void cbmem_run_init_hooks(int is_recovery)
{
}
static void *get_cbmem_ptr(void)
{
void *cbmem_top_ptr = (void *)_cbmem_top_ptr;
if (cbmem_top_ptr)
return cbmem_top_ptr - CBMEM_SIZE;
else
return NULL;
}
static void clear_cbmem(void)
{
void *ptr = get_cbmem_ptr();
if (ptr)
memset(ptr, 0, CBMEM_SIZE);
}
int setup_test(void **state)
{
void *cbmem_top_ptr = malloc(CBMEM_SIZE);
if (!cbmem_top_ptr)
return -1;
_cbmem_top_ptr = (uintptr_t)cbmem_top_ptr + CBMEM_SIZE;
clear_cbmem();
cbmem_initialize_empty();
return 0;
}
int teardown_test(void **state)
{
if (_cbmem_top_ptr && (_cbmem_top_ptr - CBMEM_SIZE))
free((void *)(_cbmem_top_ptr - CBMEM_SIZE));
_cbmem_top_ptr = 0;
return 0;
}
/* This function is used as prog_entry of struct prog to prevent potential calls to unaccessible
or incorrect addresses. */
void prog_entry_mock(void *arg)
{
}
/* This test checks if stage_cache_add() correctly adds CBMEM_ID_STAGE_x_META
and CBMEM_ID_STAGEx_CACHE entries to cbmem. stage_cache_add() must create meta
entry containing load address, entry address and argument for it. It also must
copy buffer pointer pointed by start pointer of prog struct to cache entry. */
void test_stage_cache_add(void **state)
{
const int id = 12;
int arg = 0xC14;
struct stage_cache *meta = NULL;
uint8_t *prog_data_buf = NULL;
const size_t data_sz = 4 * KiB;
uint8_t *data = malloc(data_sz);
struct prog prog_data = {0};
assert_non_null(data);
memset(data, 0xDB, data_sz);
prog_data = (struct prog)PROG_INIT(PROG_ROMSTAGE, "test_prog");
prog_set_area(&prog_data, data, data_sz);
prog_set_entry(&prog_data, prog_entry_mock, &arg);
stage_cache_add(id, &prog_data);
meta = cbmem_find(CBMEM_ID_STAGEx_META + id);
assert_non_null(meta);
assert_int_equal(meta->load_addr, (uintptr_t)prog_start(&prog_data));
assert_int_equal(meta->entry_addr, (uintptr_t)prog_entry(&prog_data));
assert_int_equal(meta->arg, (uintptr_t)prog_entry_arg(&prog_data));
prog_data_buf = cbmem_find(CBMEM_ID_STAGEx_CACHE + id);
assert_non_null(prog_data_buf);
assert_memory_equal(data, prog_data_buf, data_sz);
free(data);
}
/* This test checks if stage_cache_add_raw() correctly creates entry with data from
provided buffer. Data should be accessible using cbmem_find() with
(CBMEM_ID_STAGEx_RAW + id) parameter. */
void test_stage_cache_add_raw(void **state)
{
const int id = 55;
const size_t data_sz = 8 * KiB;
uint8_t *data = malloc(data_sz);
uint8_t *data_raw = NULL;
assert_non_null(data);
memset(data, 0x91, data_sz);
stage_cache_add_raw(id, data, data_sz);
data_raw = cbmem_find(CBMEM_ID_STAGEx_RAW + id);
assert_non_null(data_raw);
assert_memory_equal(data_raw, data, data_sz);
free(data);
}
/* This test checks if stage_cache_get_raw() correctly extracts base and size of previously
added entry. */
void test_stage_cache_get_raw(void **state)
{
const int id = 23;
const size_t data_sz = 3 * KiB;
uint8_t *data = malloc(data_sz);
size_t data_out_sz = 0;
uint8_t *data_out = NULL;
assert_non_null(data);
memset(data, 0x3c, data_sz);
stage_cache_add_raw(id, data, data_sz);
stage_cache_get_raw(id, (void **)&data_out, &data_out_sz);
assert_int_equal(data_sz, data_out_sz);
assert_memory_equal(data, data_out, data_sz);
free(data);
}
/* This test checks if stage_cache_load_stage() correctly loads previously added stage data
and its metadata. */
void test_stage_cache_load_stage(void **state)
{
int id = 0xCC;
struct prog prog_out = {0};
const size_t data_sz = 7 * KiB;
uint8_t *data = malloc(data_sz);
uint8_t *data_bak = malloc(data_sz);
struct prog prog_data = {0};
int arg = 0x33224455;
assert_non_null(data);
assert_non_null(data_bak);
memset(data, 0x45, data_sz);
prog_data = (struct prog)PROG_INIT(PROG_RAMSTAGE, "test_prog");
prog_set_area(&prog_data, data, data_sz);
prog_set_entry(&prog_data, prog_entry_mock, &arg);
stage_cache_add(id, &prog_data);
/* Copy current data to backup buffer and clear current buffer */
memcpy(data_bak, data, data_sz);
memset(data, 0, data_sz);
/* Load stage data. Data should be returned to the same buffer. */
stage_cache_load_stage(id, &prog_out);
/* Data should be same as it was before */
assert_memory_equal(data, data_bak, data_sz);
assert_int_equal(prog_start(&prog_data), prog_start(&prog_out));
assert_int_equal(prog_size(&prog_data), prog_size(&prog_out));
assert_ptr_equal(prog_entry(&prog_data), prog_entry(&prog_out));
assert_ptr_equal(prog_entry_arg(&prog_data), prog_entry_arg(&prog_out));
free(data_bak);
free(data);
}
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_stage_cache_add,
setup_test, teardown_test),
cmocka_unit_test_setup_teardown(test_stage_cache_add_raw,
setup_test, teardown_test),
cmocka_unit_test_setup_teardown(test_stage_cache_get_raw,
setup_test, teardown_test),
cmocka_unit_test_setup_teardown(test_stage_cache_load_stage,
setup_test, teardown_test),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}