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