Edward O'Callaghan has uploaded this change for review.

View Change

tree/: Move {un}map_flash_region out of programmer state machine

Change-Id: I9f011736681481c464946386b196c9ec2e9d7e29
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
---
M atapromise.c
M atavia.c
M dummyflasher.c
M flashrom.c
M include/programmer.h
M internal.c
M serprog.c
7 files changed, 79 insertions(+), 33 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/78/67478/1
diff --git a/atapromise.c b/atapromise.c
index ffa4698..acd98d5 100644
--- a/atapromise.c
+++ b/atapromise.c
@@ -127,6 +127,7 @@
.chip_writel = fallback_chip_writel,
.chip_writen = fallback_chip_writen,
.shutdown = atapromise_shutdown,
+ .map_flash_region = atapromise_map,
};

static int atapromise_init(const struct programmer_cfg *cfg)
@@ -190,5 +191,4 @@
.type = PCI,
.devs.dev = ata_promise,
.init = atapromise_init,
- .map_flash_region = atapromise_map,
};
diff --git a/atavia.c b/atavia.c
index a0a0547..6e25e2c 100644
--- a/atavia.c
+++ b/atavia.c
@@ -141,6 +141,7 @@
.chip_writew = fallback_chip_writew,
.chip_writel = fallback_chip_writel,
.chip_writen = fallback_chip_writen,
+ .map_flash_region = atavia_map,
};

static int atavia_init(const struct programmer_cfg *cfg)
@@ -189,5 +190,4 @@
.type = PCI,
.devs.dev = ata_via,
.init = atavia_init,
- .map_flash_region = atavia_map,
};
diff --git a/dummyflasher.c b/dummyflasher.c
index 40f22d9..16ce986 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -929,6 +929,8 @@
.write_256 = dummy_spi_write_256,
.write_aai = default_spi_write_aai,
.probe_opcode = dummy_spi_probe_opcode,
+ .map_flash_region = dummy_map,
+ .unmap_flash_region = dummy_unmap,
};

static const struct par_master par_master_dummyflasher = {
@@ -940,6 +942,8 @@
.chip_writew = dummy_chip_writew,
.chip_writel = dummy_chip_writel,
.chip_writen = dummy_chip_writen,
+ .map_flash_region = dummy_map,
+ .unmap_flash_region = dummy_unmap,
};

static const struct opaque_master opaque_master_dummyflasher = {
@@ -947,6 +951,8 @@
.read = dummy_opaque_read,
.write = dummy_opaque_write,
.erase = dummy_opaque_erase,
+ .map_flash_region = dummy_map,
+ .unmap_flash_region = dummy_unmap,
};

static int init_data(const struct programmer_cfg *cfg,
@@ -1424,6 +1430,4 @@
/* FIXME */
.devs.note = "Dummy device, does nothing and logs all accesses\n",
.init = dummy_init,
- .map_flash_region = dummy_map,
- .unmap_flash_region = dummy_unmap,
};
diff --git a/flashrom.c b/flashrom.c
index 8d08341..605d0ae 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -197,10 +197,17 @@
static void *programmer_map_flash_region(const struct flashctx *flash, const char *descr,
uintptr_t phys_addr, size_t len)
{
- void *ret;
- if (programmer->map_flash_region)
- ret = programmer->map_flash_region(descr, phys_addr, len);
- else
+ void *ret = NULL;
+ if (flash->mst->buses_supported & BUS_SPI) {
+ if (flash->mst->spi.map_flash_region)
+ ret = flash->mst->spi.map_flash_region(descr, phys_addr, len);
+ } else if (flash->mst->buses_supported & BUS_PROG) {
+ if (flash->mst->par.map_flash_region)
+ ret = flash->mst->opaque.map_flash_region(descr, phys_addr, len);
+ } else if (flash->mst->buses_supported & BUS_PARALLEL) {
+ if (flash->mst->par.map_flash_region)
+ ret = flash->mst->par.map_flash_region(descr, phys_addr, len);
+ } else
ret = fallback_map(descr, phys_addr, len);
msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
__func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
@@ -209,13 +216,35 @@

static void programmer_unmap_flash_region(const struct flashctx *flash, void *virt_addr, size_t len)
{
- if (programmer->unmap_flash_region)
- programmer->unmap_flash_region(virt_addr, len);
- else
+ if (flash->mst->buses_supported & BUS_SPI) {
+ if (flash->mst->spi.unmap_flash_region)
+ flash->mst->spi.unmap_flash_region(virt_addr, len);
+ } else if (flash->mst->buses_supported & BUS_PROG) {
+ if (flash->mst->par.unmap_flash_region)
+ flash->mst->opaque.unmap_flash_region(virt_addr, len);
+ } else if (flash->mst->buses_supported & BUS_PARALLEL) {
+ if (flash->mst->par.unmap_flash_region)
+ flash->mst->par.unmap_flash_region(virt_addr, len);
+ } else
fallback_unmap(virt_addr, len);
msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
}

+static bool is_physmap(const struct flashctx *flash)
+{
+ if (flash->mst->buses_supported & BUS_SPI) {
+ if (flash->mst->spi.map_flash_region)
+ return flash->mst->spi.map_flash_region == physmap;
+ } else if (flash->mst->buses_supported & BUS_PROG) {
+ if (flash->mst->par.map_flash_region)
+ return flash->mst->opaque.map_flash_region == physmap;
+ } else if (flash->mst->buses_supported & BUS_PARALLEL) {
+ if (flash->mst->par.map_flash_region)
+ return flash->mst->par.map_flash_region == physmap;
+ }
+ return false;
+}
+
void programmer_delay(const struct flashctx *flash, unsigned int usecs)
{
if (usecs > 0) {
@@ -828,7 +857,7 @@
flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
free(tmp);
#if CONFIG_INTERNAL == 1
- if (programmer->map_flash_region == physmap)
+ if (is_physmap(flash))
msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
PRIxPTR_WIDTH, flash->physical_memory);
else
diff --git a/include/programmer.h b/include/programmer.h
index cfd8d08..2971f79 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -49,9 +49,6 @@
} devs;

int (*init) (const struct programmer_cfg *cfg);
-
- void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len);
- void (*unmap_flash_region) (void *virt_addr, size_t len);
};

extern const struct programmer_entry *const programmer_table[];
@@ -313,6 +310,8 @@
int (*shutdown)(void *data);
bool (*probe_opcode)(struct flashctx *flash, uint8_t opcode);
void (*delay) (unsigned int usecs);
+ void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len);
+ void (*unmap_flash_region) (void *virt_addr, size_t len);
void *data;
};

@@ -413,6 +412,8 @@
enum flashrom_wp_result (*wp_write_cfg)(struct flashctx *, const struct flashrom_wp_cfg *);
enum flashrom_wp_result (*wp_read_cfg)(struct flashrom_wp_cfg *, struct flashctx *);
enum flashrom_wp_result (*wp_get_ranges)(struct flashrom_wp_ranges **, struct flashctx *);
+ void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len);
+ void (*unmap_flash_region) (void *virt_addr, size_t len);
int (*shutdown)(void *data);
void *data;
};
@@ -430,6 +431,8 @@
void (*chip_readn) (const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len);
int (*shutdown)(void *data);
void (*delay) (unsigned int usecs);
+ void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len);
+ void (*unmap_flash_region) (void *virt_addr, size_t len);
void *data;
};
int register_par_master(const struct par_master *mst, const enum chipbustype buses, void *data);
diff --git a/internal.c b/internal.c
index a20c539..cf719a4 100644
--- a/internal.c
+++ b/internal.c
@@ -115,6 +115,8 @@
.chip_writew = internal_chip_writew,
.chip_writel = internal_chip_writel,
.chip_writen = fallback_chip_writen,
+ .map_flash_region = physmap,
+ .unmap_flash_region = physunmap,
};

static int get_params(const struct programmer_cfg *cfg,
@@ -347,6 +349,4 @@
.type = OTHER,
.devs.note = NULL,
.init = internal_init,
- .map_flash_region = physmap,
- .unmap_flash_region = physunmap,
};
diff --git a/serprog.c b/serprog.c
index ee4a010..441b8a0 100644
--- a/serprog.c
+++ b/serprog.c
@@ -573,6 +573,21 @@
sp_prev_was_write = 0;
}

+static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
+{
+ /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits
+ * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that
+ * the hardware observes a subset of the address bits only). Combined with the standard mapping of
+ * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as
+ * needed for non-SPI chips). Below we make sure that the requested range is within this window. */
+ if ((phys_addr & 0xFF000000) == 0xFF000000) {
+ return (void*)phys_addr;
+ }
+ msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n",
+ descr, len, PRIxPTR_WIDTH, phys_addr);
+ return NULL;
+}
+
static const struct par_master par_master_serprog = {
.chip_readb = serprog_chip_readb,
.chip_readw = fallback_chip_readw,
@@ -583,6 +598,7 @@
.chip_writel = fallback_chip_writel,
.chip_writen = fallback_chip_writen,
.delay = serprog_delay,
+ .map_flash_region = serprog_map,
};

static enum chipbustype serprog_buses_supported = BUS_NONE;
@@ -946,26 +962,10 @@
return 1;
}

-static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
-{
- /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits
- * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that
- * the hardware observes a subset of the address bits only). Combined with the standard mapping of
- * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as
- * needed for non-SPI chips). Below we make sure that the requested range is within this window. */
- if ((phys_addr & 0xFF000000) == 0xFF000000) {
- return (void*)phys_addr;
- }
- msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n",
- descr, len, PRIxPTR_WIDTH, phys_addr);
- return NULL;
-}
-
const struct programmer_entry programmer_serprog = {
.name = "serprog",
.type = OTHER,
/* FIXME */
.devs.note = "All programmer devices speaking the serprog protocol\n",
.init = serprog_init,
- .map_flash_region = serprog_map,
};

To view, visit change 67478. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I9f011736681481c464946386b196c9ec2e9d7e29
Gerrit-Change-Number: 67478
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-MessageType: newchange