X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fmdr.c;h=3796259948a5f25124dc49672cd076c8f38e9049;hp=650abfd62d650e6c313ad4d8a0e5d3e7fa83d270;hb=a7479fa89def9d8b1854d629dfdaa0ba17132617;hpb=facd0e7827926d0639260be40e9cc4c595794194
diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c
index 650abfd62d..3796259948 100644
--- a/src/flash/nor/mdr.c
+++ b/src/flash/nor/mdr.c
@@ -22,9 +22,7 @@
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -88,11 +86,6 @@ FLASH_BANK_COMMAND_HANDLER(mdr_flash_bank_command)
return ERROR_OK;
}
-static int mdr_protect_check(struct flash_bank *bank)
-{
- return ERROR_OK;
-}
-
static int mdr_mass_erase(struct flash_bank *bank)
{
struct target *target = bank->target;
@@ -173,7 +166,8 @@ static int mdr_erase(struct flash_bank *bank, int first, int last)
if (retval != ERROR_OK)
goto reset_pg_and_lock;
- if ((first == 0) && (last == (bank->num_sectors - 1))) {
+ if ((first == 0) && (last == (bank->num_sectors - 1)) &&
+ !mdr_info->mem_type) {
retval = mdr_mass_erase(bank);
goto reset_pg_and_lock;
}
@@ -218,12 +212,7 @@ reset_pg_and_lock:
return retval;
}
-static int mdr_protect(struct flash_bank *bank, int set, int first, int last)
-{
- return ERROR_OK;
-}
-
-static int mdr_write_block(struct flash_bank *bank, uint8_t *buffer,
+static int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct target *target = bank->target;
@@ -255,7 +244,7 @@ static int mdr_write_block(struct flash_bank *bank, uint8_t *buffer,
&write_algorithm) != ERROR_OK) {
LOG_WARNING("no working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- };
+ }
retval = target_write_buffer(target, write_algorithm->address,
sizeof(mdr32fx_flash_write_code), mdr32fx_flash_write_code);
@@ -274,7 +263,7 @@ static int mdr_write_block(struct flash_bank *bank, uint8_t *buffer,
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- };
+ }
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (32bit) */
@@ -314,7 +303,7 @@ static int mdr_write_block(struct flash_bank *bank, uint8_t *buffer,
return retval;
}
-static int mdr_write(struct flash_bank *bank, uint8_t *buffer,
+static int mdr_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct target *target = bank->target;
@@ -345,7 +334,7 @@ static int mdr_write(struct flash_bank *bank, uint8_t *buffer,
LOG_INFO("odd number of bytes to write, padding with 0xff");
buffer = memcpy(new_buffer, buffer, count);
while (rem--)
- buffer[count++] = 0xff;
+ new_buffer[count++] = 0xff;
}
uint32_t flash_cmd, cur_per_clock;
@@ -471,6 +460,107 @@ free_buffer:
if (new_buffer)
free(new_buffer);
+ /* read some bytes bytes to flush buffer in flash accelerator.
+ * See errata for 1986VE1T and 1986VE3. Error 0007 */
+ if ((retval == ERROR_OK) && (!mdr_info->mem_type)) {
+ uint32_t tmp;
+ target_checksum_memory(bank->target, bank->base, 64, &tmp);
+ }
+
+ return retval;
+}
+
+static int mdr_read(struct flash_bank *bank, uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ struct target *target = bank->target;
+ struct mdr_flash_bank *mdr_info = bank->driver_priv;
+ int retval, retval2;
+
+ if (!mdr_info->mem_type)
+ return default_flash_read(bank, buffer, offset, count);
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (offset & 0x3) {
+ LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte alignment", offset);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
+ if (count & 0x3) {
+ LOG_ERROR("count 0x%" PRIx32 " breaks required 4-byte alignment", count);
+ return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
+ }
+
+ uint32_t flash_cmd, cur_per_clock;
+
+ retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);
+ if (retval != ERROR_OK)
+ goto err;
+
+ if (!(cur_per_clock & MD_PER_CLOCK_RST_CLK)) {
+ /* Something's very wrong if the RST_CLK module is not clocked */
+ LOG_ERROR("Target needs reset before flash operations");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ goto err;
+ }
+
+ retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);
+ if (retval != ERROR_OK)
+ goto err;
+
+ retval = target_write_u32(target, FLASH_KEY, KEY);
+ if (retval != ERROR_OK)
+ goto err;
+
+ retval = target_read_u32(target, FLASH_CMD, &flash_cmd);
+ if (retval != ERROR_OK)
+ goto err_lock;
+
+ /* Switch on register access */
+ flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON | FLASH_IFREN;
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ for (uint32_t i = 0; i < count; i += 4) {
+ retval = target_write_u32(target, FLASH_ADR, offset + i);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd |
+ FLASH_XE | FLASH_YE | FLASH_SE);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ uint32_t buf;
+ retval = target_read_u32(target, FLASH_DO, &buf);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ buf_set_u32(buffer, i * 8, 32, buf);
+
+ retval = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval != ERROR_OK)
+ goto reset_pg_and_lock;
+
+ }
+
+reset_pg_and_lock:
+ flash_cmd &= FLASH_DELAY_MASK;
+ retval2 = target_write_u32(target, FLASH_CMD, flash_cmd);
+ if (retval == ERROR_OK)
+ retval = retval2;
+
+err_lock:
+ retval2 = target_write_u32(target, FLASH_KEY, 0);
+ if (retval == ERROR_OK)
+ retval = retval2;
+
+err:
return retval;
}
@@ -482,6 +572,11 @@ static int mdr_probe(struct flash_bank *bank)
page_count = mdr_info->page_count;
page_size = bank->size / page_count;
+ if (bank->sectors) {
+ free(bank->sectors);
+ bank->sectors = NULL;
+ }
+
bank->num_sectors = page_count;
bank->sectors = malloc(sizeof(struct flash_sector) * page_count);
@@ -514,16 +609,17 @@ static int get_mdr_info(struct flash_bank *bank, char *buf, int buf_size)
return ERROR_OK;
}
-struct flash_driver mdr_flash = {
+const struct flash_driver mdr_flash = {
.name = "mdr",
+ .usage = "flash bank mdr 0 0 \n"
+ ": 0 for main memory, 1 for info memory",
.flash_bank_command = mdr_flash_bank_command,
.erase = mdr_erase,
- .protect = mdr_protect,
.write = mdr_write,
- .read = default_flash_read,
+ .read = mdr_read,
.probe = mdr_probe,
.auto_probe = mdr_auto_probe,
.erase_check = default_flash_blank_check,
- .protect_check = mdr_protect_check,
.info = get_mdr_info,
+ .free_driver_priv = default_flash_free_driver_priv,
};