diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2016-04-28 16:05:10 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-04-28 16:08:38 +0200 |
commit | 854ba3f912400990615b3cf464f4b0c4c3b5ceb9 (patch) | |
tree | 88873af3ca18f66ac6b32a236db8dae9b4c724c1 /scripts | |
parent | 471893d0200cf4631bb820c7db793ba18998a5d2 (diff) | |
download | barebox-854ba3f912400990615b3cf464f4b0c4c3b5ceb9.tar.gz barebox-854ba3f912400990615b3cf464f4b0c4c3b5ceb9.tar.xz |
scripts: imx-usb-loader: support set_bits/clear_bits
Now that we can use set_bits/clear_bits in the DCD tables, add support
for this in the imx-usb-loader aswell.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/imx/imx-usb-loader.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 91151b859c..cf9d610823 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -412,7 +412,7 @@ int do_status(void) #define V(a) (((a) >> 24) & 0xff), (((a) >> 16) & 0xff), (((a) >> 8) & 0xff), ((a) & 0xff) -static int read_memory(unsigned addr, unsigned char *dest, unsigned cnt) +static int read_memory(unsigned addr, void *dest, unsigned cnt) { static unsigned char read_reg_command[] = { 1, @@ -559,6 +559,31 @@ static int write_memory(unsigned addr, unsigned val, int width) return err; } +static int modify_memory(unsigned addr, unsigned val, int width, int set_bits, int clear_bits) +{ + int err; + + if (set_bits || clear_bits) { + uint32_t r; + + err = read_memory(addr, &r, 4); + if (err < 0) + return err; + + if (verbose > 1) + printf("reg 0x%08x val: 0x%08x %s0x%08x\n", addr, r, + set_bits ? "|= " : "&= ~", val); + + if (set_bits) + r |= val; + if (clear_bits) + r &= ~val; + val = r; + } + + return write_memory(addr, val, 4); +} + static int load_file(void *buf, unsigned len, unsigned dladdr, unsigned char type) { static unsigned char dl_command[] = { @@ -685,15 +710,24 @@ static int write_dcd_table_ivt(struct imx_flash_header_v2 *hdr, unsigned char *f while (dcd < dcd_end) { unsigned s_length = (dcd[1] << 8) + dcd[2]; unsigned char *s_end = dcd + s_length; + int set_bits = 0, clear_bits = 0; printf("command: 0x%02x sub dcd length: 0x%04x, flags: 0x%02x\n", dcd[0], s_length, dcd[3]); - if ((dcd[0] != 0xcc) || (dcd[3] != 0x04)) { + if ((dcd[0] != 0xcc)) { printf("Skipping unknown sub tag 0x%02x with len %04x\n", dcd[0], s_length); usleep(50000); dcd += s_length; continue; } + + if (dcd[3] & PARAMETER_FLAG_MASK) { + if (dcd[3] & PARAMETER_FLAG_SET) + set_bits = 1; + else + clear_bits = 1; + } + dcd += 4; if (s_end > dcd_end) { @@ -706,9 +740,8 @@ static int write_dcd_table_ivt(struct imx_flash_header_v2 *hdr, unsigned char *f unsigned val = (dcd[4] << 24) | (dcd[5] << 16) | (dcd[6] << 8) | dcd[7]; dcd += 8; - err = write_memory(addr, val, 4); - if (err < 0) - return err; + + modify_memory(addr, val, 4, set_bits, clear_bits); } } return err; @@ -1209,7 +1242,7 @@ cleanup: static int write_mem(struct config_data *data, uint32_t addr, uint32_t val, int width, int set_bits, int clear_bits) { - return write_memory(addr, val, width); + return modify_memory(addr, val, width, set_bits, clear_bits); } static int parse_initfile(const char *filename) |