Hello Urja Rannikko,
I'd like you to do a code review. Please visit
https://review.coreboot.org/21813
to review the following change.
Change subject: Enable continuous SPI reads
......................................................................
Enable continuous SPI reads
Previous unnecessary page-by-page reading is repurposed to
read by big naturally aligned areas (now chip size limited
to 16MB for future-proofing of 4 byte addressed multi-die chips)
and serprog hack for continuous reads is removed.
Original-Change-Id: Iadf909c9216578b1c5dacd4c4991bb436e32edc9
Original-Reviewed-on: https://review.coreboot.org/20223
Original-Reviewed-by: Nico Huber <nico.h(a)gmx.de>
Original-Tested-by: build bot (Jenkins) <no-reply(a)coreboot.org>
Change-Id: I8fdf4621847b1973e5d7344b369d63da5c62e16f
Signed-off-by: Urja Rannikko <urjaman(a)gmail.com>
---
M serprog.c
M spi25.c
2 files changed, 15 insertions(+), 35 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/13/21813/1
diff --git a/serprog.c b/serprog.c
index 98aac83..25c9944 100644
--- a/serprog.c
+++ b/serprog.c
@@ -303,15 +303,13 @@
unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr,
unsigned char *readarr);
-static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
- unsigned int start, unsigned int len);
static struct spi_master spi_master_serprog = {
.type = SPI_CONTROLLER_SERPROG,
.max_data_read = MAX_DATA_READ_UNLIMITED,
.max_data_write = MAX_DATA_WRITE_UNLIMITED,
.command = serprog_spi_send_command,
.multicommand = default_spi_send_multicommand,
- .read = serprog_spi_read,
+ .read = default_spi_read,
.write_256 = default_spi_write_256,
.write_aai = default_spi_write_aai,
};
@@ -931,25 +929,6 @@
readarr);
free(parmbuf);
return ret;
-}
-
-/* FIXME: This function is optimized so that it does not split each transaction
- * into chip page_size long blocks unnecessarily like spi_read_chunked. This has
- * the advantage that it is much faster for most chips, but breaks those with
- * non-continuous reads. When spi_read_chunked is fixed this method can be removed. */
-static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
- unsigned int start, unsigned int len)
-{
- unsigned int i, cur_len;
- const unsigned int max_read = spi_master_serprog.max_data_read;
- for (i = 0; i < len; i += cur_len) {
- int ret;
- cur_len = min(max_read, (len - i));
- ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
- if (ret)
- return ret;
- }
- return 0;
}
void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
diff --git a/spi25.c b/spi25.c
index af4b6db..76242be 100644
--- a/spi25.c
+++ b/spi25.c
@@ -940,30 +940,31 @@
/*
* Read a part of the flash chip.
* FIXME: Use the chunk code from Michael Karcher instead.
- * Each page is read separately in chunks with a maximum size of chunksize.
+ * Each naturally aligned area is read separately in chunks with a maximum size of chunksize.
*/
int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
unsigned int len, unsigned int chunksize)
{
int rc = 0;
unsigned int i, j, starthere, lenhere, toread;
- unsigned int page_size = flash->chip->page_size;
+ /* Limit for multi-die 4-byte-addressing chips. */
+ unsigned int area_size = min(flash->chip->total_size * 1024, 16 * 1024 * 1024);
/* Warning: This loop has a very unusual condition and body.
- * The loop needs to go through each page with at least one affected
- * byte. The lowest page number is (start / page_size) since that
- * division rounds down. The highest page number we want is the page
+ * The loop needs to go through each area with at least one affected
+ * byte. The lowest area number is (start / area_size) since that
+ * division rounds down. The highest area number we want is the area
* where the last byte of the range lives. That last byte has the
- * address (start + len - 1), thus the highest page number is
- * (start + len - 1) / page_size. Since we want to include that last
- * page as well, the loop condition uses <=.
+ * address (start + len - 1), thus the highest area number is
+ * (start + len - 1) / area_size. Since we want to include that last
+ * area as well, the loop condition uses <=.
*/
- for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
- /* Byte position of the first byte in the range in this page. */
+ for (i = start / area_size; i <= (start + len - 1) / area_size; i++) {
+ /* Byte position of the first byte in the range in this area. */
/* starthere is an offset to the base address of the chip. */
- starthere = max(start, i * page_size);
- /* Length of bytes in the range in this page. */
- lenhere = min(start + len, (i + 1) * page_size) - starthere;
+ starthere = max(start, i * area_size);
+ /* Length of bytes in the range in this area. */
+ lenhere = min(start + len, (i + 1) * area_size) - starthere;
for (j = 0; j < lenhere; j += chunksize) {
toread = min(chunksize, lenhere - j);
rc = spi_nbyte_read(flash, starthere + j, buf + starthere - start + j, toread);
--
To view, visit https://review.coreboot.org/21813
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: stable
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8fdf4621847b1973e5d7344b369d63da5c62e16f
Gerrit-Change-Number: 21813
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: Urja Rannikko <urjaman(a)gmail.com>
Nico Huber has uploaded this change for review. ( https://review.coreboot.org/21808
Change subject: ich_descriptors: Add function to guess chipset version
......................................................................
ich_descriptors: Add function to guess chipset version
Add guess_ich_chipset() that takes fields from a descriptor dump and
returns the lowest possible chipset version.
Intel did several incompatible changes to the descriptor through the
years. However, they forgot to add a version number. So we have to
apply some heuristics to detect the chipset version in case of exter-
nal flashing.
Original-Change-Id: Ie1736663dc33801b19d3e695c072c61a6c6345a2
Original-Reviewed-on: https://review.coreboot.org/20246
Original-Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Original-Reviewed-by: David Hendricks <david.hendricks(a)gmail.com>
Original-Tested-by: build bot (Jenkins) <no-reply(a)coreboot.org>
Change-Id: I3968901a9e82a34356e8c5edb14354b82bf27305
Signed-off-by: Nico Huber <nico.huber(a)secunet.com>
---
M ich_descriptors.c
M ich_descriptors.h
2 files changed, 66 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/08/21808/1
diff --git a/ich_descriptors.c b/ich_descriptors.c
index 3e53ec9..4c18dfa 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -702,6 +702,68 @@
msg_pdbg2("\n");
}
+/*
+ * Guesses a minimum chipset version based on the maximum number of
+ * soft straps per generation.
+ */
+static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content)
+{
+ if (content->ICCRIBA == 0x00) {
+ if (content->MSL == 0 && content->ISL <= 2)
+ return CHIPSET_ICH8;
+ else if (content->ISL <= 2)
+ return CHIPSET_ICH9;
+ else if (content->ISL <= 10)
+ return CHIPSET_ICH10;
+ else if (content->ISL <= 16)
+ return CHIPSET_5_SERIES_IBEX_PEAK;
+ msg_pwarn("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
+ return CHIPSET_5_SERIES_IBEX_PEAK;
+ } else if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
+ if (content->MSL == 0 && content->ISL <= 17)
+ return CHIPSET_BAYTRAIL;
+ else if (content->MSL <= 1 && content->ISL <= 18)
+ return CHIPSET_6_SERIES_COUGAR_POINT;
+ else if (content->MSL <= 1 && content->ISL <= 21)
+ return CHIPSET_8_SERIES_LYNX_POINT;
+ msg_pwarn("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n");
+ return CHIPSET_9_SERIES_WILDCAT_POINT;
+ } else {
+ return CHIPSET_100_SERIES_SUNRISE_POINT;
+ }
+}
+
+/*
+ * As an additional measure, we check the read frequency like `ifdtool`.
+ * The frequency value 6 (17MHz) was reserved before Skylake and is the
+ * only valid value since. Skylake is currently the most important dis-
+ * tinction because of the dropped number of regions field (NR).
+ */
+enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const content,
+ const struct ich_desc_component *const component)
+{
+ const enum ich_chipset guess = guess_ich_chipset_from_content(content);
+
+ if (component->modes.freq_read == 6) {
+ if (guess != CHIPSET_100_SERIES_SUNRISE_POINT)
+ msg_pwarn("\nThe firmware descriptor has the read frequency set to 17MHz. However,\n"
+ "it doesn't look like a Skylake/Sunrise Point compatible descriptor.\n"
+ "Please report this message, the output of `ich_descriptors_tool` for\n"
+ "your descriptor and the output of `lspci -nn` to flashrom(a)flashrom.org\n\n");
+ return CHIPSET_100_SERIES_SUNRISE_POINT;
+ } else {
+ if (guess == CHIPSET_100_SERIES_SUNRISE_POINT) {
+ msg_pwarn("\nThe firmware descriptor looks like a Skylake/Sunrise Point descriptor.\n"
+ "However, the read frequency isn't set to 17MHz (the only valid value).\n"
+ "Please report this message, the output of `ich_descriptors_tool` for\n"
+ "your descriptor and the output of `lspci -nn` to flashrom(a)flashrom.org\n\n");
+ return CHIPSET_9_SERIES_WILDCAT_POINT;
+ }
+ }
+
+ return guess;
+}
+
/* len is the length of dump in bytes */
int read_ich_descriptors_from_dump(const uint32_t *dump, unsigned int len, struct ich_descriptors *desc)
{
diff --git a/ich_descriptors.h b/ich_descriptors.h
index ec85e0c..920e098 100644
--- a/ich_descriptors.h
+++ b/ich_descriptors.h
@@ -93,9 +93,10 @@
union { /* 0x0c */
uint32_t FLMAP2;
struct {
- uint32_t FMSBA :8, /* Flash (G)MCH Strap Base Addr. */
- MSL :8, /* MCH Strap Length */
- :16;
+ uint32_t FMSBA :8, /* Flash (G)MCH Strap Base Addr. */
+ MSL :8, /* MCH Strap Length */
+ ICCRIBA :8, /* ICC Reg. Init Base Addr. (new since Sandy Bridge) */
+ RIL :8; /* Register Init Length (new since Hawell) */
};
};
};
--
To view, visit https://review.coreboot.org/21808
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: stable
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3968901a9e82a34356e8c5edb14354b82bf27305
Gerrit-Change-Number: 21808
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h(a)gmx.de>