From bc8be110ff314cab0e09792a05b6871672c18302 Mon Sep 17 00:00:00 2001
From: Antonio Borneo <borneo.antonio@gmail.com>
Date: Tue, 11 May 2010 11:16:33 +0800
Subject: [PATCH] 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 <borneo.antonio@gmail.com>
---
 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       |  2 ++
 src/flash/nor/core.c      | 24 ++++++++++++++++++++++++
 src/flash/nor/core.h      | 11 +++++++++++
 src/flash/nor/driver.h    | 15 +++++++++++++++
 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       |  2 +-
 src/flash/nor/tms470.c    |  1 +
 23 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c
index 82ea2bc6e..40ee32126 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 5f013ed85..06b84cd31 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 cca0cf2cc..606cc32b0 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 15b8b2794..7cdab5193 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 94ff7b947..1b080acd8 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 936f07ca6..00f73f214 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -3,6 +3,7 @@
  *   Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>       *
  *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *
  *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
+ *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *
  *                                                                         *
  *   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 1dfd721be..a35f64f68 100644
--- a/src/flash/nor/core.h
+++ b/src/flash/nor/core.h
@@ -3,6 +3,7 @@
  *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *
  *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *
  *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
+ *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *
  *                                                                         *
  *   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  *
@@ -135,6 +136,16 @@ int flash_write(struct target *target,
 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,
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 0e7713273..3757442fc 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -3,6 +3,7 @@
  *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *
  *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *
  *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
+ *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *
  *                                                                         *
  *   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  *
@@ -130,6 +131,20 @@ struct flash_driver
 	int (*write)(struct flash_bank *bank,
 			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 783a40c1b..f9c328548 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 e1e77eaa2..92851ed0c 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 34ccbe4e3..de1bc9e56 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 438ab544c..154248caf 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 5ab4e9cce..b6d207e83 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 5b004951b..3ae7bb4f0 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 5d9372481..9a295eb03 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 4ebd2564b..58009ae57 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 cce5f3700..38374ffe5 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 7afd9597d..d11a8edc6 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 3d523413c..46510ed45 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 2208fe326..e8e942eec 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 861d70bcb..073dfe10f 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 ad2181239..af655c6d8 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 edb43afa2..c1681f197 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,
-- 
GitLab