summaryrefslogtreecommitdiffstats
path: root/tests/lib/cbmem_stage_cache-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/cbmem_stage_cache-test.c')
-rw-r--r--tests/lib/cbmem_stage_cache-test.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/tests/lib/cbmem_stage_cache-test.c b/tests/lib/cbmem_stage_cache-test.c
new file mode 100644
index 000000000000..24ba09542044
--- /dev/null
+++ b/tests/lib/cbmem_stage_cache-test.c
@@ -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);
+}