* 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#define FTCTR 0x2020000C /* Flash test control */
#define FBWST 0x20200010 /* Flash bridge wait-state */
#define FCRA 0x2020001C /* Flash clock divider */
-#define FMSSTART 0x20200020 /* Flash Built-In Selft Test start address */
-#define FMSSTOP 0x20200024 /* Flash Built-In Selft Test stop address */
+#define FMSSTART 0x20200020 /* Flash Built-In Self Test start address */
+#define FMSSTOP 0x20200024 /* Flash Built-In Self Test stop address */
#define FMS16 0x20200028 /* Flash 16-bit signature */
#define FMSW0 0x2020002C /* Flash 128-bit signature Word 0 */
#define FMSW1 0x20200030 /* Flash 128-bit signature Word 1 */
/**
* Maximum contiguous block of internal SRAM (bytes).
- * Autodetected by the driver. Not the total amount of SRAM, only the
+ * Autodetected by the driver. Not the total amount of SRAM, only
* the largest \em contiguous block!
*/
uint32_t max_ram_block;
static uint32_t lpc2900_read_security_status(struct flash_bank *bank);
static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
uint32_t addr_from, uint32_t addr_to,
- uint32_t (*signature)[4]);
-static uint32_t lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);
+ uint32_t signature[4]);
+static unsigned int lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);
static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var);
/*********************** Helper functions **************************/
* Anything else is undefined (is_protected = -1). This is treated as
* a protected sector!
*/
- int sector;
- int index_t;
- for (sector = 0; sector < bank->num_sectors; sector++) {
+ for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
+ unsigned int index_t;
+
/* Convert logical sector number to physical sector number */
if (sector <= 4)
index_t = sector + 11;
static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
uint32_t addr_from,
uint32_t addr_to,
- uint32_t (*signature)[4])
+ uint32_t signature[4])
{
struct target *target = bank->target;
return ERROR_FLASH_OPERATION_FAILED;
/* Return the signature */
- target_read_memory(target, FMSW0, 4, 4, (uint8_t *)signature);
+ uint8_t sig_buf[4 * 4];
+ target_read_memory(target, FMSW0, 4, 4, sig_buf);
+ target_buffer_get_u32_array(target, sig_buf, 4, signature);
return ERROR_OK;
}
* @param bank Pointer to the flash bank descriptor
* @param offset Offset address relative to bank start
*/
-static uint32_t lpc2900_address2sector(struct flash_bank *bank,
+static unsigned int lpc2900_address2sector(struct flash_bank *bank,
uint32_t offset)
{
uint32_t address = bank->base + offset;
/* Run through all sectors of this bank */
- int sector;
- for (sector = 0; sector < bank->num_sectors; sector++) {
+ for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
/* Return immediately if address is within the current sector */
if (address < (bank->sectors[sector].offset + bank->sectors[sector].size))
return sector;
*/
static int lpc2900_write_index_page(struct flash_bank *bank,
int pagenum,
- uint8_t (*page)[FLASH_PAGE_SIZE])
+ uint8_t page[FLASH_PAGE_SIZE])
{
/* Only pages 4...7 are user writable */
if ((pagenum < 4) || (pagenum > 7)) {
/* Write whole page to flash data latches */
if (target_write_memory(target,
bank->base + pagenum * FLASH_PAGE_SIZE,
- 4, FLASH_PAGE_SIZE / 4, (uint8_t *)page) != ERROR_OK) {
+ 4, FLASH_PAGE_SIZE / 4, page) != ERROR_OK) {
LOG_ERROR("Index sector write failed @ page %d", pagenum);
target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);
/**
* Calculate FPTR.TR register value for desired program/erase time.
*
- * @param clock System clock in Hz
- * @param time Program/erase time in µs
+ * @param clock_var System clock in Hz
+ * @param time_var Program/erase time in µs
*/
static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var)
{
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
if (bank->target->state != TARGET_HALTED) {
}
/* Run BIST over whole flash range */
- status = lpc2900_run_bist128(bank, bank->base, bank->base + (bank->size - 1), &signature);
+ status = lpc2900_run_bist128(bank, bank->base, bank->base + (bank->size - 1), signature);
if (status != ERROR_OK)
return status;
- command_print(CMD_CTX, "signature: 0x%8.8" PRIx32
+ command_print(CMD, "signature: 0x%8.8" PRIx32
":0x%8.8" PRIx32
":0x%8.8" PRIx32
":0x%8.8" PRIx32,
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
}
/* Storage for customer info. Read in two parts */
- uint32_t customer[ISS_CUSTOMER_NWORDS1 + ISS_CUSTOMER_NWORDS2];
+ uint8_t customer[4 * (ISS_CUSTOMER_NWORDS1 + ISS_CUSTOMER_NWORDS2)];
/* Enable access to index sector */
target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS);
/* Read two parts */
target_read_memory(target, bank->base+ISS_CUSTOMER_START1, 4,
ISS_CUSTOMER_NWORDS1,
- (uint8_t *)&customer[0]);
+ &customer[0]);
target_read_memory(target, bank->base+ISS_CUSTOMER_START2, 4,
ISS_CUSTOMER_NWORDS2,
- (uint8_t *)&customer[ISS_CUSTOMER_NWORDS1]);
+ &customer[4 * ISS_CUSTOMER_NWORDS1]);
/* Deactivate access to index sector */
target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);
/* Try and open the file */
- struct fileio fileio;
+ struct fileio *fileio;
const char *filename = CMD_ARGV[1];
int ret = fileio_open(&fileio, filename, FILEIO_WRITE, FILEIO_BINARY);
if (ret != ERROR_OK) {
}
size_t nwritten;
- ret = fileio_write(&fileio, sizeof(customer),
- (const uint8_t *)customer, &nwritten);
+ ret = fileio_write(fileio, sizeof(customer), customer, &nwritten);
if (ret != ERROR_OK) {
LOG_ERROR("Write operation to file %s failed", filename);
- fileio_close(&fileio);
+ fileio_close(fileio);
return ret;
}
- fileio_close(&fileio);
+ fileio_close(fileio);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
lpc2900_info->risky = !strcmp(CMD_ARGV[1], ISS_PASSWORD);
if (!lpc2900_info->risky) {
- command_print(CMD_CTX, "Wrong password (use '%s')", ISS_PASSWORD);
+ command_print(CMD, "Wrong password (use '%s')", ISS_PASSWORD);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- command_print(CMD_CTX,
+ command_print(CMD,
"Potentially dangerous operation allowed in next command!");
return ERROR_OK;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if (!lpc2900_info->risky) {
- command_print(CMD_CTX, "Command execution not allowed!");
+ command_print(CMD, "Command execution not allowed!");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
lpc2900_info->risky = 0;
/* The image will always start at offset 0 */
struct image image;
- image.base_address_set = 1;
+ image.base_address_set = true;
image.base_address = 0;
- image.start_address_set = 0;
+ image.start_address_set = false;
const char *filename = CMD_ARGV[1];
const char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL;
image_close(&image);
return retval;
}
- retval = lpc2900_write_index_page(bank, 4, &page);
+ retval = lpc2900_write_index_page(bank, 4, page);
if (retval != ERROR_OK) {
image_close(&image);
return retval;
image_close(&image);
return retval;
}
- retval = lpc2900_write_index_page(bank, 5, &page);
+ retval = lpc2900_write_index_page(bank, 5, page);
if (retval != ERROR_OK) {
image_close(&image);
return retval;
/* Get the bank descriptor */
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if (!lpc2900_info->risky) {
- command_print(CMD_CTX, "Command execution not allowed! "
+ command_print(CMD, "Command execution not allowed! "
"(use 'password' command first)");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
lpc2900_info->risky = 0;
/* Read sector range, and do a sanity check. */
- int first, last;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
+ unsigned int first, last;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);
if ((first >= bank->num_sectors) ||
(last >= bank->num_sectors) ||
(first > last)) {
- command_print(CMD_CTX, "Illegal sector range");
+ command_print(CMD, "Illegal sector range");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
uint8_t page[FLASH_PAGE_SIZE];
- int sector;
/* Sectors in page 6 */
if ((first <= 4) || (last >= 8)) {
memset(&page, 0xff, FLASH_PAGE_SIZE);
- for (sector = first; sector <= last; sector++) {
+ for (unsigned int sector = first; sector <= last; sector++) {
if (sector <= 4)
memset(&page[0xB0 + 16*sector], 0, 16);
else if (sector >= 8)
memset(&page[0x00 + 16*(sector - 8)], 0, 16);
}
- retval = lpc2900_write_index_page(bank, 6, &page);
+ retval = lpc2900_write_index_page(bank, 6, page);
if (retval != ERROR_OK) {
LOG_ERROR("failed to update index sector page 6");
return retval;
/* Sectors in page 7 */
if ((first <= 7) && (last >= 5)) {
memset(&page, 0xff, FLASH_PAGE_SIZE);
- for (sector = first; sector <= last; sector++) {
+ for (unsigned int sector = first; sector <= last; sector++) {
if ((sector >= 5) && (sector <= 7))
memset(&page[0x00 + 16*(sector - 5)], 0, 16);
}
- retval = lpc2900_write_index_page(bank, 7, &page);
+ retval = lpc2900_write_index_page(bank, 7, page);
if (retval != ERROR_OK) {
LOG_ERROR("failed to update index sector page 7");
return retval;
}
}
- command_print(CMD_CTX,
+ command_print(CMD,
"Sectors security will become effective after next power cycle");
/* Update the sector security status */
/* Get the bank descriptor */
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
/* Check if command execution is allowed. */
if (!lpc2900_info->risky) {
- command_print(CMD_CTX, "Command execution not allowed! "
+ command_print(CMD, "Command execution not allowed! "
"(use 'password' command first)");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
page[0x30 + 3] = 0x7F;
/* Write to page 5 */
- retval = lpc2900_write_index_page(bank, 5, &page);
+ retval = lpc2900_write_index_page(bank, 5, page);
if (retval != ERROR_OK) {
LOG_ERROR("failed to update index sector page 5");
return retval;
* @param first First sector to be erased
* @param last Last sector (including) to be erased
*/
-static int lpc2900_erase(struct flash_bank *bank, int first, int last)
+static int lpc2900_erase(struct flash_bank *bank, unsigned int first,
+ unsigned int last)
{
uint32_t status;
- int sector;
- int last_unsecured_sector;
+ unsigned int last_unsecured_sector;
+ bool has_unsecured_sector;
struct target *target = bank->target;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
return status;
/* Sanity check on sector range */
- if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
+ if ((last < first) || (last >= bank->num_sectors)) {
LOG_INFO("Bad sector range");
return ERROR_FLASH_SECTOR_INVALID;
}
* a special way.
*/
last_unsecured_sector = -1;
- for (sector = first; sector <= last; sector++) {
- if (!bank->sectors[sector].is_protected)
+ has_unsecured_sector = false;
+ for (unsigned int sector = first; sector <= last; sector++) {
+ if (!bank->sectors[sector].is_protected) {
last_unsecured_sector = sector;
+ has_unsecured_sector = true;
+ }
}
/* Exit now, in case of the rare constellation where all sectors in range
* are secured. This is regarded a success, since erasing/programming of
* secured sectors shall be handled transparently.
*/
- if (last_unsecured_sector == -1)
+ if (!has_unsecured_sector)
return ERROR_OK;
/* Enable flash block and set the correct CRA clock of 66 kHz */
FLASH_ERASE_TIME));
/* Sectors are marked for erasure, then erased all together */
- for (sector = first; sector <= last_unsecured_sector; sector++) {
+ for (unsigned int sector = first; sector <= last_unsecured_sector; sector++) {
/* Only mark sectors that aren't secured. Any attempt to erase a group
* of sectors will fail if any single one of them is secured!
*/
return ERROR_OK;
}
-static int lpc2900_protect(struct flash_bank *bank, int set, int first, int last)
-{
- /* This command is not supported.
- * "Protection" in LPC2900 terms is handled transparently. Sectors will
- * automatically be unprotected as needed.
- * Instead we use the concept of sector security. A secured sector is shown
- * as "protected" in OpenOCD. Sector security is a permanent feature, and
- * cannot be disabled once activated.
- */
-
- return ERROR_OK;
-}
+/* lpc2900_protect command is not supported.
+* "Protection" in LPC2900 terms is handled transparently. Sectors will
+* automatically be unprotected as needed.
+* Instead we use the concept of sector security. A secured sector is shown
+* as "protected" in OpenOCD. Sector security is a permanent feature, and
+* cannot be disabled once activated.
+*/
/**
* Write data to flash.
* @param offset Start address (relative to bank start)
* @param count Number of bytes to be programmed
*/
-static int lpc2900_write(struct flash_bank *bank, uint8_t *buffer,
+static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
uint8_t page[FLASH_PAGE_SIZE];
uint32_t num_bytes;
struct target *target = bank->target;
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
- int sector;
int retval;
static const uint32_t write_target_code[] = {
lpc2900_read_security_status(bank);
/* Unprotect all involved sectors */
- for (sector = 0; sector < bank->num_sectors; sector++) {
+ for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
/* Start address in or before this sector?
* End address in or behind this sector? */
if (((bank->base + offset) <
* a target algorithm. If not, fall back to host programming. */
/* We need some room for target code. */
- uint32_t target_code_size = sizeof(write_target_code);
+ const uint32_t target_code_size = sizeof(write_target_code);
/* Try working area allocation. Start with a large buffer, and try with
* reduced size if that fails. */
break;
}
}
- ;
if (warea) {
struct reg_param reg_params[5];
- struct arm_algorithm armv4_5_info;
+ struct arm_algorithm arm_algo;
/* We can use target mode. Download the algorithm. */
- retval = target_write_buffer(target,
- (warea->address)+buffer_size,
- target_code_size,
- (uint8_t *)write_target_code);
+ uint8_t code[sizeof(write_target_code)];
+ target_buffer_set_u32_array(target, code, ARRAY_SIZE(write_target_code),
+ write_target_code);
+ retval = target_write_buffer(target, (warea->address) + buffer_size, sizeof(code), code);
if (retval != ERROR_OK) {
LOG_ERROR("Unable to write block write code to target");
target_free_all_working_areas(target);
/* Write to flash in large blocks */
while (count != 0) {
uint32_t this_npages;
- uint8_t *this_buffer;
- int start_sector = lpc2900_address2sector(bank, offset);
+ const uint8_t *this_buffer;
+ unsigned int start_sector = lpc2900_address2sector(bank, offset);
/* First page / last page / rest */
if (offset % FLASH_PAGE_SIZE) {
this_buffer = buffer;
/* Make sure we stop at the next secured sector */
- sector = start_sector + 1;
+ unsigned int sector = start_sector + 1;
while (sector < bank->num_sectors) {
/* Secured? */
if (bank->sectors[sector].is_protected) {
/* Skip the current sector if it is secured */
if (bank->sectors[start_sector].is_protected) {
- LOG_DEBUG("Skip secured sector %d",
+ LOG_DEBUG("Skip secured sector %u",
start_sector);
/* Stop if this is the last sector */
buf_set_u32(reg_params[4].value, 0, 32, FPTR_EN_T | prog_time);
/* Execute algorithm, assume breakpoint for last instruction */
- armv4_5_info.common_magic = ARM_COMMON_MAGIC;
- armv4_5_info.core_mode = ARM_MODE_SVC;
- armv4_5_info.core_state = ARM_STATE_ARM;
+ arm_algo.common_magic = ARM_COMMON_MAGIC;
+ arm_algo.core_mode = ARM_MODE_SVC;
+ arm_algo.core_state = ARM_STATE_ARM;
retval = target_run_algorithm(target, 0, NULL, 5, reg_params,
(warea->address) + buffer_size,
(warea->address) + buffer_size + target_code_size - 4,
10000, /* 10s should be enough for max. 16 KiB of data */
- &armv4_5_info);
+ &arm_algo);
if (retval != ERROR_OK) {
LOG_ERROR("Execution of flash algorithm failed.");
{
struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
struct target *target = bank->target;
- int i = 0;
uint32_t offset;
}
/* Show detected device */
- LOG_INFO("Flash bank %d: Device %s, %" PRIu32
- " KiB in %d sectors",
+ LOG_INFO("Flash bank %u: Device %s, %" PRIu32
+ " KiB in %u sectors",
bank->bank_number,
lpc2900_info->target_name, bank->size / KiB,
bank->num_sectors);
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
offset = 0;
- for (i = 0; i < bank->num_sectors; i++) {
+ for (unsigned int i = 0; i < bank->num_sectors; i++) {
bank->sectors[i].offset = offset;
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = -1;
* that has more than 19 sectors. Politely ask for a fix then.
*/
bank->sectors[i].size = 0;
- LOG_ERROR("Never heard about sector %d", i);
+ LOG_ERROR("Never heard about sector %u", i);
}
offset += bank->sectors[i].size;
return status;
}
- /* Use the BIST (Built-In Selft Test) to generate a signature of each flash
+ /* Use the BIST (Built-In Self Test) to generate a signature of each flash
* sector. Compare against the expected signature of an empty sector.
*/
- int sector;
- for (sector = 0; sector < bank->num_sectors; sector++) {
+ for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
uint32_t signature[4];
status = lpc2900_run_bist128(bank, bank->sectors[sector].offset,
- bank->sectors[sector].offset + (bank->sectors[sector].size - 1), &signature);
+ bank->sectors[sector].offset + (bank->sectors[sector].size - 1), signature);
if (status != ERROR_OK)
return status;
return lpc2900_read_security_status(bank);
}
-/**
- * Print info about the driver (not the device).
- *
- * @param bank Pointer to the flash bank descriptor
- * @param buf Buffer to take the string
- * @param buf_size Maximum number of characters that the buffer can take
- */
-static int lpc2900_info(struct flash_bank *bank, char *buf, int buf_size)
-{
- snprintf(buf, buf_size, "lpc2900 flash driver");
- return ERROR_OK;
-}
-
-struct flash_driver lpc2900_flash = {
+const struct flash_driver lpc2900_flash = {
.name = "lpc2900",
.commands = lpc2900_command_handlers,
.flash_bank_command = lpc2900_flash_bank_command,
.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,
.protect_check = lpc2900_protect_check,
- .info = lpc2900_info
+ .free_driver_priv = default_flash_free_driver_priv,
};