blob: 7256a270c1217e5db0931475143f30da893928ee [file] [log] [blame]
Jakub Czapigadb4b21a2021-05-25 15:46:37 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <tests/test.h>
4#include <cbmem.h>
Jakub Czapigaea619422021-11-23 08:43:25 +00005#include <commonlib/bsd/cbmem_id.h>
Jakub Czapigadb4b21a2021-05-25 15:46:37 +02006#include <stage_cache.h>
7
8#define CBMEM_SIZE (32 * KiB)
9
10/* CBMEM top pointer used by implementation. */
11extern uintptr_t _cbmem_top_ptr;
12
13void cbmem_run_init_hooks(int is_recovery)
14{
15}
16
17static void *get_cbmem_ptr(void)
18{
19 void *cbmem_top_ptr = (void *)_cbmem_top_ptr;
20 if (cbmem_top_ptr)
21 return cbmem_top_ptr - CBMEM_SIZE;
22 else
23 return NULL;
24}
25
26static void clear_cbmem(void)
27{
28 void *ptr = get_cbmem_ptr();
29 if (ptr)
30 memset(ptr, 0, CBMEM_SIZE);
31}
32
33int setup_test(void **state)
34{
35 void *cbmem_top_ptr = malloc(CBMEM_SIZE);
36
37 if (!cbmem_top_ptr)
38 return -1;
39
40 _cbmem_top_ptr = (uintptr_t)cbmem_top_ptr + CBMEM_SIZE;
41 clear_cbmem();
42 cbmem_initialize_empty();
43 return 0;
44}
45
46int teardown_test(void **state)
47{
48 if (_cbmem_top_ptr && (_cbmem_top_ptr - CBMEM_SIZE))
49 free((void *)(_cbmem_top_ptr - CBMEM_SIZE));
50
51 _cbmem_top_ptr = 0;
52 return 0;
53}
54
55/* This function is used as prog_entry of struct prog to prevent potential calls to unaccessible
56 or incorrect addresses. */
57void prog_entry_mock(void *arg)
58{
59}
60
61/* This test checks if stage_cache_add() correctly adds CBMEM_ID_STAGE_x_META
62 and CBMEM_ID_STAGEx_CACHE entries to cbmem. stage_cache_add() must create meta
63 entry containing load address, entry address and argument for it. It also must
64 copy buffer pointer pointed by start pointer of prog struct to cache entry. */
65void test_stage_cache_add(void **state)
66{
67 const int id = 12;
68 int arg = 0xC14;
69 struct stage_cache *meta = NULL;
70 uint8_t *prog_data_buf = NULL;
71 const size_t data_sz = 4 * KiB;
72 uint8_t *data = malloc(data_sz);
73 struct prog prog_data = {0};
74
75 assert_non_null(data);
76 memset(data, 0xDB, data_sz);
77 prog_data = (struct prog)PROG_INIT(PROG_ROMSTAGE, "test_prog");
78 prog_set_area(&prog_data, data, data_sz);
79 prog_set_entry(&prog_data, prog_entry_mock, &arg);
80
81 stage_cache_add(id, &prog_data);
82
83 meta = cbmem_find(CBMEM_ID_STAGEx_META + id);
84 assert_non_null(meta);
85 assert_int_equal(meta->load_addr, (uintptr_t)prog_start(&prog_data));
86 assert_int_equal(meta->entry_addr, (uintptr_t)prog_entry(&prog_data));
87 assert_int_equal(meta->arg, (uintptr_t)prog_entry_arg(&prog_data));
88
89 prog_data_buf = cbmem_find(CBMEM_ID_STAGEx_CACHE + id);
90 assert_non_null(prog_data_buf);
91 assert_memory_equal(data, prog_data_buf, data_sz);
92
93 free(data);
94}
95
96/* This test checks if stage_cache_add_raw() correctly creates entry with data from
97 provided buffer. Data should be accessible using cbmem_find() with
98 (CBMEM_ID_STAGEx_RAW + id) parameter. */
99void test_stage_cache_add_raw(void **state)
100{
101 const int id = 55;
102 const size_t data_sz = 8 * KiB;
103 uint8_t *data = malloc(data_sz);
104 uint8_t *data_raw = NULL;
105
106 assert_non_null(data);
107 memset(data, 0x91, data_sz);
108
109 stage_cache_add_raw(id, data, data_sz);
110
111 data_raw = cbmem_find(CBMEM_ID_STAGEx_RAW + id);
112 assert_non_null(data_raw);
113 assert_memory_equal(data_raw, data, data_sz);
114
115 free(data);
116}
117
118
119/* This test checks if stage_cache_get_raw() correctly extracts base and size of previously
120 added entry. */
121void test_stage_cache_get_raw(void **state)
122{
123 const int id = 23;
124 const size_t data_sz = 3 * KiB;
125 uint8_t *data = malloc(data_sz);
126 size_t data_out_sz = 0;
127 uint8_t *data_out = NULL;
128
129 assert_non_null(data);
130 memset(data, 0x3c, data_sz);
131 stage_cache_add_raw(id, data, data_sz);
132
133 stage_cache_get_raw(id, (void **)&data_out, &data_out_sz);
134
135 assert_int_equal(data_sz, data_out_sz);
136 assert_memory_equal(data, data_out, data_sz);
137
138 free(data);
139}
140
141/* This test checks if stage_cache_load_stage() correctly loads previously added stage data
142 and its metadata. */
143void test_stage_cache_load_stage(void **state)
144{
145 int id = 0xCC;
146 struct prog prog_out = {0};
147 const size_t data_sz = 7 * KiB;
148 uint8_t *data = malloc(data_sz);
149 uint8_t *data_bak = malloc(data_sz);
150 struct prog prog_data = {0};
151 int arg = 0x33224455;
152
153 assert_non_null(data);
154 assert_non_null(data_bak);
155 memset(data, 0x45, data_sz);
156
157 prog_data = (struct prog)PROG_INIT(PROG_RAMSTAGE, "test_prog");
158 prog_set_area(&prog_data, data, data_sz);
159 prog_set_entry(&prog_data, prog_entry_mock, &arg);
160 stage_cache_add(id, &prog_data);
161
162 /* Copy current data to backup buffer and clear current buffer */
163 memcpy(data_bak, data, data_sz);
164 memset(data, 0, data_sz);
165
166 /* Load stage data. Data should be returned to the same buffer. */
167 stage_cache_load_stage(id, &prog_out);
168
169 /* Data should be same as it was before */
170 assert_memory_equal(data, data_bak, data_sz);
171 assert_int_equal(prog_start(&prog_data), prog_start(&prog_out));
172 assert_int_equal(prog_size(&prog_data), prog_size(&prog_out));
173 assert_ptr_equal(prog_entry(&prog_data), prog_entry(&prog_out));
174 assert_ptr_equal(prog_entry_arg(&prog_data), prog_entry_arg(&prog_out));
175
176 free(data_bak);
177 free(data);
178}
179
180int main(void)
181{
182 const struct CMUnitTest tests[] = {
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000183 cmocka_unit_test_setup_teardown(test_stage_cache_add, setup_test,
184 teardown_test),
185 cmocka_unit_test_setup_teardown(test_stage_cache_add_raw, setup_test,
186 teardown_test),
187 cmocka_unit_test_setup_teardown(test_stage_cache_get_raw, setup_test,
188 teardown_test),
189 cmocka_unit_test_setup_teardown(test_stage_cache_load_stage, setup_test,
190 teardown_test),
Jakub Czapigadb4b21a2021-05-25 15:46:37 +0200191 };
192
Jakub Czapiga7c6081e2021-08-25 16:27:35 +0200193 return cb_run_group_tests(tests, NULL, NULL);
Jakub Czapigadb4b21a2021-05-25 15:46:37 +0200194}