spi: Use bus probing for SFDP
Only probe for the SFDP signature and split the actual SFDP parsing
into a chip preparation function.
Change-Id: I182d0a386bb2fd11951a1c9f2f965ce68ff57cf0
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/427
diff --git a/sfdp.c b/sfdp.c
index 215f24a..45303ae 100644
--- a/sfdp.c
+++ b/sfdp.c
@@ -16,12 +16,16 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+
#include "flash.h"
#include "spi_command.h"
#include "spi.h"
+#include "programmer.h"
+#include "flashchips.h"
#include "chipdrivers/spi.h"
+#include "chipdrivers/probing.h"
-static int spi_sfdp_read_sfdp_chunk(struct flashctx *flash, uint32_t address, uint8_t *buf, int len)
+static int spi_sfdp_read_sfdp_chunk(const struct spi_master *spi, uint32_t address, uint8_t *buf, int len)
{
int i, ret;
uint8_t *newbuf;
@@ -40,7 +44,7 @@
newbuf = malloc(len + 1);
if (!newbuf)
return SPI_PROGRAMMER_ERROR;
- ret = spi_send_command(flash, sizeof(cmd) - 1, len + 1, cmd, newbuf);
+ ret = spi->command(spi, sizeof(cmd) - 1, len + 1, cmd, newbuf);
memmove(buf, newbuf + 1, len);
free(newbuf);
if (ret)
@@ -51,7 +55,7 @@
return 0;
}
-static int spi_sfdp_read_sfdp(struct flashctx *flash, uint32_t address, uint8_t *buf, int len)
+static int spi_sfdp_read_sfdp(const struct spi_master *spi, uint32_t address, uint8_t *buf, int len)
{
/* FIXME: There are different upper bounds for the number of bytes to
* read on the various programmers (even depending on the rest of the
@@ -60,7 +64,7 @@
int ret = 0;
while (len > 0) {
int step = min(len, maxstep);
- ret = spi_sfdp_read_sfdp_chunk(flash, address, buf, step);
+ ret = spi_sfdp_read_sfdp_chunk(spi, address, buf, step);
if (ret)
return ret;
address += step;
@@ -338,9 +342,10 @@
return 0;
}
-int probe_spi_sfdp(struct flashctx *flash)
+int spi_prepare_sfdp(struct flashctx *flash, enum preparation_steps step)
{
- int ret = 0;
+ const struct spi_master *const spi = flash->mst.spi;
+ int ret;
uint8_t buf[8];
uint32_t tmp32;
uint8_t nph;
@@ -350,31 +355,23 @@
uint8_t *hbuf;
uint8_t *tbuf;
- if (spi_sfdp_read_sfdp(flash, 0x00, buf, 4)) {
- msg_cdbg("Receiving SFDP signature failed.\n");
+ if (step != PREPARE_POST_PROBE)
return 0;
- }
- tmp32 = buf[0];
- tmp32 |= ((unsigned int)buf[1]) << 8;
- tmp32 |= ((unsigned int)buf[2]) << 16;
- tmp32 |= ((unsigned int)buf[3]) << 24;
- if (tmp32 != 0x50444653) {
- msg_cdbg2("Signature = 0x%08x (should be 0x50444653)\n", tmp32);
- msg_cdbg("No SFDP signature found.\n");
- return 0;
- }
-
- if (spi_sfdp_read_sfdp(flash, 0x04, buf, 3)) {
+ ret = spi_sfdp_read_sfdp(spi, 0x04, buf, 3);
+ if (ret) {
msg_cdbg("Receiving SFDP revision and number of parameter "
"headers (NPH) failed. ");
- return 0;
+ return ret;
}
+
+ ret = SPI_GENERIC_ERROR;
+
msg_cdbg2("SFDP revision = %d.%d\n", buf[1], buf[0]);
if (buf[1] != 0x01) {
msg_cdbg("The chip supports an unknown version of SFDP. "
"Aborting SFDP probe!\n");
- return 0;
+ return ret;
}
nph = buf[2];
msg_cdbg2("SFDP number of parameter headers is %d (NPH = %d).\n",
@@ -387,7 +384,7 @@
msg_gerr("Out of memory!\n");
goto cleanup_hdrs;
}
- if (spi_sfdp_read_sfdp(flash, 0x08, hbuf, (nph + 1) * 8)) {
+ if (spi_sfdp_read_sfdp(spi, 0x08, hbuf, (nph + 1) * 8)) {
msg_cdbg("Receiving SFDP parameter table headers failed.\n");
goto cleanup_hdrs;
}
@@ -422,7 +419,7 @@
msg_gerr("Out of memory!\n");
goto cleanup_hdrs;
}
- if (spi_sfdp_read_sfdp(flash, tmp32, tbuf, len)){
+ if (spi_sfdp_read_sfdp(spi, tmp32, tbuf, len)){
msg_cdbg("Fetching SFDP parameter table %d failed.\n",
i);
free(tbuf);
@@ -460,14 +457,14 @@
"parameter table is wrong (%d B), "
"skipping it.\n", len);
} else if (sfdp_fill_flash(flash->chip, tbuf, len) == 0)
- ret = 1;
+ ret = 0;
}
free(tbuf);
}
- if (ret == 1 && selfcheck_chip(flash->chip, -1)) {
+ if (ret == 0 && selfcheck_chip(flash->chip, -1)) {
msg_cerr("SFDP parsing resulted in invalid chip structure.\n");
- ret = 0;
+ ret = SPI_FLASHPROG_BUG;
}
cleanup_hdrs:
@@ -475,3 +472,36 @@
free(hbuf);
return ret;
}
+
+struct found_id *probe_spi_sfdp(const struct bus_probe *probe, const struct master_common *mst)
+{
+ uint8_t buf[8];
+ uint32_t tmp32;
+
+ if (spi_sfdp_read_sfdp((struct spi_master *)mst, 0x00, buf, 4)) {
+ msg_cdbg("Receiving SFDP signature failed.\n");
+ return NULL;
+ }
+ tmp32 = buf[0];
+ tmp32 |= ((unsigned int)buf[1]) << 8;
+ tmp32 |= ((unsigned int)buf[2]) << 16;
+ tmp32 |= ((unsigned int)buf[3]) << 24;
+
+ if (tmp32 != 0x50444653) {
+ msg_cdbg2("Signature = 0x%08x (should be 0x50444653)\n", tmp32);
+ msg_cdbg("No SFDP signature found.\n");
+ return NULL;
+ }
+
+ struct found_id *const found = calloc(1, sizeof(*found));
+ if (!found) {
+ msg_cerr("Out of memory!\n");
+ return NULL;
+ }
+
+ found->info.id.type = ID_SPI_SFDP;
+ found->info.id.manufacture = GENERIC_MANUF_ID;
+ found->info.id.model = SFDP_DEVICE_ID;
+
+ return found;
+}