1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright 2020 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #include <include/test.h>
17
18 #include "wraps.h"
19 #include "tests.h"
20 #include "programmer.h"
21 #include "flashchips.h"
22 #include "chipdrivers.h"
23 #include "spi.h"
24
25 struct flashchip mock_chip = {
26 .vendor = "Generic",
27 .name = "unknown SPI chip (RDID)",
28 .bustype = BUS_SPI,
29 .manufacture_id = GENERIC_MANUF_ID,
30 .model_id = GENERIC_DEVICE_ID,
31 .total_size = 0,
32 .page_size = 256,
33 .tested = TEST_BAD_PREW,
34 .probe = PROBE_SPI_RDID,
35 .write = NO_WRITE_FUNC,
36 };
37
38 /*
39 * This declaration is needed for visibility, so that wrap below could
40 * redirect to real function.
41 */
42 int __real_spi_send_command(const struct flashctx *flash,
43 unsigned int writecnt, unsigned int readcnt,
44 const unsigned char *writearr, unsigned char *readarr);
45
__wrap_spi_send_command(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)46 int __wrap_spi_send_command(const struct flashctx *flash,
47 unsigned int writecnt, unsigned int readcnt,
48 const unsigned char *writearr, unsigned char *readarr)
49 {
50 if (flash->chip != &mock_chip)
51 /*
52 * Caller is some other test, redirecting to real function.
53 * This test is the only one which uses wrap of spi_send_command,
54 * all other tests use real function.
55 */
56 return __real_spi_send_command(flash, writecnt, readcnt, writearr, readarr);
57
58 check_expected_ptr(flash);
59 assert_int_equal(writecnt, mock_type(int));
60 assert_int_equal(writearr[0], mock_type(int));
61
62 int rcnt = mock_type(int);
63 assert_int_equal(readcnt, rcnt);
64 for (int i = 0; i < rcnt; i++)
65 readarr[i] = i;
66
67 return 0;
68 }
69
spi_read_progress_cb(struct flashrom_flashctx * flashctx)70 static void spi_read_progress_cb(struct flashrom_flashctx *flashctx)
71 {
72 struct flashrom_progress *progress_state = flashctx->progress_state;
73 uint32_t *cnt = (uint32_t *) progress_state->user_data;
74 assert_int_equal(0x300, progress_state->total);
75 switch (*cnt) {
76 case 0:
77 assert_int_equal(0x100, progress_state->current);
78 break;
79 case 1:
80 assert_int_equal(0x200, progress_state->current);
81 break;
82 case 2:
83 assert_int_equal(0x300, progress_state->current);
84 break;
85 case 3:
86 assert_int_equal(0x300, progress_state->current);
87 break;
88 case 4:
89 assert_int_equal(0x300, progress_state->current);
90 break;
91 default:
92 fail();
93 }
94 (*cnt)++;
95 }
96
spi_read_chunked_test_success(void ** state)97 void spi_read_chunked_test_success(void **state)
98 {
99 (void) state; /* unused */
100 uint8_t buf[0x400] = { 0x0 };
101 uint32_t cnt = 0;
102 const unsigned int max_data_read = 0x100;
103 const unsigned int offset = 0x100;
104 struct registered_master mst = {
105 .spi.read = default_spi_read,
106 .spi.max_data_read = max_data_read
107 };
108
109 /* setup initial test state */
110 struct flashctx flashctx = {
111 .chip = &mock_chip,
112 .mst = &mst
113 };
114 struct flashrom_progress progress_state = {
115 .user_data = (void *) &cnt,
116 };
117 flashrom_set_progress_callback(&flashctx, spi_read_progress_cb, &progress_state);
118 for (int i = 0; i < 4; i++) {
119 expect_memory(__wrap_spi_send_command, flash,
120 &flashctx, sizeof(flashctx));
121 will_return(__wrap_spi_send_command, JEDEC_WRDI);
122 will_return(__wrap_spi_send_command, JEDEC_READ);
123 will_return(__wrap_spi_send_command, max_data_read);
124 }
125 assert_int_equal(0, spi_chip_read(&flashctx, buf, offset, sizeof(buf)));
126 assert_int_equal(5, cnt);
127 }
128
spi_write_enable_test_success(void ** state)129 void spi_write_enable_test_success(void **state)
130 {
131 (void) state; /* unused */
132
133 /* setup initial test state. */
134 struct flashctx flashctx = { .chip = &mock_chip };
135 expect_memory(__wrap_spi_send_command, flash,
136 &flashctx, sizeof(flashctx));
137
138 will_return(__wrap_spi_send_command, JEDEC_WREN_OUTSIZE);
139 will_return(__wrap_spi_send_command, JEDEC_WREN);
140 will_return(__wrap_spi_send_command, JEDEC_WREN_INSIZE);
141 assert_int_equal(0, spi_write_enable(&flashctx));
142 }
143
spi_write_disable_test_success(void ** state)144 void spi_write_disable_test_success(void **state)
145 {
146 (void) state; /* unused */
147
148 /* setup initial test state. */
149 struct flashctx flashctx = { .chip = &mock_chip };
150 expect_memory(__wrap_spi_send_command, flash,
151 &flashctx, sizeof(flashctx));
152
153 will_return(__wrap_spi_send_command, JEDEC_WRDI_OUTSIZE);
154 will_return(__wrap_spi_send_command, JEDEC_WRDI);
155 will_return(__wrap_spi_send_command, JEDEC_WRDI_INSIZE);
156 assert_int_equal(0, spi_write_disable(&flashctx));
157 }
158
probe_spi_rdid_test_success(void ** state)159 void probe_spi_rdid_test_success(void **state)
160 {
161 (void) state; /* unused */
162
163 /* setup initial test state. */
164 struct flashctx flashctx = { .chip = &mock_chip };
165 expect_memory(__wrap_spi_send_command, flash,
166 &flashctx, sizeof(flashctx));
167
168 will_return(__wrap_spi_send_command, JEDEC_RDID_OUTSIZE);
169 will_return(__wrap_spi_send_command, JEDEC_RDID);
170 will_return(__wrap_spi_send_command, JEDEC_RDID_INSIZE);
171 assert_int_equal(0, probe_spi_rdid(&flashctx));
172 }
173
probe_spi_rdid4_test_success(void ** state)174 void probe_spi_rdid4_test_success(void **state)
175 {
176 (void) state; /* unused */
177
178 /* setup initial test state. */
179 struct flashctx flashctx = { .chip = &mock_chip };
180 expect_memory(__wrap_spi_send_command, flash,
181 &flashctx, sizeof(flashctx));
182
183 will_return(__wrap_spi_send_command, JEDEC_RDID_OUTSIZE);
184 will_return(__wrap_spi_send_command, JEDEC_RDID);
185 will_return(__wrap_spi_send_command, JEDEC_RDID_INSIZE + 1);
186 assert_int_equal(0, probe_spi_rdid4(&flashctx));
187 }
188
probe_spi_rems_test_success(void ** state)189 void probe_spi_rems_test_success(void **state)
190 {
191 (void) state; /* unused */
192
193 /* setup initial test state. */
194 struct flashctx flashctx = { .chip = &mock_chip };
195 expect_memory(__wrap_spi_send_command, flash,
196 &flashctx, sizeof(flashctx));
197
198 will_return(__wrap_spi_send_command, JEDEC_REMS_OUTSIZE);
199 will_return(__wrap_spi_send_command, JEDEC_REMS);
200 will_return(__wrap_spi_send_command, JEDEC_REMS_INSIZE);
201 assert_int_equal(0, probe_spi_rems(&flashctx));
202 }
203
probe_spi_res1_test_success(void ** state)204 void probe_spi_res1_test_success(void **state)
205 {
206 (void) state; /* unused */
207
208 /* setup initial test state. */
209 struct flashctx flashctx = { .chip = &mock_chip };
210 expect_memory(__wrap_spi_send_command, flash,
211 &flashctx, sizeof(flashctx));
212
213 will_return(__wrap_spi_send_command, JEDEC_RES_OUTSIZE);
214 will_return(__wrap_spi_send_command, JEDEC_RES);
215 will_return(__wrap_spi_send_command, JEDEC_RES_INSIZE + 1);
216 assert_int_equal(0, probe_spi_res2(&flashctx));
217 }
218
probe_spi_res2_test_success(void ** state)219 void probe_spi_res2_test_success(void **state)
220 {
221 (void) state; /* unused */
222
223 /* setup initial test state. */
224 clear_spi_id_cache();
225 struct flashctx flashctx = { .chip = &mock_chip };
226 expect_memory(__wrap_spi_send_command, flash,
227 &flashctx, sizeof(flashctx));
228
229 will_return(__wrap_spi_send_command, JEDEC_RES_OUTSIZE);
230 will_return(__wrap_spi_send_command, JEDEC_RES);
231 will_return(__wrap_spi_send_command, JEDEC_RES_INSIZE + 1);
232 assert_int_equal(0, probe_spi_res2(&flashctx));
233 }
234
probe_spi_res3_test_success(void ** state)235 void probe_spi_res3_test_success(void **state)
236 {
237 (void) state; /* unused */
238
239 /* setup initial test state. */
240 struct flashctx flashctx = { .chip = &mock_chip };
241 expect_memory(__wrap_spi_send_command, flash,
242 &flashctx, sizeof(flashctx));
243
244 will_return(__wrap_spi_send_command, JEDEC_RES_OUTSIZE);
245 will_return(__wrap_spi_send_command, JEDEC_RES);
246 will_return(__wrap_spi_send_command, JEDEC_RES_INSIZE + 2);
247 assert_int_equal(0, probe_spi_res3(&flashctx));
248 }
249
probe_spi_at25f_test_success(void ** state)250 void probe_spi_at25f_test_success(void **state)
251 {
252 (void) state; /* unused */
253
254 /* setup initial test state. */
255 struct flashctx flashctx = { .chip = &mock_chip };
256 expect_memory(__wrap_spi_send_command, flash,
257 &flashctx, sizeof(flashctx));
258
259 will_return(__wrap_spi_send_command, AT25F_RDID_OUTSIZE);
260 will_return(__wrap_spi_send_command, AT25F_RDID);
261 will_return(__wrap_spi_send_command, AT25F_RDID_INSIZE);
262 assert_int_equal(0, probe_spi_at25f(&flashctx));
263 }
264
265 /* spi95.c */
probe_spi_st95_test_success(void ** state)266 void probe_spi_st95_test_success(void **state)
267 {
268 (void) state; /* unused */
269
270 /* setup initial test state. */
271 struct flashctx flashctx = { .chip = &mock_chip };
272 expect_memory(__wrap_spi_send_command, flash,
273 &flashctx, sizeof(flashctx));
274
275 /* chip total size < 64K. */
276 uint32_t rdid_outsize = ST_M95_RDID_2BA_OUTSIZE; // 16 bit address
277
278 will_return(__wrap_spi_send_command, rdid_outsize);
279 will_return(__wrap_spi_send_command, ST_M95_RDID);
280 will_return(__wrap_spi_send_command, ST_M95_RDID_INSIZE);
281 assert_int_equal(0, probe_spi_st95(&flashctx));
282 }
283