24 size_t bytes_out,
void *din,
size_t bytes_in)
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 },
55 size_t bytes_out,
void *
din,
size_t bytes_in)
67 .din =
NULL, .bytesin = 0 };
83 size_t bytes_out,
void *
din,
size_t bytes_in)
89 .din =
NULL, .bytesin = 0 };
117 #pragma GCC diagnostic push
118 #if defined(__GNUC__) && !defined(__clang__)
119 #pragma GCC diagnostic ignored "-Wstack-usage="
121 #pragma GCC diagnostic ignored "-Wvla"
123 size_t cmd_len,
const void *data,
size_t data_len)
126 u8 buff[cmd_len + data_len];
127 memcpy(buff, cmd, cmd_len);
128 memcpy(buff + cmd_len, data, data_len);
138 #pragma GCC diagnostic pop
143 size_t len,
void *
buf)
147 int (*do_cmd)(
const struct spi_slave *spi,
const u8 *din,
148 size_t in_bytes,
void *out,
size_t out_bytes);
150 if (
CONFIG(SPI_FLASH_NO_FAST_READ)) {
175 ret = do_cmd(&flash->
spi, cmd, cmd_len, data, xfer_len);
178 "SF: Failed to send read command %#.2x(%#x, %#zx): %d\n",
179 cmd[0],
offset, xfer_len, ret);
206 "SF: SPI command failed on attempt %d with rc %d\n", attempt,
211 if ((status & poll_bit) == 0)
222 unsigned long timeout)
235 if (
offset % erase_size || len % erase_size) {
252 #if CONFIG(DEBUG_SPI_FLASH)
282 size_t len,
const void *
buf)
284 unsigned long byte_addr;
285 unsigned long page_size;
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);
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],
313 buf + actual, chunk_len);
326 if (
CONFIG(DEBUG_SPI_FLASH))
328 len, (
unsigned long)(
offset - len));
336 #if CONFIG(SPI_FLASH_ADESTO)
339 #if CONFIG(SPI_FLASH_AMIC)
342 #if CONFIG(SPI_FLASH_ATMEL)
345 #if CONFIG(SPI_FLASH_EON)
348 #if CONFIG(SPI_FLASH_GIGADEVICE)
351 #if CONFIG(SPI_FLASH_MACRONIX)
354 #if CONFIG(SPI_FLASH_SPANSION)
359 #if CONFIG(SPI_FLASH_SST)
363 #if CONFIG(SPI_FLASH_STMICRO)
369 #if CONFIG(SPI_FLASH_WINBOND)
416 if (part->
id[0] == lid[0] && part->
id[1] == lid[1])
434 if (manuf_id != vi->
id)
461 if (
CONFIG(DEBUG_SPI_FLASH)) {
463 for (i = 0; i <
sizeof(idcode); i++)
468 manuf_id = idcode[0];
474 if (
CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) {
477 manuf_id = idcode[0];
480 id[0] = (idcode[1] << 8) | idcode[2];
481 id[1] = (idcode[3] << 8) | idcode[4];
510 const char *mode_string =
"";
512 mode_string =
" (Dual I/O mode)";
514 mode_string =
" (Dual Output mode)";
516 "SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n",
518 if (
bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS
519 && flash->
size != CONFIG_ROM_SIZE) {
521 " CONFIG_ROM_SIZE 0x%x!!\n", flash->
size,
579 struct region flash_region = { 0 };
591 "implemented for this vendor.\n");
602 struct region flash_region = { 0 };
615 "implemented for this vendor.\n");
652 if (!
CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP))
669 if (!
CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP))
688 if (!
CONFIG(BOOT_DEVICE_SPI_FLASH))
694 flash->
size =
sizeof(*flash);
710 if (!
CONFIG(BOOT_DEVICE_MEMORY_MAPPED)) {
724 struct region flash_region = { 0 };
748 size_t bytesout,
void *din,
size_t bytesin))
754 if (count < 1 || count > 2)
758 if (!vectors[0].dout || !vectors[0].bytesout)
761 if (vectors[0].din || vectors[0].bytesin)
766 if (vectors[1].bytesin && !vectors[1].din)
769 if (vectors[1].dout || vectors[1].bytesout)
771 din = vectors[1].
din;
778 ret = func(
slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in);
const struct spi_flash_vendor_info spi_flash_adesto_vi
const struct spi_flash_vendor_info spi_flash_amic_vi
struct arm64_kernel_header header
void * memcpy(void *dest, const void *src, size_t n)
uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
#define assert(statement)
const struct spi_flash_vendor_info spi_flash_atmel_vi
const struct spi_flash * boot_device_spi_flash(void)
#define printk(level,...)
const struct spi_flash_vendor_info spi_flash_eon_vi
const struct spi_flash_vendor_info spi_flash_gigadevice_vi
struct lb_record * lb_new_record(struct lb_header *header)
static int stopwatch_expired(struct stopwatch *sw)
static long stopwatch_duration_msecs(struct stopwatch *sw)
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
#define BIOS_INFO
BIOS_INFO - Expected events.
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
const struct spi_flash_vendor_info spi_flash_macronix_vi
int region_is_subregion(const struct region *p, const struct region *c)
#define ENV_INITIAL_STAGE
const struct spi_flash_vendor_info spi_flash_spansion_ext2_vi
const struct spi_flash_vendor_info spi_flash_spansion_vi
const struct spi_flash_vendor_info spi_flash_spansion_ext1_vi
int spi_xfer_vector(const struct spi_slave *slave, struct spi_op vectors[], size_t count)
int spi_claim_bus(const struct spi_slave *slave)
unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, unsigned int buf_len)
void spi_release_bus(const struct spi_slave *slave)
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
#define SPI_FLASH_PROG_TIMEOUT_MS
#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS
const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc
int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, const struct region *region, const enum ctrlr_prot_type type)
int spi_flash_cmd_write_page_program(const struct spi_flash *flash, u32 offset, size_t len, const void *buf)
static const struct spi_flash_vendor_info * spi_flash_vendors[]
void lb_spi_flash(struct lb_header *header)
int spi_flash_set_write_protected(const struct spi_flash *flash, const struct region *region, const enum spi_flash_status_reg_lockdown mode)
int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash)
int spi_flash_cmd_read(const struct spi_flash *flash, u32 offset, size_t len, void *buf)
int spi_flash_volatile_group_begin(const struct spi_flash *flash)
static int do_dual_io_cmd(const struct spi_slave *spi, const u8 *dout, size_t bytes_out, void *din, size_t bytes_in)
int spi_flash_read(const struct spi_flash *flash, u32 offset, size_t len, void *buf)
int spi_flash_is_write_protected(const struct spi_flash *flash, const struct region *region)
int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
static uint32_t volatile_group_count
static int do_spi_flash_cmd(const struct spi_slave *spi, const u8 *dout, size_t bytes_out, void *din, size_t bytes_in)
const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc
static int do_dual_output_cmd(const struct spi_slave *spi, const u8 *dout, size_t bytes_out, void *din, size_t bytes_in)
static void spi_flash_addr(u32 addr, u8 *cmd)
int spi_flash_generic_probe(const struct spi_slave *spi, struct spi_flash *flash)
int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout)
static const struct spi_flash_part_id * find_part(const struct spi_flash_vendor_info *vi, uint16_t id[2])
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))
int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len, const void *buf)
int spi_flash_status(const struct spi_flash *flash, u8 *reg)
static int find_match(const struct spi_slave *spi, struct spi_flash *flash, uint8_t manuf_id, uint16_t id[2])
int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len)
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)
int spi_flash_volatile_group_end(const struct spi_flash *flash)
int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd, size_t cmd_len, const void *data, size_t data_len)
int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg)
int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len)
int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, u8 cmd, u8 poll_bit)
int chipset_volatile_group_begin(const struct spi_flash *flash)
int chipset_volatile_group_end(const struct spi_flash *flash)
spi_flash_status_reg_lockdown
@ SPI_WRITE_PROTECTION_PERMANENT
@ SPI_WRITE_PROTECTION_PIN
@ SPI_WRITE_PROTECTION_PRESERVE
@ SPI_WRITE_PROTECTION_NONE
@ SPI_WRITE_PROTECTION_REBOOT
const struct spi_flash_vendor_info spi_flash_winbond_vi
#define CMD_READ_FAST_DUAL_OUTPUT
int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode)
const struct spi_flash_vendor_info spi_flash_stmicro4_vi
#define CMD_READ_ARRAY_SLOW
const struct spi_flash_vendor_info spi_flash_stmicro1_vi
const struct spi_flash_vendor_info spi_flash_sst_ai_vi
const struct spi_flash_vendor_info spi_flash_stmicro3_vi
#define CMD_READ_FAST_DUAL_IO
#define CMD_READ_ARRAY_FAST
#define CMD_EXIT_4BYTE_ADDR_MODE
const struct spi_flash_vendor_info spi_flash_sst_vi
const struct spi_flash_vendor_info spi_flash_stmicro2_vi
static struct spi_slave slave
int(* xfer_dual)(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin)
int(* flash_probe)(const struct spi_slave *slave, struct spi_flash *flash)
int(* flash_protect)(const struct spi_flash *flash, const struct region *region, const enum ctrlr_prot_type type)
int(* erase)(const struct spi_flash *flash, u32 offset, size_t len)
int(* read)(const struct spi_flash *flash, u32 offset, size_t len, void *buf)
int(* status)(const struct spi_flash *flash, u8 *reg)
int(* write)(const struct spi_flash *flash, u32 offset, size_t len, const void *buf)
uint16_t fast_read_dual_output_support
uint16_t nr_sectors_shift
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)
int(* get_write)(const struct spi_flash *flash, const struct region *region)
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)
uint8_t sector_size_kib_shift
uint16_t match_id_mask[2]
const struct spi_flash_protection_ops * prot_ops
const struct spi_flash_ops * ops
const struct spi_flash_part_id * part
union spi_flash::@248 flags
enum spi_op_status status
const struct spi_ctrlr * ctrlr