xref: /aosp_15_r20/external/coreboot/src/drivers/spi/spi_flash.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <assert.h>
4 #include <boot/coreboot_tables.h>
5 #include <commonlib/region.h>
6 #include <console/console.h>
7 #include <string.h>
8 #include <spi-generic.h>
9 #include <spi_flash.h>
10 #include <timer.h>
11 #include <types.h>
12 
13 #include "spi_flash_internal.h"
14 
15 #if CONFIG(SPI_FLASH_FORCE_4_BYTE_ADDR_MODE)
16 #define ADDR_MOD 1
17 #else
18 #define ADDR_MOD 0
19 #endif
20 
21 #define SPI_FLASH_EXIT_4BYTE_STAGE	\
22 	(ENV_INITIAL_STAGE || CONFIG(BOOT_DEVICE_MEMORY_MAPPED))
23 
spi_flash_addr(u32 addr,u8 * cmd)24 static void spi_flash_addr(u32 addr, u8 *cmd)
25 {
26 	/* cmd[0] is actual command */
27 	if (CONFIG(SPI_FLASH_FORCE_4_BYTE_ADDR_MODE)) {
28 		cmd[1] = addr >> 24;
29 		cmd[2] = addr >> 16;
30 		cmd[3] = addr >> 8;
31 		cmd[4] = addr >> 0;
32 	} else {
33 		cmd[1] = addr >> 16;
34 		cmd[2] = addr >> 8;
35 		cmd[3] = addr >> 0;
36 	}
37 }
38 
do_spi_flash_cmd(const struct spi_slave * spi,const u8 * dout,size_t bytes_out,void * din,size_t bytes_in)39 static int do_spi_flash_cmd(const struct spi_slave *spi, const u8 *dout,
40 			    size_t bytes_out, void *din, size_t bytes_in)
41 {
42 	int ret;
43 	/*
44 	 * SPI flash requires command-response kind of behavior. Thus, two
45 	 * separate SPI vectors are required -- first to transmit dout and other
46 	 * to receive in din. If some specialized SPI flash controllers
47 	 * (e.g. x86) can perform both command and response together, it should
48 	 * be handled at SPI flash controller driver level.
49 	 */
50 	struct spi_op vectors[] = {
51 		[0] = { .dout = dout, .bytesout = bytes_out,
52 			.din = NULL, .bytesin = 0, },
53 		[1] = { .dout = NULL, .bytesout = 0,
54 			.din = din, .bytesin = bytes_in },
55 	};
56 	size_t count = ARRAY_SIZE(vectors);
57 	if (!bytes_in)
58 		count = 1;
59 
60 	ret = spi_claim_bus(spi);
61 	if (ret)
62 		return ret;
63 
64 	ret = spi_xfer_vector(spi, vectors, count);
65 
66 	spi_release_bus(spi);
67 	return ret;
68 }
69 
do_dual_output_cmd(const struct spi_slave * spi,const u8 * dout,size_t bytes_out,void * din,size_t bytes_in)70 static int do_dual_output_cmd(const struct spi_slave *spi, const u8 *dout,
71 			      size_t bytes_out, void *din, size_t bytes_in)
72 {
73 	int ret;
74 
75 	/*
76 	 * spi_xfer_vector() will automatically fall back to .xfer() if
77 	 * .xfer_vector() is unimplemented. So using vector API here is more
78 	 * flexible, even though a controller that implements .xfer_vector()
79 	 * and (the non-vector based) .xfer_dual() but not .xfer() would be
80 	 * pretty odd.
81 	 */
82 	struct spi_op vector = { .dout = dout, .bytesout = bytes_out,
83 				 .din = NULL, .bytesin = 0 };
84 
85 	ret = spi_claim_bus(spi);
86 	if (ret)
87 		return ret;
88 
89 	ret = spi_xfer_vector(spi, &vector, 1);
90 
91 	if (!ret)
92 		ret = spi->ctrlr->xfer_dual(spi, NULL, 0, din, bytes_in);
93 
94 	spi_release_bus(spi);
95 	return ret;
96 }
97 
do_dual_io_cmd(const struct spi_slave * spi,const u8 * dout,size_t bytes_out,void * din,size_t bytes_in)98 static int do_dual_io_cmd(const struct spi_slave *spi, const u8 *dout,
99 			  size_t bytes_out, void *din, size_t bytes_in)
100 {
101 	int ret;
102 
103 	/* Only the very first byte (opcode) is transferred in "single" mode. */
104 	struct spi_op vector = { .dout = dout, .bytesout = 1,
105 				 .din = NULL, .bytesin = 0 };
106 
107 	ret = spi_claim_bus(spi);
108 	if (ret)
109 		return ret;
110 
111 	ret = spi_xfer_vector(spi, &vector, 1);
112 
113 	if (!ret)
114 		ret = spi->ctrlr->xfer_dual(spi, &dout[1], bytes_out - 1, NULL, 0);
115 
116 	if (!ret)
117 		ret = spi->ctrlr->xfer_dual(spi, NULL, 0, din, bytes_in);
118 
119 	spi_release_bus(spi);
120 	return ret;
121 }
122 
spi_flash_cmd(const struct spi_slave * spi,u8 cmd,void * response,size_t len)123 int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len)
124 {
125 	int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len);
126 	if (ret)
127 		printk(BIOS_WARNING, "SF: Failed to send command %02x: %d\n", cmd, ret);
128 
129 	return ret;
130 }
131 
132 /* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */
133 #pragma GCC diagnostic push
134 #if defined(__GNUC__) && !defined(__clang__)
135 #pragma GCC diagnostic ignored "-Wstack-usage="
136 #endif
137 #pragma GCC diagnostic ignored "-Wvla"
spi_flash_cmd_write(const struct spi_slave * spi,const u8 * cmd,size_t cmd_len,const void * data,size_t data_len)138 int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd,
139 			size_t cmd_len, const void *data, size_t data_len)
140 {
141 	int ret;
142 	u8 buff[cmd_len + data_len];
143 	memcpy(buff, cmd, cmd_len);
144 	memcpy(buff + cmd_len, data, data_len);
145 
146 	ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0);
147 	if (ret) {
148 		printk(BIOS_WARNING, "SF: Failed to send write command (%zu bytes): %d\n",
149 				data_len, ret);
150 	}
151 
152 	return ret;
153 }
154 #pragma GCC diagnostic pop
155 
156 /* Perform the read operation honoring spi controller fifo size, reissuing
157  * the read command until the full request completed. */
spi_flash_cmd_read(const struct spi_flash * flash,u32 offset,size_t len,void * buf)158 int spi_flash_cmd_read(const struct spi_flash *flash, u32 offset,
159 				  size_t len, void *buf)
160 {
161 	u8 cmd[5 + ADDR_MOD];
162 	int ret, cmd_len;
163 	int (*do_cmd)(const struct spi_slave *spi, const u8 *din,
164 		      size_t in_bytes, void *out, size_t out_bytes);
165 
166 	if (CONFIG(SPI_FLASH_NO_FAST_READ)) {
167 		cmd_len = 4 + ADDR_MOD;
168 		cmd[0] = CMD_READ_ARRAY_SLOW;
169 		do_cmd = do_spi_flash_cmd;
170 	} else if (flash->flags.dual_io && flash->spi.ctrlr->xfer_dual) {
171 		cmd_len = 5 + ADDR_MOD;
172 		cmd[0] = CMD_READ_FAST_DUAL_IO;
173 		cmd[4 + ADDR_MOD] = 0;
174 		do_cmd = do_dual_io_cmd;
175 	} else if (flash->flags.dual_output && flash->spi.ctrlr->xfer_dual) {
176 		cmd_len = 5 + ADDR_MOD;
177 		cmd[0] = CMD_READ_FAST_DUAL_OUTPUT;
178 		cmd[4 + ADDR_MOD] = 0;
179 		do_cmd = do_dual_output_cmd;
180 	} else {
181 		cmd_len = 5 + ADDR_MOD;
182 		cmd[0] = CMD_READ_ARRAY_FAST;
183 		cmd[4 + ADDR_MOD] = 0;
184 		do_cmd = do_spi_flash_cmd;
185 	}
186 
187 	uint8_t *data = buf;
188 	while (len) {
189 		size_t xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len);
190 		spi_flash_addr(offset, cmd);
191 		ret = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len);
192 		if (ret) {
193 			printk(BIOS_WARNING,
194 			       "SF: Failed to send read command %#.2x(%#x, %#zx): %d\n",
195 			       cmd[0], offset, xfer_len, ret);
196 			return ret;
197 		}
198 		offset += xfer_len;
199 		data += xfer_len;
200 		len -= xfer_len;
201 	}
202 
203 	return 0;
204 }
205 
spi_flash_cmd_poll_bit(const struct spi_flash * flash,unsigned long timeout,u8 cmd,u8 poll_bit)206 int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
207 			   u8 cmd, u8 poll_bit)
208 {
209 	const struct spi_slave *spi = &flash->spi;
210 	int ret;
211 	int attempt = 0;
212 	u8 status;
213 	struct stopwatch sw;
214 
215 	stopwatch_init_msecs_expire(&sw, timeout);
216 	do {
217 		attempt++;
218 
219 		ret = do_spi_flash_cmd(spi, &cmd, 1, &status, 1);
220 		if (ret) {
221 			printk(BIOS_WARNING,
222 			       "SF: SPI command failed on attempt %d with rc %d\n", attempt,
223 			       ret);
224 			return -1;
225 		}
226 
227 		if ((status & poll_bit) == 0)
228 			return 0;
229 	} while (!stopwatch_expired(&sw));
230 
231 	printk(BIOS_WARNING, "SF: timeout at %lld msec after %d attempts\n",
232 	       stopwatch_duration_msecs(&sw), attempt);
233 
234 	return -1;
235 }
236 
spi_flash_cmd_wait_ready(const struct spi_flash * flash,unsigned long timeout)237 int spi_flash_cmd_wait_ready(const struct spi_flash *flash,
238 			unsigned long timeout)
239 {
240 	return spi_flash_cmd_poll_bit(flash, timeout,
241 		CMD_READ_STATUS, STATUS_WIP);
242 }
243 
spi_flash_cmd_erase(const struct spi_flash * flash,u32 offset,size_t len)244 int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
245 {
246 	u32 start, end, erase_size;
247 	int ret = -1;
248 	u8 cmd[4 + ADDR_MOD];
249 
250 	erase_size = flash->sector_size;
251 	if (offset % erase_size || len % erase_size) {
252 		printk(BIOS_WARNING, "SF: Erase offset/length not multiple of erase size\n");
253 		return -1;
254 	}
255 	if (len == 0) {
256 		printk(BIOS_WARNING, "SF: Erase length cannot be 0\n");
257 		return -1;
258 	}
259 
260 	cmd[0] = flash->erase_cmd;
261 	start = offset;
262 	end = start + len;
263 
264 	while (offset < end) {
265 		spi_flash_addr(offset, cmd);
266 		offset += erase_size;
267 
268 		if (CONFIG(DEBUG_SPI_FLASH)) {
269 			if (ADDR_MOD)
270 				printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x %2x (%x)\n",
271 					cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], offset);
272 			else
273 				printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n",
274 					cmd[0], cmd[1], cmd[2], cmd[3], offset);
275 		}
276 
277 		ret = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0);
278 		if (ret)
279 			goto out;
280 
281 		ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0);
282 		if (ret)
283 			goto out;
284 
285 		ret = spi_flash_cmd_wait_ready(flash,
286 				SPI_FLASH_PAGE_ERASE_TIMEOUT_MS);
287 		if (ret)
288 			goto out;
289 	}
290 
291 	printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start);
292 
293 out:
294 	return ret;
295 }
296 
spi_flash_cmd_status(const struct spi_flash * flash,u8 * reg)297 int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg)
298 {
299 	return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg));
300 }
301 
spi_flash_cmd_write_page_program(const struct spi_flash * flash,u32 offset,size_t len,const void * buf)302 int spi_flash_cmd_write_page_program(const struct spi_flash *flash, u32 offset,
303 				size_t len, const void *buf)
304 {
305 	unsigned long byte_addr;
306 	unsigned long page_size;
307 	size_t chunk_len;
308 	size_t actual;
309 	int ret = 0;
310 	u8 cmd[4 + ADDR_MOD];
311 
312 	page_size = flash->page_size;
313 	cmd[0] = flash->pp_cmd;
314 
315 	for (actual = 0; actual < len; actual += chunk_len) {
316 		byte_addr = offset % page_size;
317 		chunk_len = MIN(len - actual, page_size - byte_addr);
318 		chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len);
319 
320 		spi_flash_addr(offset, cmd);
321 		if (CONFIG(DEBUG_SPI_FLASH)) {
322 			if (ADDR_MOD)
323 				printk(BIOS_SPEW,
324 					"PP: %p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n",
325 					buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4],
326 					chunk_len);
327 			else
328 				printk(BIOS_SPEW,
329 					"PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
330 					buf + actual, cmd[0], cmd[1], cmd[2], cmd[3],
331 					chunk_len);
332 		}
333 
334 		ret = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0);
335 		if (ret < 0) {
336 			printk(BIOS_WARNING, "SF: Enabling Write failed\n");
337 			goto out;
338 		}
339 
340 		ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
341 				buf + actual, chunk_len);
342 		if (ret < 0) {
343 			printk(BIOS_WARNING, "SF: Page Program failed\n");
344 			goto out;
345 		}
346 
347 		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS);
348 		if (ret)
349 			goto out;
350 
351 		offset += chunk_len;
352 	}
353 
354 	if (CONFIG(DEBUG_SPI_FLASH))
355 		printk(BIOS_SPEW, "SF: : Successfully programmed %zu bytes @ 0x%lx\n",
356 			len, (unsigned long)(offset - len));
357 	ret = 0;
358 
359 out:
360 	return ret;
361 }
362 
363 static const struct spi_flash_vendor_info *spi_flash_vendors[] = {
364 #if CONFIG(SPI_FLASH_ADESTO)
365 	&spi_flash_adesto_vi,
366 #endif
367 #if CONFIG(SPI_FLASH_AMIC)
368 	&spi_flash_amic_vi,
369 #endif
370 #if CONFIG(SPI_FLASH_ATMEL)
371 	&spi_flash_atmel_vi,
372 #endif
373 #if CONFIG(SPI_FLASH_EON)
374 	&spi_flash_eon_vi,
375 #endif
376 #if CONFIG(SPI_FLASH_GIGADEVICE)
377 	&spi_flash_gigadevice_vi,
378 #endif
379 #if CONFIG(SPI_FLASH_MACRONIX)
380 	&spi_flash_macronix_vi,
381 #endif
382 #if CONFIG(SPI_FLASH_SPANSION)
383 	&spi_flash_spansion_ext1_vi,
384 	&spi_flash_spansion_ext2_vi,
385 	&spi_flash_spansion_vi,
386 #endif
387 #if CONFIG(SPI_FLASH_SST)
388 	&spi_flash_sst_ai_vi,
389 	&spi_flash_sst_vi,
390 #endif
391 #if CONFIG(SPI_FLASH_STMICRO)
392 	&spi_flash_stmicro1_vi,
393 	&spi_flash_stmicro2_vi,
394 	&spi_flash_stmicro3_vi,
395 	&spi_flash_stmicro4_vi,
396 #endif
397 #if CONFIG(SPI_FLASH_WINBOND)
398 	&spi_flash_winbond_vi,
399 #endif
400 #if CONFIG(SPI_FLASH_ISSI)
401 	&spi_flash_issi_vi,
402 #endif
403 };
404 #define IDCODE_LEN 5
405 
fill_spi_flash(const struct spi_slave * spi,struct spi_flash * flash,const struct spi_flash_vendor_info * vi,const struct spi_flash_part_id * part)406 static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash,
407 	const struct spi_flash_vendor_info *vi,
408 	const struct spi_flash_part_id *part)
409 {
410 	memcpy(&flash->spi, spi, sizeof(*spi));
411 	flash->vendor = vi->id;
412 	flash->model = part->id[0];
413 
414 	flash->page_size = 1U << vi->page_size_shift;
415 	flash->sector_size = (1U << vi->sector_size_kib_shift) * KiB;
416 	flash->size = flash->sector_size * (1U << part->nr_sectors_shift);
417 	flash->erase_cmd = vi->desc->erase_cmd;
418 	flash->status_cmd = vi->desc->status_cmd;
419 	flash->pp_cmd = vi->desc->pp_cmd;
420 	flash->wren_cmd = vi->desc->wren_cmd;
421 
422 	flash->flags.dual_output = part->fast_read_dual_output_support;
423 	flash->flags.dual_io = part->fast_read_dual_io_support;
424 
425 	flash->ops = &vi->desc->ops;
426 	flash->prot_ops = vi->prot_ops;
427 	flash->part = part;
428 
429 	if (vi->after_probe)
430 		return vi->after_probe(flash);
431 
432 	return 0;
433 }
434 
find_part(const struct spi_flash_vendor_info * vi,uint16_t id[2])435 static const struct spi_flash_part_id *find_part(const struct spi_flash_vendor_info *vi,
436 						uint16_t id[2])
437 {
438 	size_t i;
439 	const uint16_t lid[2] = {
440 		[0] = id[0] & vi->match_id_mask[0],
441 		[1] = id[1] & vi->match_id_mask[1],
442 	};
443 
444 	for (i = 0; i < vi->nr_part_ids; i++) {
445 		const struct spi_flash_part_id *part = &vi->ids[i];
446 
447 		if (part->id[0] == lid[0] && part->id[1] == lid[1])
448 			return part;
449 	}
450 
451 	return NULL;
452 }
453 
find_match(const struct spi_slave * spi,struct spi_flash * flash,uint8_t manuf_id,uint16_t id[2])454 static int find_match(const struct spi_slave *spi, struct spi_flash *flash,
455 			uint8_t manuf_id, uint16_t id[2])
456 {
457 	int i;
458 
459 	for (i = 0; i < (int)ARRAY_SIZE(spi_flash_vendors); i++) {
460 		const struct spi_flash_vendor_info *vi;
461 		const struct spi_flash_part_id *part;
462 
463 		vi = spi_flash_vendors[i];
464 
465 		if (manuf_id != vi->id)
466 			continue;
467 
468 		part = find_part(vi, id);
469 
470 		if (part == NULL)
471 			continue;
472 
473 		return fill_spi_flash(spi, flash, vi, part);
474 	}
475 
476 	printk(BIOS_WARNING, "SF: no match for ID %04x %04x\n", id[0], id[1]);
477 	return -1;
478 }
479 
spi_flash_generic_probe(const struct spi_slave * spi,struct spi_flash * flash)480 int spi_flash_generic_probe(const struct spi_slave *spi,
481 				struct spi_flash *flash)
482 {
483 	int ret, i;
484 	u8 idcode[IDCODE_LEN];
485 	u8 manuf_id;
486 	u16 id[2];
487 
488 	/* Read the ID codes */
489 	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
490 	if (ret)
491 		return -1;
492 
493 	if (CONFIG(DEBUG_SPI_FLASH)) {
494 		printk(BIOS_SPEW, "SF: Got idcode: ");
495 		for (i = 0; i < sizeof(idcode); i++)
496 			printk(BIOS_SPEW, "%02x ", idcode[i]);
497 		printk(BIOS_SPEW, "\n");
498 	}
499 
500 	manuf_id = idcode[0];
501 
502 	printk(BIOS_INFO, "Manufacturer: %02x\n", manuf_id);
503 
504 	/* If no result from RDID command and STMicro parts are enabled attempt
505 	   to wake the part from deep sleep and obtain alternative id info. */
506 	if (CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) {
507 		if (stmicro_release_deep_sleep_identify(spi, idcode))
508 			return -1;
509 		manuf_id = idcode[0];
510 	}
511 
512 	id[0] = (idcode[1] << 8) | idcode[2];
513 	id[1] = (idcode[3] << 8) | idcode[4];
514 
515 	return find_match(spi, flash, manuf_id, id);
516 }
517 
spi_flash_probe(unsigned int bus,unsigned int cs,struct spi_flash * flash)518 int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash)
519 {
520 	struct spi_slave spi;
521 	int ret = -1;
522 
523 	if (spi_setup_slave(bus, cs, &spi)) {
524 		printk(BIOS_WARNING, "SF: Failed to set up slave\n");
525 		return -1;
526 	}
527 
528 	/* Try special programmer probe if any. */
529 	if (spi.ctrlr->flash_probe)
530 		ret = spi.ctrlr->flash_probe(&spi, flash);
531 
532 	/* If flash is not found, try generic spi flash probe. */
533 	if (ret)
534 		ret = spi_flash_generic_probe(&spi, flash);
535 
536 	/* Give up -- nothing more to try if flash is not found. */
537 	if (ret) {
538 		printk(BIOS_WARNING, "SF: Unsupported manufacturer!\n");
539 		return -1;
540 	}
541 
542 	const char *mode_string = "";
543 	if (flash->flags.dual_io && spi.ctrlr->xfer_dual)
544 		mode_string = " (Dual I/O mode)";
545 	else if (flash->flags.dual_output && spi.ctrlr->xfer_dual)
546 		mode_string = " (Dual Output mode)";
547 	printk(BIOS_INFO,
548 	       "SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n",
549 		flash->vendor, flash->model, flash->sector_size, flash->size, mode_string);
550 	if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS
551 			&& flash->size != CONFIG_ROM_SIZE) {
552 		printk(BIOS_ERR, "SF size 0x%x does not correspond to"
553 			" CONFIG_ROM_SIZE 0x%x!!\n", flash->size,
554 			CONFIG_ROM_SIZE);
555 	}
556 
557 	if (CONFIG(SPI_FLASH_EXIT_4_BYTE_ADDR_MODE) && SPI_FLASH_EXIT_4BYTE_STAGE) {
558 		printk(BIOS_DEBUG, "SF: Exiting 4-byte addressing mode\n");
559 		spi_flash_cmd(&flash->spi, CMD_EXIT_4BYTE_ADDR_MODE, NULL, 0);
560 	}
561 
562 	return 0;
563 }
564 
spi_flash_read(const struct spi_flash * flash,u32 offset,size_t len,void * buf)565 int spi_flash_read(const struct spi_flash *flash, u32 offset, size_t len,
566 		void *buf)
567 {
568 	return flash->ops->read(flash, offset, len, buf);
569 }
570 
spi_flash_write(const struct spi_flash * flash,u32 offset,size_t len,const void * buf)571 int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len,
572 		const void *buf)
573 {
574 	int ret;
575 
576 	if (spi_flash_volatile_group_begin(flash))
577 		return -1;
578 
579 	ret = flash->ops->write(flash, offset, len, buf);
580 
581 	if (spi_flash_volatile_group_end(flash))
582 		return -1;
583 
584 	return ret;
585 }
586 
spi_flash_erase(const struct spi_flash * flash,u32 offset,size_t len)587 int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len)
588 {
589 	int ret;
590 
591 	if (spi_flash_volatile_group_begin(flash))
592 		return -1;
593 
594 	ret = flash->ops->erase(flash, offset, len);
595 
596 	if (spi_flash_volatile_group_end(flash))
597 		return -1;
598 
599 	return ret;
600 }
601 
spi_flash_status(const struct spi_flash * flash,u8 * reg)602 int spi_flash_status(const struct spi_flash *flash, u8 *reg)
603 {
604 	if (flash->ops->status)
605 		return flash->ops->status(flash, reg);
606 
607 	return -1;
608 }
609 
spi_flash_is_write_protected(const struct spi_flash * flash,const struct region * region)610 int spi_flash_is_write_protected(const struct spi_flash *flash,
611 				 const struct region *region)
612 {
613 	struct region flash_region = { 0 };
614 
615 	if (!flash || !region)
616 		return -1;
617 
618 	flash_region.size = flash->size;
619 
620 	if (!region_is_subregion(&flash_region, region))
621 		return -1;
622 
623 	if (!flash->prot_ops) {
624 		printk(BIOS_WARNING, "SPI: Write-protection gathering not "
625 		       "implemented for this vendor.\n");
626 		return -1;
627 	}
628 
629 	return flash->prot_ops->get_write(flash, region);
630 }
631 
spi_flash_set_write_protected(const struct spi_flash * flash,const struct region * region,const enum spi_flash_status_reg_lockdown mode)632 int spi_flash_set_write_protected(const struct spi_flash *flash,
633 				  const struct region *region,
634 				  const enum spi_flash_status_reg_lockdown mode)
635 {
636 	struct region flash_region = { 0 };
637 	int ret;
638 
639 	if (!flash)
640 		return -1;
641 
642 	flash_region.size = flash->size;
643 
644 	if (!region_is_subregion(&flash_region, region))
645 		return -1;
646 
647 	if (!flash->prot_ops) {
648 		printk(BIOS_WARNING, "SPI: Setting write-protection is not "
649 		       "implemented for this vendor.\n");
650 		return -1;
651 	}
652 
653 	ret = flash->prot_ops->set_write(flash, region, mode);
654 
655 	if (ret == 0 && mode != SPI_WRITE_PROTECTION_PRESERVE) {
656 		printk(BIOS_INFO, "SPI: SREG lock-down was set to ");
657 		switch (mode) {
658 		case SPI_WRITE_PROTECTION_NONE:
659 			printk(BIOS_INFO, "NEVER\n");
660 		break;
661 		case SPI_WRITE_PROTECTION_PIN:
662 			printk(BIOS_INFO, "WP\n");
663 		break;
664 		case SPI_WRITE_PROTECTION_REBOOT:
665 			printk(BIOS_INFO, "REBOOT\n");
666 		break;
667 		case SPI_WRITE_PROTECTION_PERMANENT:
668 			printk(BIOS_INFO, "PERMANENT\n");
669 		break;
670 		default:
671 			printk(BIOS_INFO, "UNKNOWN\n");
672 		break;
673 		}
674 	}
675 
676 	return ret;
677 }
678 
679 static uint32_t volatile_group_count;
680 
spi_flash_volatile_group_begin(const struct spi_flash * flash)681 int spi_flash_volatile_group_begin(const struct spi_flash *flash)
682 {
683 	uint32_t count;
684 	int ret = 0;
685 
686 	if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP))
687 		return ret;
688 
689 	count = volatile_group_count;
690 	if (count == 0)
691 		ret = chipset_volatile_group_begin(flash);
692 
693 	count++;
694 	volatile_group_count = count;
695 	return ret;
696 }
697 
spi_flash_volatile_group_end(const struct spi_flash * flash)698 int spi_flash_volatile_group_end(const struct spi_flash *flash)
699 {
700 	uint32_t count;
701 	int ret = 0;
702 
703 	if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP))
704 		return ret;
705 
706 	count = volatile_group_count;
707 	assert(count == 0);
708 	count--;
709 	volatile_group_count = count;
710 
711 	if (count == 0)
712 		ret = chipset_volatile_group_end(flash);
713 
714 	return ret;
715 }
716 
lb_spi_flash(struct lb_header * header)717 void lb_spi_flash(struct lb_header *header)
718 {
719 	struct lb_spi_flash *flash;
720 	const struct spi_flash *spi_flash_dev;
721 
722 	if (!CONFIG(BOOT_DEVICE_SPI_FLASH))
723 		return;
724 
725 	flash = (struct lb_spi_flash *)lb_new_record(header);
726 
727 	flash->tag = LB_TAG_SPI_FLASH;
728 	flash->size = sizeof(*flash);
729 
730 	spi_flash_dev = boot_device_spi_flash();
731 
732 	if (spi_flash_dev) {
733 		flash->flash_size = spi_flash_dev->size;
734 		flash->sector_size = spi_flash_dev->sector_size;
735 		flash->erase_cmd = spi_flash_dev->erase_cmd;
736 	} else {
737 		flash->flash_size = CONFIG_ROM_SIZE;
738 		/* Default 64k erase command should work on most flash.
739 		 * Uniform 4k erase only works on certain devices. */
740 		flash->sector_size = 64 * KiB;
741 		flash->erase_cmd = CMD_BLOCK_ERASE;
742 	}
743 
744 	if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED)) {
745 		flash->mmap_count = 0;
746 	} else {
747 		struct flash_mmap_window *table = (struct flash_mmap_window *)(flash + 1);
748 		flash->mmap_count = spi_flash_get_mmap_windows(table);
749 		flash->size += flash->mmap_count * sizeof(*table);
750 	}
751 }
752 
spi_flash_ctrlr_protect_region(const struct spi_flash * flash,const struct region * region,const enum ctrlr_prot_type type)753 int spi_flash_ctrlr_protect_region(const struct spi_flash *flash,
754 				   const struct region *region,
755 				   const enum ctrlr_prot_type type)
756 {
757 	const struct spi_ctrlr *ctrlr;
758 	struct region flash_region = { 0 };
759 
760 	if (!flash)
761 		return -1;
762 
763 	flash_region.size = flash->size;
764 
765 	if (!region_is_subregion(&flash_region, region))
766 		return -1;
767 
768 	ctrlr = flash->spi.ctrlr;
769 
770 	if (!ctrlr)
771 		return -1;
772 
773 	if (ctrlr->flash_protect)
774 		return ctrlr->flash_protect(flash, region, type);
775 
776 	return -1;
777 }
778 
spi_flash_vector_helper(const struct spi_slave * slave,struct spi_op vectors[],size_t count,int (* func)(const struct spi_slave * slave,const void * dout,size_t bytesout,void * din,size_t bytesin))779 int spi_flash_vector_helper(const struct spi_slave *slave,
780 	struct spi_op vectors[], size_t count,
781 	int (*func)(const struct spi_slave *slave, const void *dout,
782 		    size_t bytesout, void *din, size_t bytesin))
783 {
784 	int ret;
785 	void *din;
786 	size_t bytes_in;
787 
788 	if (count < 1 || count > 2)
789 		return -1;
790 
791 	/* SPI flash commands always have a command first... */
792 	if (!vectors[0].dout || !vectors[0].bytesout)
793 		return -1;
794 	/* And not read any data during the command. */
795 	if (vectors[0].din || vectors[0].bytesin)
796 		return -1;
797 
798 	if (count == 2) {
799 		/* If response bytes requested ensure the buffer is valid. */
800 		if (vectors[1].bytesin && !vectors[1].din)
801 			return -1;
802 		/* No sends can accompany a receive. */
803 		if (vectors[1].dout || vectors[1].bytesout)
804 			return -1;
805 		din = vectors[1].din;
806 		bytes_in = vectors[1].bytesin;
807 	} else {
808 		din = NULL;
809 		bytes_in = 0;
810 	}
811 
812 	ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in);
813 
814 	if (ret) {
815 		vectors[0].status = SPI_OP_FAILURE;
816 		if (count == 2)
817 			vectors[1].status = SPI_OP_FAILURE;
818 	} else {
819 		vectors[0].status = SPI_OP_SUCCESS;
820 		if (count == 2)
821 			vectors[1].status = SPI_OP_SUCCESS;
822 	}
823 
824 	return ret;
825 }
826 
827 const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc = {
828 	.erase_cmd = 0x20, /* Sector Erase */
829 	.status_cmd = 0x05, /* Read Status */
830 	.pp_cmd = 0x02, /* Page Program */
831 	.wren_cmd = 0x06, /* Write Enable */
832 	.ops = {
833 		.read = spi_flash_cmd_read,
834 		.write = spi_flash_cmd_write_page_program,
835 		.erase = spi_flash_cmd_erase,
836 		.status = spi_flash_cmd_status,
837 	},
838 };
839 
840 const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc = {
841 	.erase_cmd = 0xd8, /* Sector Erase */
842 	.status_cmd = 0x05, /* Read Status */
843 	.pp_cmd = 0x02, /* Page Program */
844 	.wren_cmd = 0x06, /* Write Enable */
845 	.ops = {
846 		.read = spi_flash_cmd_read,
847 		.write = spi_flash_cmd_write_page_program,
848 		.erase = spi_flash_cmd_erase,
849 		.status = spi_flash_cmd_status,
850 	},
851 };
852