Make flash-size limiting of atapromise a general --force feature
To allow accessing at least part of flash chips behind this size-limited
controller, the `atapromise' driver used a local function that adjusted
a chip description. As flashprog would have bailed out earlier already,
this was only ever usable with the `--force' flag.
The same adjustment can be used with other programmers. Making it a glo-
bal feature also gets rid of a driver peculiarity and removes the depen-
dency on `flashctx` in the `atapromise' driver.
The logic enforces a complete chip erase if any erase is necessary. So,
while this should make part of the chip fully read/writable, content of
the inaccessible area will be lost on write.
Change-Id: I6bce8ff7781f683b001f76154621f22bd03687bc
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/431
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/helpers.c b/helpers.c
index b892c20..53fee54 100644
--- a/helpers.c
+++ b/helpers.c
@@ -18,7 +18,9 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+
#include "flash.h"
+#include "programmer.h"
/* Check if raw data is all 0 or all 1. */
bool flashprog_no_data(const void *const raw_data, const size_t len)
@@ -59,6 +61,43 @@
return 0;
}
+int flashprog_limit_chip(struct flashctx *flash)
+{
+ const chipsize_t limit = flash->mst.common->max_rom_decode;
+ struct flashchip *const chip = flash->chip;
+ const chipsize_t chip_size = chip->total_size * 1024;
+ unsigned int usable_erasers = 0;
+ unsigned int i;
+
+
+ /* Chip is small enough or already limited. */
+ if (chip_size <= limit)
+ return 0;
+
+ /* Undefine all block_erasers that don't operate on the whole chip,
+ and adjust the eraseblock size of those which do. */
+ for (i = 0; i < NUM_ERASEFUNCTIONS; ++i) {
+ if (chip->block_erasers[i].eraseblocks[0].size != chip_size) {
+ chip->block_erasers[i].eraseblocks[0].count = 0;
+ chip->block_erasers[i].block_erase = NULL;
+ } else {
+ chip->block_erasers[i].eraseblocks[0].size = limit;
+ usable_erasers++;
+ }
+ }
+
+ if (usable_erasers) {
+ chip->total_size = limit / 1024;
+ if (chip->page_size > limit)
+ chip->page_size = limit;
+ return 0;
+ } else {
+ msg_pdbg("Failed to adjust size of chip \"%s\" (%d kB).\n",
+ chip->name, chip->total_size);
+ return -1;
+ }
+}
+
/* Returns the minimum number of bits needed to represent the given address.
* FIXME: use mind-blowing implementation. */
uint32_t address_to_bits(uint32_t addr)