From: Øyvind H. <go...@us...> - 2010-05-16 13:42:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 76b81682eeea804518cf69c4d916ccc78c2f3093 (commit) via 602685e66f163f26179f41215cf302b0a894803e (commit) via bc8be110ff314cab0e09792a05b6871672c18302 (commit) via 24ebfffff54f5201f1503256df56717900e65e2d (commit) via feb95fbb7b1af02bf62a7b06ce2fcfb972d41040 (commit) via ebdd3a1670b8561e238f5c16245cefefd56b6f71 (commit) via 34f70956ed31c2739d34bae23fa6ca620e5299f8 (commit) via a69cbf0f74015993d749bdfe1a80f4b5a8bb6dc3 (commit) via 61bb0d3d235c659eb407a7032aa9ec70a914dc03 (commit) via 89747f81f22084b255f35d92f709facd3b4553a1 (commit) via c7b269ace1bbe07d5db7a562bb9242f4be32be67 (commit) from b8c54b362b395e50baf749366f6ec9e29fcba27e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 76b81682eeea804518cf69c4d916ccc78c2f3093 Author: Antonio Borneo <bor...@gm...> Date: Tue May 11 11:48:09 2010 +0800 NOR/CFI: minor code cleanup Remove few LOG_DEBUG() messages, together with code and variables required to build such messages. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 72c95dd..b19b945 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -805,8 +805,6 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - struct target *target = bank->target; /* FIXME: to be removed */ - uint8_t command[CFI_MAX_BUS_WIDTH]; /* FIXME: to be removed */ int retry = 0; int i; @@ -820,16 +818,12 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la for (i = first; i <= last; i++) { - cfi_command(bank, 0x60, command); /* FIXME: to be removed */ - LOG_DEBUG("address: 0x%4.4" PRIx32 ", command: 0x%4.4" PRIx32, flash_address(bank, i, 0x0), target_buffer_get_u32(target, command)); if ((retval = cfi_send_command(bank, 0x60, flash_address(bank, i, 0x0))) != ERROR_OK) { return retval; } if (set) { - cfi_command(bank, 0x01, command); /* FIXME: to be removed */ - LOG_DEBUG("address: 0x%4.4" PRIx32 ", command: 0x%4.4" PRIx32 , flash_address(bank, i, 0x0), target_buffer_get_u32(target, command)); if ((retval = cfi_send_command(bank, 0x01, flash_address(bank, i, 0x0))) != ERROR_OK) { return retval; @@ -838,8 +832,6 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la } else { - cfi_command(bank, 0xd0, command); /* FIXME: to be removed */ - LOG_DEBUG("address: 0x%4.4" PRIx32 ", command: 0x%4.4" PRIx32, flash_address(bank, i, 0x0), target_buffer_get_u32(target, command)); if ((retval = cfi_send_command(bank, 0xd0, flash_address(bank, i, 0x0))) != ERROR_OK) { return retval; commit 602685e66f163f26179f41215cf302b0a894803e Author: Antonio Borneo <bor...@gm...> Date: Tue May 11 11:35:28 2010 +0800 NOR/CFI: add cfi_read() implementation Final step to force bus_width size during CFI flash read. Added CFI specific implementation cfi_read() that uses only accesses at bus_width size. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 1b080ac..72c95dd 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -4,6 +4,7 @@ * Copyright (C) 2009 Michael Schwingen * * mi...@sc... * * Copyright (C) 2010 Ãyvind Harboe <oyv...@zy...> * + * Copyright (C) 2010 by Antonio Borneo <bor...@gm...> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -1799,6 +1800,76 @@ static int cfi_write_words(struct flash_bank *bank, uint8_t *word, uint32_t word return ERROR_FLASH_OPERATION_FAILED; } +static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +{ + struct cfi_flash_bank *cfi_info = bank->driver_priv; + struct target *target = bank->target; + uint32_t address = bank->base + offset; + uint32_t read_p; + int align; /* number of unaligned bytes */ + uint8_t current_word[CFI_MAX_BUS_WIDTH]; + int i; + int retval; + + LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", + (int)count, (unsigned)offset); + + if (bank->target->state != TARGET_HALTED) + { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) + return ERROR_FLASH_DST_OUT_OF_BANK; + + if (cfi_info->qry[0] != 'Q') + return ERROR_FLASH_BANK_NOT_PROBED; + + /* start at the first byte of the first word (bus_width size) */ + read_p = address & ~(bank->bus_width - 1); + if ((align = address - read_p) != 0) + { + LOG_INFO("Fixup %d unaligned read head bytes", align); + + /* read a complete word from flash */ + if ((retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word)) != ERROR_OK) + return retval; + + /* take only bytes we need */ + for (i = align; (i < bank->bus_width) && (count > 0); i++, count--) + *buffer++ = current_word[i]; + + read_p += bank->bus_width; + } + + align = count / bank->bus_width; + if (align) + { + if ((retval = target_read_memory(target, read_p, bank->bus_width, align, buffer)) != ERROR_OK) + return retval; + + read_p += align * bank->bus_width; + buffer += align * bank->bus_width; + count -= align * bank->bus_width; + } + + if (count) + { + LOG_INFO("Fixup %d unaligned read tail bytes", count); + + /* read a complete word from flash */ + if ((retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word)) != ERROR_OK) + return retval; + + /* take only bytes we need */ + for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) + *buffer++ = current_word[i]; + } + + return ERROR_OK; +} + static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -2467,8 +2538,7 @@ struct flash_driver cfi_flash = { .erase = cfi_erase, .protect = cfi_protect, .write = cfi_write, - /* FIXME: access flash at bus_width size */ - .read = default_flash_read, + .read = cfi_read, .probe = cfi_probe, .auto_probe = cfi_auto_probe, /* FIXME: access flash at bus_width size */ commit bc8be110ff314cab0e09792a05b6871672c18302 Author: Antonio Borneo <bor...@gm...> Date: Tue May 11 11:16:33 2010 +0800 NOR: add read() callback to struct flash_driver Final target is to force bus_width size during CFI flash read. In this first step I need to replace default flash read with flash specific implementation. This patch introduces: - flash_driver_read() layer; - default_flash_read(), backward compatible; - read() callback in struct flash_driver; - proper initialization in every flash_driver instance. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c index 82ea2bc..40ee321 100644 --- a/src/flash/nor/aduc702x.c +++ b/src/flash/nor/aduc702x.c @@ -417,6 +417,7 @@ struct flash_driver aduc702x_flash = { .erase = aduc702x_erase, .protect = aduc702x_protect, .write = aduc702x_write, + .read = default_flash_read, .probe = aduc702x_probe, .auto_probe = aduc702x_probe, .erase_check = default_flash_blank_check, diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 5f013ed..06b84cd 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -2505,6 +2505,7 @@ struct flash_driver at91sam3_flash = { .erase = sam3_erase, .protect = sam3_protect, .write = sam3_write, + .read = default_flash_read, .probe = sam3_probe, .auto_probe = sam3_auto_probe, .erase_check = sam3_erase_check, diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c index cca0cf2..606cc32 100644 --- a/src/flash/nor/at91sam7.c +++ b/src/flash/nor/at91sam7.c @@ -1207,6 +1207,7 @@ struct flash_driver at91sam7_flash = { .erase = at91sam7_erase, .protect = at91sam7_protect, .write = at91sam7_write, + .read = default_flash_read, .probe = at91sam7_probe, .auto_probe = at91sam7_probe, .erase_check = at91sam7_erase_check, diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index 15b8b27..7cdab51 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -497,6 +497,7 @@ struct flash_driver avr_flash = { .erase = avrf_erase, .protect = avrf_protect, .write = avrf_write, + .read = default_flash_read, .probe = avrf_probe, .auto_probe = avrf_auto_probe, .erase_check = default_flash_mem_blank_check, diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 94ff7b9..1b080ac 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -2467,6 +2467,8 @@ struct flash_driver cfi_flash = { .erase = cfi_erase, .protect = cfi_protect, .write = cfi_write, + /* FIXME: access flash at bus_width size */ + .read = default_flash_read, .probe = cfi_probe, .auto_probe = cfi_auto_probe, /* FIXME: access flash at bus_width size */ diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index 936f07c..00f73f2 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -3,6 +3,7 @@ * Copyright (C) 2007-2010 Ãyvind Harboe <oyv...@zy...> * * Copyright (C) 2008 by Spencer Oliver <sp...@sp...> * * Copyright (C) 2009 Zachary T Welch <zw...@su...> * + * Copyright (C) 2010 by Antonio Borneo <bor...@gm...> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -100,6 +101,29 @@ int flash_driver_write(struct flash_bank *bank, return retval; } +int flash_driver_read(struct flash_bank *bank, + uint8_t *buffer, uint32_t offset, uint32_t count) +{ + int retval; + + LOG_DEBUG("call flash_driver_read()"); + + retval = bank->driver->read(bank, buffer, offset, count); + if (retval != ERROR_OK) + { + LOG_ERROR("error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)", + bank->base, offset, retval); + } + + return retval; +} + +int default_flash_read(struct flash_bank *bank, + uint8_t *buffer, uint32_t offset, uint32_t count) +{ + return target_read_buffer(bank->target, offset + bank->base, count, buffer); +} + void flash_bank_add(struct flash_bank *bank) { /* put flash bank in linked list */ diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 1dfd721..a35f64f 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -3,6 +3,7 @@ * Copyright (C) 2007,2008 Ãyvind Harboe <oyv...@zy...> * * Copyright (C) 2008 by Spencer Oliver <sp...@sp...> * * Copyright (C) 2009 Zachary T Welch <zw...@su...> * + * Copyright (C) 2010 by Antonio Borneo <bor...@gm...> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -136,6 +137,16 @@ void flash_set_dirty(void); /// @returns The number of flash banks currently defined. int flash_get_bank_count(void); /** + * Provides default read implementation for flash memory. + * @param bank The bank to read. + * @param buffer The data bytes read. + * @param offset The offset into the chip to read. + * @param count The number of bytes to read. + * @returns ERROR_OK if successful; otherwise, an error code. + */ +int default_flash_read(struct flash_bank *bank, + uint8_t *buffer, uint32_t offset, uint32_t count); +/** * Provides default erased-bank check handling. Checks to see if * the flash driver knows they are erased; if things look uncertain, * this routine will call default_flash_mem_blank_check() to confirm. diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 0e77132..3757442 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -3,6 +3,7 @@ * Copyright (C) 2007,2008 Ãyvind Harboe <oyv...@zy...> * * Copyright (C) 2008 by Spencer Oliver <sp...@sp...> * * Copyright (C) 2009 Zachary T Welch <zw...@su...> * + * Copyright (C) 2010 by Antonio Borneo <bor...@gm...> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -131,6 +132,20 @@ struct flash_driver uint8_t *buffer, uint32_t offset, uint32_t count); /** + * Read data from the flash. Note CPU address will be + * "bank->base + offset", while the physical address is + * dependent upon current target MMU mappings. + * + * @param bank The bank to read. + * @param buffer The data bytes read. + * @param offset The offset into the chip to read. + * @param count The number of bytes to read. + * @returns ERROR_OK if successful; otherwise, an error code. + */ + int (*read)(struct flash_bank *bank, + uint8_t *buffer, uint32_t offset, uint32_t count); + + /** * Probe to determine what kind of flash is present. * This is invoked by the "probe" script command. * diff --git a/src/flash/nor/ecos.c b/src/flash/nor/ecos.c index 783a40c..f9c3285 100644 --- a/src/flash/nor/ecos.c +++ b/src/flash/nor/ecos.c @@ -436,6 +436,7 @@ struct flash_driver ecosflash_flash = { .erase = ecosflash_erase, .protect = ecosflash_protect, .write = ecosflash_write, + .read = default_flash_read, .probe = ecosflash_probe, .auto_probe = ecosflash_probe, .erase_check = default_flash_blank_check, diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c index e1e77ea..92851ed 100644 --- a/src/flash/nor/faux.c +++ b/src/flash/nor/faux.c @@ -141,6 +141,7 @@ struct flash_driver faux_flash = { .erase = faux_erase, .protect = faux_protect, .write = faux_write, + .read = default_flash_read, .probe = faux_probe, .auto_probe = faux_probe, .erase_check = default_flash_blank_check, diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h index 34ccbe4..de1bc9e 100644 --- a/src/flash/nor/imp.h +++ b/src/flash/nor/imp.h @@ -40,6 +40,8 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last); int flash_driver_protect(struct flash_bank *bank, int set, int first, int last); int flash_driver_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count); +int flash_driver_read(struct flash_bank *bank, + uint8_t *buffer, uint32_t offset, uint32_t count); /* write (optional verify) an image to flash memory of the given target */ int flash_write_unlock(struct target *target, struct image *image, diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 438ab54..154248c 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -814,6 +814,7 @@ struct flash_driver lpc2000_flash = { .erase = lpc2000_erase, .protect = lpc2000_protect, .write = lpc2000_write, + .read = default_flash_read, .probe = lpc2000_probe, .auto_probe = lpc2000_probe, .erase_check = lpc2000_erase_check, diff --git a/src/flash/nor/lpc288x.c b/src/flash/nor/lpc288x.c index 5ab4e9c..b6d207e 100644 --- a/src/flash/nor/lpc288x.c +++ b/src/flash/nor/lpc288x.c @@ -478,6 +478,7 @@ struct flash_driver lpc288x_flash = { .erase = lpc288x_erase, .protect = lpc288x_protect, .write = lpc288x_write, + .read = default_flash_read, .probe = lpc288x_probe, .auto_probe = lpc288x_probe, .erase_check = lpc288x_erase_check, diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c index 5b00495..3ae7bb4 100644 --- a/src/flash/nor/lpc2900.c +++ b/src/flash/nor/lpc2900.c @@ -1830,6 +1830,7 @@ struct flash_driver lpc2900_flash = .erase = lpc2900_erase, .protect = lpc2900_protect, .write = lpc2900_write, + .read = default_flash_read, .probe = lpc2900_probe, .auto_probe = lpc2900_probe, .erase_check = lpc2900_erase_check, diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c index 5d93724..9a295eb 100644 --- a/src/flash/nor/ocl.c +++ b/src/flash/nor/ocl.c @@ -353,6 +353,7 @@ struct flash_driver ocl_flash = { .erase = ocl_erase, .protect = ocl_protect, .write = ocl_write, + .read = default_flash_read, .probe = ocl_probe, .erase_check = ocl_erase_check, .protect_check = ocl_protect_check, diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index 4ebd256..58009ae 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -766,6 +766,7 @@ struct flash_driver pic32mx_flash = { .erase = pic32mx_erase, .protect = pic32mx_protect, .write = pic32mx_write, + .read = default_flash_read, .probe = pic32mx_probe, .auto_probe = pic32mx_auto_probe, .erase_check = default_flash_mem_blank_check, diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index cce5f37..38374ff 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -1261,6 +1261,7 @@ struct flash_driver stellaris_flash = { .erase = stellaris_erase, .protect = stellaris_protect, .write = stellaris_write, + .read = default_flash_read, .probe = stellaris_probe, .auto_probe = stellaris_probe, .erase_check = default_flash_mem_blank_check, diff --git a/src/flash/nor/stm32x.c b/src/flash/nor/stm32x.c index 7afd959..d11a8ed 100644 --- a/src/flash/nor/stm32x.c +++ b/src/flash/nor/stm32x.c @@ -1293,6 +1293,7 @@ struct flash_driver stm32x_flash = { .erase = stm32x_erase, .protect = stm32x_protect, .write = stm32x_write, + .read = default_flash_read, .probe = stm32x_probe, .auto_probe = stm32x_auto_probe, .erase_check = default_flash_mem_blank_check, diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c index 3d52341..46510ed 100644 --- a/src/flash/nor/str7x.c +++ b/src/flash/nor/str7x.c @@ -790,6 +790,7 @@ struct flash_driver str7x_flash = { .erase = str7x_erase, .protect = str7x_protect, .write = str7x_write, + .read = default_flash_read, .probe = str7x_probe, .auto_probe = str7x_probe, .erase_check = default_flash_blank_check, diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c index 2208fe3..e8e942e 100644 --- a/src/flash/nor/str9x.c +++ b/src/flash/nor/str9x.c @@ -701,6 +701,7 @@ struct flash_driver str9x_flash = { .erase = str9x_erase, .protect = str9x_protect, .write = str9x_write, + .read = default_flash_read, .probe = str9x_probe, .auto_probe = str9x_probe, .erase_check = default_flash_blank_check, diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c index 861d70b..073dfe1 100644 --- a/src/flash/nor/str9xpec.c +++ b/src/flash/nor/str9xpec.c @@ -1247,6 +1247,7 @@ struct flash_driver str9xpec_flash = { .erase = str9xpec_erase, .protect = str9xpec_protect, .write = str9xpec_write, + .read = default_flash_read, .probe = str9xpec_probe, .auto_probe = str9xpec_probe, .erase_check = str9xpec_erase_check, diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index ad21812..af655c6 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -559,7 +559,7 @@ COMMAND_HANDLER(handle_flash_fill_command) goto done; } - err = target_read_buffer(target, address + wrote, cur_size, readback); + err = flash_driver_read(bank, readback, address - bank->base + wrote, cur_size); if (err != ERROR_OK) { retval = err; diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c index edb43af..c1681f1 100644 --- a/src/flash/nor/tms470.c +++ b/src/flash/nor/tms470.c @@ -1264,6 +1264,7 @@ struct flash_driver tms470_flash = { .erase = tms470_erase, .protect = tms470_protect, .write = tms470_write, + .read = default_flash_read, .probe = tms470_probe, .auto_probe = tms470_auto_probe, .erase_check = tms470_erase_check, commit 24ebfffff54f5201f1503256df56717900e65e2d Author: Antonio Borneo <bor...@gm...> Date: Mon May 10 17:07:28 2010 +0800 NOR/TCL: fix typo in error message Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index a6e942e..ad21812 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -571,7 +571,7 @@ COMMAND_HANDLER(handle_flash_fill_command) { if (readback[i]!=chunk[i]) { - LOG_ERROR("Verfication error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x", + LOG_ERROR("Verification error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x", address + wrote + i, readback[i], chunk[i]); retval = ERROR_FAIL; goto done; commit feb95fbb7b1af02bf62a7b06ce2fcfb972d41040 Author: Antonio Borneo <bor...@gm...> Date: Fri May 7 17:04:32 2010 +0800 NOR: fix comment for Doxygen Either bus_width and chip_width are in bytes. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index de71a39..0e77132 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -75,11 +75,12 @@ struct flash_driver * CMD_ARGV[2] = baseaddress * CMD_ARGV[3] = lengthbytes * CMD_ARGV[4] = chip_width_in bytes - * CMD_ARGV[5] = bus_width_bytes + * CMD_ARGV[5] = bus_width_in_bytes * CMD_ARGV[6] = driver-specific parameters * @endcode * - * For example, CMD_ARGV[4] = 16 bit flash, CMD_ARGV[5] = 32bit bus. + * For example, CMD_ARGV[4] = 2 (for 16 bit flash), + * CMD_ARGV[5] = 4 (for 32 bit bus). * * If extra arguments are provided (@a CMD_ARGC > 6), they will * start in @a CMD_ARGV[6]. These can be used to implement commit ebdd3a1670b8561e238f5c16245cefefd56b6f71 Author: Antonio Borneo <bor...@gm...> Date: Fri May 7 14:03:39 2010 +0800 NOR/CFI: remove use of cfi_add_byte() Remove the function cfi_add_byte() and rewrite the only instance of it. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index b2d184d..94ff7b9 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -953,40 +953,6 @@ static int cfi_protect(struct flash_bank *bank, int set, int first, int last) } } -/* FIXME Replace this by a simple memcpy() - still unsure about sideeffects */ -static void cfi_add_byte(struct flash_bank *bank, uint8_t *word, uint8_t byte) -{ - /* struct target *target = bank->target; */ - - int i; - - /* NOTE: - * The data to flash must not be changed in endian! We write a bytestrem in - * target byte order already. Only the control and status byte lane of the flash - * WSM is interpreted by the CPU in different ways, when read a uint16_t or uint32_t - * word (data seems to be in the upper or lower byte lane for uint16_t accesses). - */ - -#if 0 - if (target->endianness == TARGET_LITTLE_ENDIAN) - { -#endif - /* shift bytes */ - for (i = 0; i < bank->bus_width - 1; i++) - word[i] = word[i + 1]; - word[bank->bus_width - 1] = byte; -#if 0 - } - else - { - /* shift bytes */ - for (i = bank->bus_width - 1; i > 0; i--) - word[i] = word[i - 1]; - word[0] = byte; - } -#endif -} - /* Convert code image to target endian */ /* FIXME create general block conversion fcts in target.c?) */ static void cfi_fix_code_endian(struct target *target, uint8_t *dest, const uint32_t *src, uint32_t count) @@ -1936,12 +1902,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, if (fallback) { for (i = 0; i < bank->bus_width; i++) - current_word[i] = 0; - - for (i = 0; i < bank->bus_width; i++) - { - cfi_add_byte(bank, current_word, *buffer++); - } + current_word[i] = *buffer++; retval = cfi_write_word(bank, current_word, write_p); if (retval != ERROR_OK) commit 34f70956ed31c2739d34bae23fa6ca620e5299f8 Author: Antonio Borneo <bor...@gm...> Date: Fri May 7 13:50:42 2010 +0800 NOR/CFI: use bus_width for memory access in cfi_write() During cfi_write(), head and tail of destination area could be not aligned to bus_width. Since write operation must be at bus_width size, source buffer size is extended and buffer padded with current values read from flash. Force using bus_width to read current value from flash. Do not use cfi_add_byte() anymore, to allow removing this function later on. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index a6165c6..b2d184d 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -1838,7 +1838,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, struct cfi_flash_bank *cfi_info = bank->driver_priv; struct target *target = bank->target; uint32_t address = bank->base + offset; /* address of first byte to be programmed */ - uint32_t write_p, copy_p; + uint32_t write_p; int align; /* number of unaligned bytes */ int blk_count; /* number of bus_width bytes for block copy */ uint8_t current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being programmed */ @@ -1863,46 +1863,18 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, { LOG_INFO("Fixup %d unaligned head bytes", align); - for (i = 0; i < bank->bus_width; i++) - current_word[i] = 0; - copy_p = write_p; - - /* copy bytes before the first write address */ - for (i = 0; i < align; ++i, ++copy_p) - { - uint8_t byte; - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) - { - return retval; - } - cfi_add_byte(bank, current_word, byte); - } - - /* add bytes from the buffer */ - for (; (i < bank->bus_width) && (count > 0); i++) - { - cfi_add_byte(bank, current_word, *buffer++); - count--; - copy_p++; - } + /* read a complete word from flash */ + if ((retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word)) != ERROR_OK) + return retval; - /* if the buffer is already finished, copy bytes after the last write address */ - for (; (count == 0) && (i < bank->bus_width); ++i, ++copy_p) - { - uint8_t byte; - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) - { - return retval; - } - cfi_add_byte(bank, current_word, byte); - } + /* replace only bytes that must be written */ + for (i = align; (i < bank->bus_width) && (count > 0); i++, count--) + current_word[i] = *buffer++; retval = cfi_write_word(bank, current_word, write_p); if (retval != ERROR_OK) return retval; - write_p = copy_p; + write_p += bank->bus_width; } /* handle blocks of bus_size aligned bytes */ @@ -1995,25 +1967,14 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, { LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); - copy_p = write_p; - for (i = 0; i < bank->bus_width; i++) - current_word[i] = 0; + /* read a complete word from flash */ + if ((retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word)) != ERROR_OK) + return retval; + + /* replace only bytes that must be written */ + for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) + current_word[i] = *buffer++; - for (i = 0; (i < bank->bus_width) && (count > 0); ++i, ++copy_p) - { - cfi_add_byte(bank, current_word, *buffer++); - count--; - } - for (; i < bank->bus_width; ++i, ++copy_p) - { - uint8_t byte; - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) - { - return retval; - } - cfi_add_byte(bank, current_word, byte); - } retval = cfi_write_word(bank, current_word, write_p); if (retval != ERROR_OK) return retval; commit a69cbf0f74015993d749bdfe1a80f4b5a8bb6dc3 Author: Antonio Borneo <bor...@gm...> Date: Fri Apr 23 12:07:53 2010 +0800 NOR/CFI: use bus_width for memory access on flash ID. NOR flash structure requires each access to be bus_width wide. Fix read of flash ID accordingly to rule above. Add case (chip_width == 4), allowed by CFI spec and coherent with current value of CFI_MAX_CHIP_WIDTH but currently not used by any target. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index ca2fb0b..a6165c6 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -2105,6 +2105,7 @@ static int cfi_probe(struct flash_bank *bank) uint32_t unlock1 = 0x555; uint32_t unlock2 = 0x2aa; int retval; + uint8_t value_buf0[CFI_MAX_BUS_WIDTH], value_buf1[CFI_MAX_BUS_WIDTH]; if (bank->target->state != TARGET_HALTED) { @@ -2137,34 +2138,30 @@ static int cfi_probe(struct flash_bank *bank) return retval; } - if (bank->chip_width == 1) + if ((retval = target_read_memory(target, flash_address(bank, 0, 0x00), bank->bus_width, 1, value_buf0)) != ERROR_OK) { - uint8_t manufacturer, device_id; - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_u8(target, flash_address(bank, 0, 0x00), &manufacturer)) != ERROR_OK) - { - return retval; - } - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_u8(target, flash_address(bank, 0, 0x01), &device_id)) != ERROR_OK) - { - return retval; - } - cfi_info->manufacturer = manufacturer; - cfi_info->device_id = device_id; + return retval; } - else if (bank->chip_width == 2) + if ((retval = target_read_memory(target, flash_address(bank, 0, 0x01), bank->bus_width, 1, value_buf1)) != ERROR_OK) { - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_u16(target, flash_address(bank, 0, 0x00), &cfi_info->manufacturer)) != ERROR_OK) - { - return retval; - } - /* FIXME: access flash at bus_width size */ - if ((retval = target_read_u16(target, flash_address(bank, 0, 0x01), &cfi_info->device_id)) != ERROR_OK) - { - return retval; - } + return retval; + } + switch (bank->chip_width) { + case 1: + cfi_info->manufacturer = *value_buf0; + cfi_info->device_id = *value_buf1; + break; + case 2: + cfi_info->manufacturer = target_buffer_get_u16(target, value_buf0); + cfi_info->device_id = target_buffer_get_u16(target, value_buf1); + break; + case 4: + cfi_info->manufacturer = target_buffer_get_u32(target, value_buf0); + cfi_info->device_id = target_buffer_get_u32(target, value_buf1); + break; + default: + LOG_ERROR("Unsupported bank chipwidth %d, can't probe memory", bank->chip_width); + return ERROR_FLASH_OPERATION_FAILED; } LOG_INFO("Flash Manufacturer/Device: 0x%04x 0x%04x", cfi_info->manufacturer, cfi_info->device_id); commit 61bb0d3d235c659eb407a7032aa9ec70a914dc03 Author: Antonio Borneo <bor...@gm...> Date: Tue Apr 20 12:15:49 2010 +0800 NOR/CFI: identify memory accesses not using "bus_width". Since NOR flash devices does not handle "byte enable lanes", each read/write access involves the whole "chip_width". When multiple devices are in parallel, usually all chips are enabled during each access. All such cases are compatible with flash accesses at "bus_width" size. Access at "bus_width" size is mandatory for write access to avoid transferring of garbage values to flash. During read access the flash controller should take care, and discard unneeded bytes. Anyway, it is good practice to use "bus_width" size also for read. Every memory access that does not respect "bus_width" size is marked with a "FIXME" comment. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index f2ea947..ca2fb0b 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -1871,6 +1871,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, for (i = 0; i < align; ++i, ++copy_p) { uint8_t byte; + /* FIXME: access flash at bus_width size */ if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) { return retval; @@ -1890,6 +1891,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, for (; (count == 0) && (i < bank->bus_width); ++i, ++copy_p) { uint8_t byte; + /* FIXME: access flash at bus_width size */ if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) { return retval; @@ -2005,6 +2007,7 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, for (; i < bank->bus_width; ++i, ++copy_p) { uint8_t byte; + /* FIXME: access flash at bus_width size */ if ((retval = target_read_memory(target, copy_p, 1, 1, &byte)) != ERROR_OK) { return retval; @@ -2137,10 +2140,12 @@ static int cfi_probe(struct flash_bank *bank) if (bank->chip_width == 1) { uint8_t manufacturer, device_id; + /* FIXME: access flash at bus_width size */ if ((retval = target_read_u8(target, flash_address(bank, 0, 0x00), &manufacturer)) != ERROR_OK) { return retval; } + /* FIXME: access flash at bus_width size */ if ((retval = target_read_u8(target, flash_address(bank, 0, 0x01), &device_id)) != ERROR_OK) { return retval; @@ -2150,10 +2155,12 @@ static int cfi_probe(struct flash_bank *bank) } else if (bank->chip_width == 2) { + /* FIXME: access flash at bus_width size */ if ((retval = target_read_u16(target, flash_address(bank, 0, 0x00), &cfi_info->manufacturer)) != ERROR_OK) { return retval; } + /* FIXME: access flash at bus_width size */ if ((retval = target_read_u16(target, flash_address(bank, 0, 0x01), &cfi_info->device_id)) != ERROR_OK) { return retval; @@ -2543,6 +2550,7 @@ struct flash_driver cfi_flash = { .write = cfi_write, .probe = cfi_probe, .auto_probe = cfi_auto_probe, + /* FIXME: access flash at bus_width size */ .erase_check = default_flash_blank_check, .protect_check = cfi_protect_check, .info = cfi_info, commit 89747f81f22084b255f35d92f709facd3b4553a1 Author: Antonio Borneo <bor...@gm...> Date: Mon Apr 19 16:40:08 2010 +0800 NOR/CFI: simplify bufferwsize computation Review and simplify computation of bufferwsize. Add comments about variables' meaning. The same code is present 3 times in the file. Current patch updates all the 3 instances. Step 1) Replace "switch(bank->chip_width) {...}". Illegal values of bank->chip_width are already dropped. For legal values, the code is equivalent to: bufferwsize = buffersize / bank->chip_width; Step 2) The above code replacement plus the following line: bufferwsize /= (bank->bus_width / bank->chip_width); is merged in a single formula: bufferwsize = (buffersize / bank->chip_width) / (bank->bus_width / bank->chip_width); and simplified as: bufferwsize = buffersize / bank->bus_width; Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index ba2d909..f2ea947 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -1604,9 +1604,11 @@ static int cfi_intel_write_words(struct flash_bank *bank, uint8_t *word, uint32_ struct target *target = bank->target; /* Calculate buffer size and boundary mask */ + /* buffersize is (buffer size per chip) * (number of chips) */ + /* bufferwsize is buffersize in words */ uint32_t buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width); uint32_t buffermask = buffersize-1; - uint32_t bufferwsize; + uint32_t bufferwsize = buffersize / bank->bus_width; /* Check for valid range */ if (address & buffermask) @@ -1615,18 +1617,6 @@ static int cfi_intel_write_words(struct flash_bank *bank, uint8_t *word, uint32_ bank->base, address, cfi_info->max_buf_write_size); return ERROR_FLASH_OPERATION_FAILED; } - switch (bank->chip_width) - { - case 4 : bufferwsize = buffersize / 4; break; - case 2 : bufferwsize = buffersize / 2; break; - case 1 : bufferwsize = buffersize; break; - default: - LOG_ERROR("Unsupported chip width %d", bank->chip_width); - return ERROR_FLASH_OPERATION_FAILED; - } - - bufferwsize/=(bank->bus_width / bank->chip_width); - /* Check for valid size */ if (wordcount > bufferwsize) @@ -1733,9 +1723,11 @@ static int cfi_spansion_write_words(struct flash_bank *bank, uint8_t *word, uint struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; /* Calculate buffer size and boundary mask */ + /* buffersize is (buffer size per chip) * (number of chips) */ + /* bufferwsize is buffersize in words */ uint32_t buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width); uint32_t buffermask = buffersize-1; - uint32_t bufferwsize; + uint32_t bufferwsize = buffersize / bank->bus_width; /* Check for valid range */ if (address & buffermask) @@ -1743,17 +1735,6 @@ static int cfi_spansion_write_words(struct flash_bank *bank, uint8_t *word, uint LOG_ERROR("Write address at base 0x%" PRIx32 ", address %" PRIx32 " not aligned to 2^%d boundary", bank->base, address, cfi_info->max_buf_write_size); return ERROR_FLASH_OPERATION_FAILED; } - switch (bank->chip_width) - { - case 4 : bufferwsize = buffersize / 4; break; - case 2 : bufferwsize = buffersize / 2; break; - case 1 : bufferwsize = buffersize; break; - default: - LOG_ERROR("Unsupported chip width %d", bank->chip_width); - return ERROR_FLASH_OPERATION_FAILED; - } - - bufferwsize/=(bank->bus_width / bank->chip_width); /* Check for valid size */ if (wordcount > bufferwsize) @@ -1950,22 +1931,12 @@ static int cfi_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, { if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - //adjust buffersize for chip width + /* Calculate buffer size and boundary mask */ + /* buffersize is (buffer size per chip) * (number of chips) */ + /* bufferwsize is buffersize in words */ uint32_t buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width); uint32_t buffermask = buffersize-1; - uint32_t bufferwsize; - - switch (bank->chip_width) - { - case 4 : bufferwsize = buffersize / 4; break; - case 2 : bufferwsize = buffersize / 2; break; - case 1 : bufferwsize = buffersize; break; - default: - LOG_ERROR("Unsupported chip width %d", bank->chip_width); - return ERROR_FLASH_OPERATION_FAILED; - } - - bufferwsize/=(bank->bus_width / bank->chip_width); + uint32_t bufferwsize = buffersize / bank->bus_width; /* fall back to memory writes */ while (count >= (uint32_t)bank->bus_width) commit c7b269ace1bbe07d5db7a562bb9242f4be32be67 Author: Antonio Borneo <bor...@gm...> Date: Fri Apr 16 01:17:01 2010 +0800 NOR/CFI: check "flash bank" command arguments Arguments chip_width and bus_width of command "flash bank" are not fully checked. While bus_width is later on redundantly checked in several other parts (e.g. in cfi_command_val()) and generates run-time error, chip_width is never checked, nor related to actual bus_width value. Added check to avoid: - (chip_width == 0), that would mean no memory chip at all, avoiding also division by zero e.g. in cfi_get_u8(); - (bus_width == 0), that would mean no bus at all; - unsupported cases of chip_width or bus_width value not power of 2; - unsupported case of chip width wider than bus. Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 2235c85..ba2d909 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -624,8 +624,18 @@ FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command) return ERROR_FLASH_BANK_INVALID; } + /* both widths must: + * - not exceed max value; + * - not be null; + * - be equal to a power of 2. + * bus must be wide enought to hold one chip */ if ((bank->chip_width > CFI_MAX_CHIP_WIDTH) - || (bank->bus_width > CFI_MAX_BUS_WIDTH)) + || (bank->bus_width > CFI_MAX_BUS_WIDTH) + || (bank->chip_width == 0) + || (bank->bus_width == 0) + || (bank->chip_width & (bank->chip_width - 1)) + || (bank->bus_width & (bank->bus_width - 1)) + || (bank->chip_width > bank->bus_width)) { LOG_ERROR("chip and bus width have to specified in bytes"); return ERROR_FLASH_BANK_INVALID; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/aduc702x.c | 1 + src/flash/nor/at91sam3.c | 1 + src/flash/nor/at91sam7.c | 1 + src/flash/nor/avrf.c | 1 + src/flash/nor/cfi.c | 292 ++++++++++++++++++++------------------------- src/flash/nor/core.c | 24 ++++ src/flash/nor/core.h | 11 ++ src/flash/nor/driver.h | 20 +++- src/flash/nor/ecos.c | 1 + src/flash/nor/faux.c | 1 + src/flash/nor/imp.h | 2 + src/flash/nor/lpc2000.c | 1 + src/flash/nor/lpc288x.c | 1 + src/flash/nor/lpc2900.c | 1 + src/flash/nor/ocl.c | 1 + src/flash/nor/pic32mx.c | 1 + src/flash/nor/stellaris.c | 1 + src/flash/nor/stm32x.c | 1 + src/flash/nor/str7x.c | 1 + src/flash/nor/str9x.c | 1 + src/flash/nor/str9xpec.c | 1 + src/flash/nor/tcl.c | 4 +- src/flash/nor/tms470.c | 1 + 23 files changed, 206 insertions(+), 164 deletions(-) hooks/post-receive -- Main OpenOCD repository |