aboutsummaryrefslogtreecommitdiff
path: root/src/flash
diff options
context:
space:
mode:
Diffstat (limited to 'src/flash')
-rw-r--r--src/flash/common.c6
-rw-r--r--src/flash/common.h2
-rw-r--r--src/flash/nand/arm_io.c6
-rw-r--r--src/flash/nand/arm_io.h2
-rw-r--r--src/flash/nand/at91sam9.c13
-rw-r--r--src/flash/nand/core.c8
-rw-r--r--src/flash/nand/core.h2
-rw-r--r--src/flash/nand/davinci.c2
-rw-r--r--src/flash/nand/driver.c4
-rw-r--r--src/flash/nand/fileio.c4
-rw-r--r--src/flash/nand/lpc3180.c5
-rw-r--r--src/flash/nand/lpc32xx.c5
-rw-r--r--src/flash/nand/mx3.h8
-rw-r--r--src/flash/nand/mxc.h10
-rw-r--r--src/flash/nor/Makefile.am3
-rw-r--r--src/flash/nor/aducm360.c2
-rw-r--r--src/flash/nor/at91sam3.c78
-rw-r--r--src/flash/nor/at91sam4.c78
-rw-r--r--src/flash/nor/at91samd.c4
-rw-r--r--src/flash/nor/ath79.c2
-rw-r--r--src/flash/nor/atsame5.c34
-rw-r--r--src/flash/nor/atsamv.c28
-rw-r--r--src/flash/nor/cfi.c5
-rw-r--r--src/flash/nor/cfi.h8
-rw-r--r--src/flash/nor/core.c6
-rw-r--r--src/flash/nor/core.h2
-rw-r--r--src/flash/nor/driver.h2
-rw-r--r--src/flash/nor/drivers.c4
-rw-r--r--src/flash/nor/dw-spi-helper.h102
-rw-r--r--src/flash/nor/dw-spi.c1608
-rw-r--r--src/flash/nor/em357.c2
-rw-r--r--src/flash/nor/fespi.c8
-rw-r--r--src/flash/nor/fm4.c4
-rw-r--r--src/flash/nor/kinetis.c54
-rw-r--r--src/flash/nor/kinetis_ke.c8
-rw-r--r--src/flash/nor/lpc2000.c6
-rw-r--r--src/flash/nor/max32xxx.c12
-rw-r--r--src/flash/nor/mspm0.c1131
-rw-r--r--src/flash/nor/niietcm4.c6
-rw-r--r--src/flash/nor/nrf5.c126
-rw-r--r--src/flash/nor/ocl.c2
-rw-r--r--src/flash/nor/psoc4.c10
-rw-r--r--src/flash/nor/psoc5lp.c24
-rw-r--r--src/flash/nor/psoc6.c9
-rw-r--r--src/flash/nor/rsl10.c5
-rw-r--r--src/flash/nor/sfdp.c5
-rw-r--r--src/flash/nor/sfdp.h4
-rw-r--r--src/flash/nor/sim3x.c6
-rw-r--r--src/flash/nor/stellaris.c10
-rw-r--r--src/flash/nor/stm32l4x.c133
-rw-r--r--src/flash/nor/stm32l4x.h6
-rw-r--r--src/flash/nor/stmqspi.c4
-rw-r--r--src/flash/nor/str9xpec.c2
-rw-r--r--src/flash/nor/tcl.c8
-rw-r--r--src/flash/nor/tms470.c10
-rw-r--r--src/flash/nor/xcf.c68
-rw-r--r--src/flash/nor/xmc1xxx.c6
-rw-r--r--src/flash/startup.tcl6
58 files changed, 3370 insertions, 348 deletions
diff --git a/src/flash/common.c b/src/flash/common.c
index ebd9396..9f40a3a 100644
--- a/src/flash/common.c
+++ b/src/flash/common.c
@@ -11,14 +11,14 @@
#include "common.h"
#include <helper/log.h>
-unsigned get_flash_name_index(const char *name)
+unsigned int get_flash_name_index(const char *name)
{
const char *name_index = strrchr(name, '.');
if (!name_index)
return 0;
if (name_index[1] < '0' || name_index[1] > '9')
return ~0U;
- unsigned requested;
+ unsigned int requested;
int retval = parse_uint(name_index + 1, &requested);
/* detect parsing error by forcing past end of bank list */
return (retval == ERROR_OK) ? requested : ~0U;
@@ -26,7 +26,7 @@ unsigned get_flash_name_index(const char *name)
bool flash_driver_name_matches(const char *name, const char *expected)
{
- unsigned blen = strlen(name);
+ unsigned int blen = strlen(name);
/* only match up to the length of the driver name... */
if (strncmp(name, expected, blen) != 0)
return false;
diff --git a/src/flash/common.h b/src/flash/common.h
index 15aea5b..6ceaa8d 100644
--- a/src/flash/common.h
+++ b/src/flash/common.h
@@ -17,7 +17,7 @@
* name provides a suffix but it does not parse as an unsigned integer,
* the routine returns ~0U. This will prevent further matching.
*/
-unsigned get_flash_name_index(const char *name);
+unsigned int get_flash_name_index(const char *name);
/**
* Attempt to match the @c expected name with the @c name of a driver.
* @param name The name of the driver (from the bank's device structure).
diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c
index 80bd0cf..dd012e1 100644
--- a/src/flash/nand/arm_io.c
+++ b/src/flash/nand/arm_io.c
@@ -31,12 +31,12 @@
* @return Success or failure of the operation
*/
static int arm_code_to_working_area(struct target *target,
- const uint32_t *code, unsigned code_size,
- unsigned additional, struct working_area **area)
+ const uint32_t *code, unsigned int code_size,
+ unsigned int additional, struct working_area **area)
{
uint8_t code_buf[code_size];
int retval;
- unsigned size = code_size + additional;
+ unsigned int size = code_size + additional;
/* REVISIT this assumes size doesn't ever change.
* That's usually correct; but there are boards with
diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h
index 10f0e66..760dc7e 100644
--- a/src/flash/nand/arm_io.h
+++ b/src/flash/nand/arm_io.h
@@ -27,7 +27,7 @@ struct arm_nand_data {
struct working_area *copy_area;
/** The chunk size is the page size or ECC chunk. */
- unsigned chunk_size;
+ unsigned int chunk_size;
/** Where data is read from or written to. */
uint32_t data;
diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c
index bfbba67..41cb07b 100644
--- a/src/flash/nand/at91sam9.c
+++ b/src/flash/nand/at91sam9.c
@@ -389,9 +389,8 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
uint32_t bit = parity & 0x0F;
data[word] ^= (0x1) << bit;
- LOG_INFO("Data word %d, bit %d corrected.",
- (unsigned) word,
- (unsigned) bit);
+ LOG_INFO("Data word %" PRIu32 ", bit %" PRIu32 " corrected.",
+ word, bit);
}
}
@@ -533,7 +532,7 @@ COMMAND_HANDLER(handle_at91sam9_cle_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
- unsigned num, address_line;
+ unsigned int num, address_line;
if (CMD_ARGC != 2) {
command_print(CMD, "incorrect number of arguments for 'at91sam9 cle' command");
@@ -563,7 +562,7 @@ COMMAND_HANDLER(handle_at91sam9_ale_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
- unsigned num, address_line;
+ unsigned int num, address_line;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -591,7 +590,7 @@ COMMAND_HANDLER(handle_at91sam9_rdy_busy_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
- unsigned num, base_pioc, pin_num;
+ unsigned int num, base_pioc, pin_num;
if (CMD_ARGC != 3)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -622,7 +621,7 @@ COMMAND_HANDLER(handle_at91sam9_ce_command)
{
struct nand_device *nand = NULL;
struct at91sam9_nand *info = NULL;
- unsigned num, base_pioc, pin_num;
+ unsigned int num, base_pioc, pin_num;
if (CMD_ARGC != 3)
return ERROR_COMMAND_SYNTAX_ERROR;
diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c
index 37e1d12..c5430ae 100644
--- a/src/flash/nand/core.c
+++ b/src/flash/nand/core.c
@@ -165,8 +165,8 @@ static struct nand_ecclayout nand_oob_8 = {
*/
static struct nand_device *get_nand_device_by_name(const char *name)
{
- unsigned requested = get_flash_name_index(name);
- unsigned found = 0;
+ unsigned int requested = get_flash_name_index(name);
+ unsigned int found = 0;
struct nand_device *nand;
for (nand = nand_devices; nand; nand = nand->next) {
@@ -194,7 +194,7 @@ struct nand_device *get_nand_device_by_num(int num)
return NULL;
}
-COMMAND_HELPER(nand_command_get_device, unsigned name_index,
+COMMAND_HELPER(nand_command_get_device, unsigned int name_index,
struct nand_device **nand)
{
const char *str = CMD_ARGV[name_index];
@@ -202,7 +202,7 @@ COMMAND_HELPER(nand_command_get_device, unsigned name_index,
if (*nand)
return ERROR_OK;
- unsigned num;
+ unsigned int num;
COMMAND_PARSE_NUMBER(uint, str, num);
*nand = get_nand_device_by_num(num);
if (!*nand) {
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h
index 137298c..4286e11 100644
--- a/src/flash/nand/core.h
+++ b/src/flash/nand/core.h
@@ -209,7 +209,7 @@ int nand_correct_data(struct nand_device *nand, u_char *dat,
int nand_register_commands(struct command_context *cmd_ctx);
/** helper for parsing a nand device command argument string */
-COMMAND_HELPER(nand_command_get_device, unsigned name_index,
+COMMAND_HELPER(nand_command_get_device, unsigned int name_index,
struct nand_device **nand);
diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c
index b7169fe..17040fe 100644
--- a/src/flash/nand/davinci.c
+++ b/src/flash/nand/davinci.c
@@ -379,7 +379,7 @@ static int davinci_writepage_tail(struct nand_device *nand,
static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
{
- unsigned oob_offset;
+ unsigned int oob_offset;
struct davinci_nand *info = nand->controller_priv;
struct target *target = nand->target;
const uint32_t fcr_addr = info->aemif + NANDFCR;
diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c
index ce79e13..5d99102 100644
--- a/src/flash/nand/driver.c
+++ b/src/flash/nand/driver.c
@@ -33,7 +33,7 @@ static struct nand_flash_controller *nand_flash_controllers[] = {
struct nand_flash_controller *nand_driver_find_by_name(const char *name)
{
- for (unsigned i = 0; nand_flash_controllers[i]; i++) {
+ for (unsigned int i = 0; nand_flash_controllers[i]; i++) {
struct nand_flash_controller *controller = nand_flash_controllers[i];
if (strcmp(name, controller->name) == 0)
return controller;
@@ -42,7 +42,7 @@ struct nand_flash_controller *nand_driver_find_by_name(const char *name)
}
int nand_driver_walk(nand_driver_walker_t f, void *x)
{
- for (unsigned i = 0; nand_flash_controllers[i]; i++) {
+ for (unsigned int i = 0; nand_flash_controllers[i]; i++) {
int retval = (*f)(nand_flash_controllers[i], x);
if (retval != ERROR_OK)
return retval;
diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c
index ca618b3..613ae3c 100644
--- a/src/flash/nand/fileio.c
+++ b/src/flash/nand/fileio.c
@@ -107,7 +107,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
{
nand_fileio_init(state);
- unsigned minargs = need_size ? 4 : 3;
+ unsigned int minargs = need_size ? 4 : 3;
if (minargs > CMD_ARGC)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -131,7 +131,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,
}
if (minargs < CMD_ARGC) {
- for (unsigned i = minargs; i < CMD_ARGC; i++) {
+ for (unsigned int i = minargs; i < CMD_ARGC; i++) {
if (!strcmp(CMD_ARGV[i], "oob_raw"))
state->oob_format |= NAND_OOB_RAW;
else if (!strcmp(CMD_ARGV[i], "oob_only"))
diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index c1af1d7..d221c34 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -890,8 +890,7 @@ static int lpc3180_read_page(struct nand_device *nand,
if (mlc_isr & 0x8) {
if (mlc_isr & 0x40) {
- LOG_ERROR("uncorrectable error detected: 0x%2.2x",
- (unsigned)mlc_isr);
+ LOG_ERROR("uncorrectable error detected: 0x%2.2" PRIx32, mlc_isr);
free(page_buffer);
free(oob_buffer);
return ERROR_NAND_OPERATION_FAILED;
@@ -1275,7 +1274,7 @@ COMMAND_HANDLER(handle_lpc3180_select_command)
if ((CMD_ARGC < 1) || (CMD_ARGC > 3))
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned num;
+ unsigned int num;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
struct nand_device *nand = get_nand_device_by_num(num);
if (!nand) {
diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c
index 1fdae9f..c67f2aa 100644
--- a/src/flash/nand/lpc32xx.c
+++ b/src/flash/nand/lpc32xx.c
@@ -1386,8 +1386,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page,
if (mlc_isr & 0x8) {
if (mlc_isr & 0x40) {
- LOG_ERROR("uncorrectable error detected: "
- "0x%2.2x", (unsigned)mlc_isr);
+ LOG_ERROR("uncorrectable error detected: 0x%2.2" PRIx32, mlc_isr);
return ERROR_NAND_OPERATION_FAILED;
}
@@ -1743,7 +1742,7 @@ COMMAND_HANDLER(handle_lpc32xx_select_command)
if ((CMD_ARGC < 1) || (CMD_ARGC > 3))
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned num;
+ unsigned int num;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
struct nand_device *nand = get_nand_device_by_num(num);
if (!nand) {
diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h
index b272962..648cd86 100644
--- a/src/flash/nand/mx3.h
+++ b/src/flash/nand/mx3.h
@@ -86,10 +86,10 @@ enum mx_nf_finalize_action {
};
struct mx3_nf_flags {
- unsigned target_little_endian:1;
- unsigned nand_readonly:1;
- unsigned one_kb_sram:1;
- unsigned hw_ecc_enabled:1;
+ unsigned int target_little_endian:1;
+ unsigned int nand_readonly:1;
+ unsigned int one_kb_sram:1;
+ unsigned int hw_ecc_enabled:1;
};
struct mx3_nf_controller {
diff --git a/src/flash/nand/mxc.h b/src/flash/nand/mxc.h
index ae2c03a..e9dc0a2 100644
--- a/src/flash/nand/mxc.h
+++ b/src/flash/nand/mxc.h
@@ -138,11 +138,11 @@ enum mxc_nf_finalize_action {
};
struct mxc_nf_flags {
- unsigned target_little_endian:1;
- unsigned nand_readonly:1;
- unsigned one_kb_sram:1;
- unsigned hw_ecc_enabled:1;
- unsigned biswap_enabled:1;
+ unsigned int target_little_endian:1;
+ unsigned int nand_readonly:1;
+ unsigned int one_kb_sram:1;
+ unsigned int hw_ecc_enabled:1;
+ unsigned int biswap_enabled:1;
};
struct mxc_nf_controller {
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index afa11e7..147807f 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -26,6 +26,7 @@ NOR_DRIVERS = \
%D%/cc26xx.c \
%D%/cfi.c \
%D%/dsp5680xx_flash.c \
+ %D%/dw-spi.c \
%D%/efm32.c \
%D%/em357.c \
%D%/eneispif.c \
@@ -44,6 +45,7 @@ NOR_DRIVERS = \
%D%/max32xxx.c \
%D%/mdr.c \
%D%/msp432.c \
+ %D%/mspm0.c \
%D%/mrvlqspi.c \
%D%/niietcm4.c \
%D%/non_cfi.c \
@@ -89,6 +91,7 @@ NORHEADERS = \
%D%/cc26xx.h \
%D%/cfi.h \
%D%/driver.h \
+ %D%/dw-spi-helper.h \
%D%/imp.h \
%D%/non_cfi.h \
%D%/ocl.h \
diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c
index ce9bf24..aa573ac 100644
--- a/src/flash/nor/aducm360.c
+++ b/src/flash/nor/aducm360.c
@@ -79,7 +79,7 @@ static int aducm360_build_sector_list(struct flash_bank *bank)
/* sector size is 512 */
bank->num_sectors = bank->size / FLASH_SECTOR_SIZE;
bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
- for (unsigned 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].size = FLASH_SECTOR_SIZE;
offset += bank->sectors[i].size;
diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c
index b1cb8f1..b86a18d 100644
--- a/src/flash/nor/at91sam3.c
+++ b/src/flash/nor/at91sam3.c
@@ -154,15 +154,15 @@ struct sam3_bank_private {
struct sam3_chip *chip;
/* so we can find the original bank pointer */
struct flash_bank *bank;
- unsigned bank_number;
+ unsigned int bank_number;
uint32_t controller_address;
uint32_t base_address;
uint32_t flash_wait_states;
bool present;
- unsigned size_bytes;
- unsigned nsectors;
- unsigned sector_size;
- unsigned page_size;
+ unsigned int size_bytes;
+ unsigned int nsectors;
+ unsigned int sector_size;
+ unsigned int page_size;
};
struct sam3_chip_details {
@@ -176,12 +176,12 @@ struct sam3_chip_details {
uint32_t chipid_cidr;
const char *name;
- unsigned n_gpnvms;
+ unsigned int n_gpnvms;
#define SAM3_N_NVM_BITS 3
- unsigned gpnvm[SAM3_N_NVM_BITS];
- unsigned total_flash_size;
- unsigned total_sram_size;
- unsigned n_banks;
+ unsigned int gpnvm[SAM3_N_NVM_BITS];
+ unsigned int total_flash_size;
+ unsigned int total_sram_size;
+ unsigned int n_banks;
#define SAM3_MAX_FLASH_BANKS 2
/* these are "initialized" from the global const data */
struct sam3_bank_private bank[SAM3_MAX_FLASH_BANKS];
@@ -2029,7 +2029,7 @@ static int efc_get_result(struct sam3_bank_private *private, uint32_t *v)
}
static int efc_start_command(struct sam3_bank_private *private,
- unsigned command, unsigned argument)
+ unsigned int command, unsigned int argument)
{
uint32_t n, v;
int r;
@@ -2051,7 +2051,7 @@ do_retry:
case AT91C_EFC_FCMD_CLB:
n = (private->size_bytes / private->page_size);
if (argument >= n)
- LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
+ LOG_ERROR("*BUG*: Embedded flash has only %" PRIu32 " pages", n);
break;
case AT91C_EFC_FCMD_SFB:
@@ -2124,8 +2124,8 @@ do_retry:
* @param status - put command status bits here
*/
static int efc_perform_command(struct sam3_bank_private *private,
- unsigned command,
- unsigned argument,
+ unsigned int command,
+ unsigned int argument,
uint32_t *status)
{
@@ -2220,7 +2220,7 @@ static int flashd_erase_entire_bank(struct sam3_bank_private *private)
* @param puthere - result stored here.
*/
/* ------------------------------------------------------------------------------ */
-static int flashd_get_gpnvm(struct sam3_bank_private *private, unsigned gpnvm, unsigned *puthere)
+static int flashd_get_gpnvm(struct sam3_bank_private *private, unsigned int gpnvm, unsigned int *puthere)
{
uint32_t v;
int r;
@@ -2261,10 +2261,10 @@ static int flashd_get_gpnvm(struct sam3_bank_private *private, unsigned gpnvm, u
* @param gpnvm GPNVM index.
* @returns 0 if successful; otherwise returns an error code.
*/
-static int flashd_clr_gpnvm(struct sam3_bank_private *private, unsigned gpnvm)
+static int flashd_clr_gpnvm(struct sam3_bank_private *private, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
LOG_DEBUG("Here");
if (private->bank_number != 0) {
@@ -2293,10 +2293,10 @@ static int flashd_clr_gpnvm(struct sam3_bank_private *private, unsigned gpnvm)
* @param private info about the bank
* @param gpnvm GPNVM index.
*/
-static int flashd_set_gpnvm(struct sam3_bank_private *private, unsigned gpnvm)
+static int flashd_set_gpnvm(struct sam3_bank_private *private, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
if (private->bank_number != 0) {
LOG_ERROR("GPNVM only works with Bank0");
@@ -2346,8 +2346,8 @@ static int flashd_get_lock_bits(struct sam3_bank_private *private, uint32_t *v)
*/
static int flashd_unlock(struct sam3_bank_private *private,
- unsigned start_sector,
- unsigned end_sector)
+ unsigned int start_sector,
+ unsigned int end_sector)
{
int r;
uint32_t status;
@@ -2376,8 +2376,8 @@ static int flashd_unlock(struct sam3_bank_private *private,
* @param end_sector - last sector (inclusive) to lock
*/
static int flashd_lock(struct sam3_bank_private *private,
- unsigned start_sector,
- unsigned end_sector)
+ unsigned int start_sector,
+ unsigned int end_sector)
{
uint32_t status;
uint32_t pg;
@@ -2405,8 +2405,8 @@ static int flashd_lock(struct sam3_bank_private *private,
static uint32_t sam3_reg_fieldname(struct sam3_chip *chip,
const char *regname,
uint32_t value,
- unsigned shift,
- unsigned width)
+ unsigned int shift,
+ unsigned int width)
{
uint32_t v;
int hwidth, dwidth;
@@ -2491,7 +2491,7 @@ static const char *const sramsize[] = {
};
-static const struct archnames { unsigned value; const char *name; } archnames[] = {
+static const struct archnames { unsigned int value; const char *name; } archnames[] = {
{ 0x19, "AT91SAM9xx Series" },
{ 0x29, "AT91SAM9XExx Series" },
{ 0x34, "AT91x34 Series" },
@@ -2867,8 +2867,8 @@ static int sam3_read_this_reg(struct sam3_chip *chip, uint32_t *goes_here)
r = target_read_u32(chip->target, reg->address, goes_here);
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Err: %d",
- reg->name, (unsigned)(reg->address), r);
+ LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08" PRIx32 ", Err: %d",
+ reg->name, reg->address, r);
}
return r;
}
@@ -2883,8 +2883,8 @@ static int sam3_read_all_regs(struct sam3_chip *chip)
r = sam3_read_this_reg(chip,
sam3_get_reg_ptr(&(chip->cfg), reg));
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Error: %d",
- reg->name, ((unsigned)(reg->address)), r);
+ LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08" PRIx32 ", Error: %d",
+ reg->name, reg->address, r);
return r;
}
reg++;
@@ -2951,7 +2951,7 @@ static int sam3_protect_check(struct flash_bank *bank)
{
int r;
uint32_t v = 0;
- unsigned x;
+ unsigned int x;
struct sam3_bank_private *private;
LOG_DEBUG("Begin");
@@ -3071,7 +3071,7 @@ static int sam3_get_details(struct sam3_bank_private *private)
const struct sam3_chip_details *details;
struct sam3_chip *chip;
struct flash_bank *saved_banks[SAM3_MAX_FLASH_BANKS];
- unsigned x;
+ unsigned int x;
LOG_DEBUG("Begin");
details = all_sam3_details;
@@ -3264,7 +3264,7 @@ static int sam3_protect(struct flash_bank *bank, int set, unsigned int first,
}
-static int sam3_page_read(struct sam3_bank_private *private, unsigned pagenum, uint8_t *buf)
+static int sam3_page_read(struct sam3_bank_private *private, unsigned int pagenum, uint8_t *buf)
{
uint32_t adr;
int r;
@@ -3283,7 +3283,7 @@ static int sam3_page_read(struct sam3_bank_private *private, unsigned pagenum, u
return r;
}
-static int sam3_page_write(struct sam3_bank_private *private, unsigned pagenum, const uint8_t *buf)
+static int sam3_page_write(struct sam3_bank_private *private, unsigned int pagenum, const uint8_t *buf)
{
uint32_t adr;
uint32_t status;
@@ -3347,10 +3347,10 @@ static int sam3_write(struct flash_bank *bank,
uint32_t count)
{
int n;
- unsigned page_cur;
- unsigned page_end;
+ unsigned int page_cur;
+ unsigned int page_end;
int r;
- unsigned page_offset;
+ unsigned int page_offset;
struct sam3_bank_private *private;
uint8_t *pagebuffer;
@@ -3497,7 +3497,7 @@ COMMAND_HANDLER(sam3_handle_info_command)
if (!chip)
return ERROR_OK;
- unsigned x;
+ unsigned int x;
int r;
/* bank0 must exist before we can do anything */
@@ -3549,7 +3549,7 @@ need_define:
COMMAND_HANDLER(sam3_handle_gpnvm_command)
{
- unsigned x, v;
+ unsigned int x, v;
int r, who;
struct sam3_chip *chip;
diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c
index 6212753..26a8037 100644
--- a/src/flash/nor/at91sam4.c
+++ b/src/flash/nor/at91sam4.c
@@ -134,15 +134,15 @@ struct sam4_bank_private {
struct sam4_chip *chip;
/* so we can find the original bank pointer */
struct flash_bank *bank;
- unsigned bank_number;
+ unsigned int bank_number;
uint32_t controller_address;
uint32_t base_address;
uint32_t flash_wait_states;
bool present;
- unsigned size_bytes;
- unsigned nsectors;
- unsigned sector_size;
- unsigned page_size;
+ unsigned int size_bytes;
+ unsigned int nsectors;
+ unsigned int sector_size;
+ unsigned int page_size;
};
struct sam4_chip_details {
@@ -156,12 +156,12 @@ struct sam4_chip_details {
uint32_t chipid_cidr;
const char *name;
- unsigned n_gpnvms;
+ unsigned int n_gpnvms;
#define SAM4_N_NVM_BITS 3
- unsigned gpnvm[SAM4_N_NVM_BITS];
- unsigned total_flash_size;
- unsigned total_sram_size;
- unsigned n_banks;
+ unsigned int gpnvm[SAM4_N_NVM_BITS];
+ unsigned int total_flash_size;
+ unsigned int total_sram_size;
+ unsigned int n_banks;
#define SAM4_MAX_FLASH_BANKS 2
/* these are "initialized" from the global const data */
struct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS];
@@ -1479,7 +1479,7 @@ static int efc_get_result(struct sam4_bank_private *private, uint32_t *v)
}
static int efc_start_command(struct sam4_bank_private *private,
- unsigned command, unsigned argument)
+ unsigned int command, unsigned int argument)
{
uint32_t n, v;
int r;
@@ -1501,7 +1501,7 @@ do_retry:
case AT91C_EFC_FCMD_CLB:
n = (private->size_bytes / private->page_size);
if (argument >= n)
- LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
+ LOG_ERROR("*BUG*: Embedded flash has only %" PRIu32 " pages", n);
break;
case AT91C_EFC_FCMD_SFB:
@@ -1574,8 +1574,8 @@ do_retry:
* @param status - put command status bits here
*/
static int efc_perform_command(struct sam4_bank_private *private,
- unsigned command,
- unsigned argument,
+ unsigned int command,
+ unsigned int argument,
uint32_t *status)
{
@@ -1716,7 +1716,7 @@ static int flashd_erase_pages(struct sam4_bank_private *private,
* @param puthere - result stored here.
*/
/* ------------------------------------------------------------------------------ */
-static int flashd_get_gpnvm(struct sam4_bank_private *private, unsigned gpnvm, unsigned *puthere)
+static int flashd_get_gpnvm(struct sam4_bank_private *private, unsigned int gpnvm, unsigned int *puthere)
{
uint32_t v;
int r;
@@ -1757,10 +1757,10 @@ static int flashd_get_gpnvm(struct sam4_bank_private *private, unsigned gpnvm, u
* @param gpnvm GPNVM index.
* @returns 0 if successful; otherwise returns an error code.
*/
-static int flashd_clr_gpnvm(struct sam4_bank_private *private, unsigned gpnvm)
+static int flashd_clr_gpnvm(struct sam4_bank_private *private, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
LOG_DEBUG("Here");
if (private->bank_number != 0) {
@@ -1789,10 +1789,10 @@ static int flashd_clr_gpnvm(struct sam4_bank_private *private, unsigned gpnvm)
* @param private info about the bank
* @param gpnvm GPNVM index.
*/
-static int flashd_set_gpnvm(struct sam4_bank_private *private, unsigned gpnvm)
+static int flashd_set_gpnvm(struct sam4_bank_private *private, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
if (private->bank_number != 0) {
LOG_ERROR("GPNVM only works with Bank0");
@@ -1846,8 +1846,8 @@ static int flashd_get_lock_bits(struct sam4_bank_private *private, uint32_t *v)
*/
static int flashd_unlock(struct sam4_bank_private *private,
- unsigned start_sector,
- unsigned end_sector)
+ unsigned int start_sector,
+ unsigned int end_sector)
{
int r;
uint32_t status;
@@ -1876,8 +1876,8 @@ static int flashd_unlock(struct sam4_bank_private *private,
* @param end_sector - last sector (inclusive) to lock
*/
static int flashd_lock(struct sam4_bank_private *private,
- unsigned start_sector,
- unsigned end_sector)
+ unsigned int start_sector,
+ unsigned int end_sector)
{
uint32_t status;
uint32_t pg;
@@ -1905,8 +1905,8 @@ static int flashd_lock(struct sam4_bank_private *private,
static uint32_t sam4_reg_fieldname(struct sam4_chip *chip,
const char *regname,
uint32_t value,
- unsigned shift,
- unsigned width)
+ unsigned int shift,
+ unsigned int width)
{
uint32_t v;
int hwidth, dwidth;
@@ -1991,7 +1991,7 @@ static const char *const sramsize[] = {
};
-static const struct archnames { unsigned value; const char *name; } archnames[] = {
+static const struct archnames { unsigned int value; const char *name; } archnames[] = {
{ 0x19, "AT91SAM9xx Series" },
{ 0x29, "AT91SAM9XExx Series" },
{ 0x34, "AT91x34 Series" },
@@ -2374,8 +2374,8 @@ static int sam4_read_this_reg(struct sam4_chip *chip, uint32_t *goes_here)
r = target_read_u32(chip->target, reg->address, goes_here);
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Err: %d",
- reg->name, (unsigned)(reg->address), r);
+ LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08" PRIx32 ", Err: %d",
+ reg->name, reg->address, r);
}
return r;
}
@@ -2390,8 +2390,8 @@ static int sam4_read_all_regs(struct sam4_chip *chip)
r = sam4_read_this_reg(chip,
sam4_get_reg_ptr(&(chip->cfg), reg));
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d",
- reg->name, ((unsigned)(reg->address)), r);
+ LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08" PRIx32 ", Error: %d",
+ reg->name, reg->address, r);
return r;
}
reg++;
@@ -2444,7 +2444,7 @@ static int sam4_protect_check(struct flash_bank *bank)
{
int r;
uint32_t v[4] = {0};
- unsigned x;
+ unsigned int x;
struct sam4_bank_private *private;
LOG_DEBUG("Begin");
@@ -2557,7 +2557,7 @@ static int sam4_get_details(struct sam4_bank_private *private)
const struct sam4_chip_details *details;
struct sam4_chip *chip;
struct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS];
- unsigned x;
+ unsigned int x;
LOG_DEBUG("Begin");
details = all_sam4_details;
@@ -2796,7 +2796,7 @@ static int sam4_protect(struct flash_bank *bank, int set, unsigned int first,
}
-static int sam4_page_read(struct sam4_bank_private *private, unsigned pagenum, uint8_t *buf)
+static int sam4_page_read(struct sam4_bank_private *private, unsigned int pagenum, uint8_t *buf)
{
uint32_t adr;
int r;
@@ -2841,7 +2841,7 @@ static int sam4_set_wait(struct sam4_bank_private *private)
return r;
}
-static int sam4_page_write(struct sam4_bank_private *private, unsigned pagenum, const uint8_t *buf)
+static int sam4_page_write(struct sam4_bank_private *private, unsigned int pagenum, const uint8_t *buf)
{
uint32_t adr;
uint32_t status;
@@ -2891,10 +2891,10 @@ static int sam4_write(struct flash_bank *bank,
uint32_t count)
{
int n;
- unsigned page_cur;
- unsigned page_end;
+ unsigned int page_cur;
+ unsigned int page_end;
int r;
- unsigned page_offset;
+ unsigned int page_offset;
struct sam4_bank_private *private;
uint8_t *pagebuffer;
@@ -3045,7 +3045,7 @@ COMMAND_HANDLER(sam4_handle_info_command)
if (!chip)
return ERROR_OK;
- unsigned x;
+ unsigned int x;
int r;
/* bank0 must exist before we can do anything */
@@ -3097,7 +3097,7 @@ need_define:
COMMAND_HANDLER(sam4_handle_gpnvm_command)
{
- unsigned x, v;
+ unsigned int x, v;
int r, who;
struct sam4_chip *chip;
diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c
index 36298f1..0f7b0bb 100644
--- a/src/flash/nor/at91samd.c
+++ b/src/flash/nor/at91samd.c
@@ -365,7 +365,7 @@ static const struct samd_family *samd_find_family(uint32_t id)
uint8_t family = SAMD_GET_FAMILY(id);
uint8_t series = SAMD_GET_SERIES(id);
- for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(samd_families); i++) {
if (samd_families[i].processor == processor &&
samd_families[i].series == series &&
samd_families[i].family == family)
@@ -387,7 +387,7 @@ static const struct samd_part *samd_find_part(uint32_t id)
if (!family)
return NULL;
- for (unsigned i = 0; i < family->num_parts; i++) {
+ for (unsigned int i = 0; i < family->num_parts; i++) {
if (family->parts[i].id == devsel)
return &family->parts[i];
}
diff --git a/src/flash/nor/ath79.c b/src/flash/nor/ath79.c
index 1d1ec02..7ce42b2 100644
--- a/src/flash/nor/ath79.c
+++ b/src/flash/nor/ath79.c
@@ -513,7 +513,7 @@ static int ath79_erase(struct flash_bank *bank, unsigned int first,
if (ath79_info->dev->erase_cmd == 0x00)
return ERROR_FLASH_OPER_UNSUPPORTED;
- for (unsigned sector = first; sector <= last; sector++) {
+ for (unsigned int sector = first; sector <= last; sector++) {
if (bank->sectors[sector].is_protected) {
LOG_ERROR("Flash sector %u protected", sector);
return ERROR_FAIL;
diff --git a/src/flash/nor/atsame5.c b/src/flash/nor/atsame5.c
index c590081..f34958f 100644
--- a/src/flash/nor/atsame5.c
+++ b/src/flash/nor/atsame5.c
@@ -85,6 +85,9 @@
#define SAME_SERIES_51 0x01
#define SAME_SERIES_53 0x03
#define SAME_SERIES_54 0x04
+#define PIC32CXSG_SERIES_41 0x07
+#define PIC32CXSG_SERIES_60 0x00
+#define PIC32CXSG_SERIES_61 0x02
/* Device ID macros */
#define SAMD_GET_PROCESSOR(id) (id >> 28)
@@ -148,6 +151,27 @@ static const struct samd_part same54_parts[] = {
{ 0x03, "SAME54N19A", 512, 192 },
};
+/* See PIC32CX SG41/SG60/SG61 Family Silicon Errata and Datasheet Clarifications
+ * DS80000985G */
+/* Known PIC32CX-SG41 parts. */
+static const struct samd_part pic32cxsg41_parts[] = {
+ { 0x00, "PIC32CX1025SG41128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG41100", 1024, 256 },
+ { 0x02, "PIC32CX1025SG41064", 1024, 256 },
+};
+
+/* Known PIC32CX-SG60 parts. */
+static const struct samd_part pic32cxsg60_parts[] = {
+ { 0x00, "PIC32CX1025SG60128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG60100", 1024, 256 },
+};
+
+/* Known PIC32CX-SG61 parts. */
+static const struct samd_part pic32cxsg61_parts[] = {
+ { 0x00, "PIC32CX1025SG61128", 1024, 256 },
+ { 0x01, "PIC32CX1025SG61100", 1024, 256 },
+};
+
/* Each family of parts contains a parts table in the DEVSEL field of DID. The
* processor ID, family ID, and series ID are used to determine which exact
* family this is and then we can use the corresponding table. */
@@ -169,6 +193,12 @@ static const struct samd_family samd_families[] = {
same53_parts, ARRAY_SIZE(same53_parts) },
{ SAMD_PROCESSOR_M4, SAMD_FAMILY_E, SAME_SERIES_54,
same54_parts, ARRAY_SIZE(same54_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_41,
+ pic32cxsg41_parts, ARRAY_SIZE(pic32cxsg41_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_60,
+ pic32cxsg60_parts, ARRAY_SIZE(pic32cxsg60_parts) },
+ { SAMD_PROCESSOR_M4, SAMD_FAMILY_E, PIC32CXSG_SERIES_61,
+ pic32cxsg61_parts, ARRAY_SIZE(pic32cxsg61_parts) },
};
struct samd_info {
@@ -194,7 +224,7 @@ static const struct samd_family *samd_find_family(uint32_t id)
uint8_t family = SAMD_GET_FAMILY(id);
uint8_t series = SAMD_GET_SERIES(id);
- for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(samd_families); i++) {
if (samd_families[i].processor == processor &&
samd_families[i].series == series &&
samd_families[i].family == family)
@@ -216,7 +246,7 @@ static const struct samd_part *samd_find_part(uint32_t id)
if (!family)
return NULL;
- for (unsigned i = 0; i < family->num_parts; i++) {
+ for (unsigned int i = 0; i < family->num_parts; i++) {
if (family->parts[i].id == devsel)
return &family->parts[i];
}
diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c
index 24c432c..d6d8938 100644
--- a/src/flash/nor/atsamv.c
+++ b/src/flash/nor/atsamv.c
@@ -55,8 +55,8 @@
struct samv_flash_bank {
bool probed;
- unsigned size_bytes;
- unsigned gpnvm[SAMV_NUM_GPNVM_BITS];
+ unsigned int size_bytes;
+ unsigned int gpnvm[SAMV_NUM_GPNVM_BITS];
};
/* The actual sector size of the SAMV7 flash memory is 128K bytes.
@@ -82,7 +82,7 @@ static int samv_efc_get_result(struct target *target, uint32_t *v)
}
static int samv_efc_start_command(struct target *target,
- unsigned command, unsigned argument)
+ unsigned int command, unsigned int argument)
{
uint32_t v;
samv_efc_get_status(target, &v);
@@ -100,7 +100,7 @@ static int samv_efc_start_command(struct target *target,
}
static int samv_efc_perform_command(struct target *target,
- unsigned command, unsigned argument, uint32_t *status)
+ unsigned int command, unsigned int argument, uint32_t *status)
{
int r;
uint32_t v;
@@ -166,7 +166,7 @@ static int samv_erase_pages(struct target *target,
first_page | erase_pages, status);
}
-static int samv_get_gpnvm(struct target *target, unsigned gpnvm, unsigned *out)
+static int samv_get_gpnvm(struct target *target, unsigned int gpnvm, unsigned int *out)
{
uint32_t v;
int r;
@@ -190,10 +190,10 @@ static int samv_get_gpnvm(struct target *target, unsigned gpnvm, unsigned *out)
return r;
}
-static int samv_clear_gpnvm(struct target *target, unsigned gpnvm)
+static int samv_clear_gpnvm(struct target *target, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
@@ -209,10 +209,10 @@ static int samv_clear_gpnvm(struct target *target, unsigned gpnvm)
return r;
}
-static int samv_set_gpnvm(struct target *target, unsigned gpnvm)
+static int samv_set_gpnvm(struct target *target, unsigned int gpnvm)
{
int r;
- unsigned v;
+ unsigned int v;
if (gpnvm >= SAMV_NUM_GPNVM_BITS) {
LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS);
return ERROR_FAIL;
@@ -231,7 +231,7 @@ static int samv_set_gpnvm(struct target *target, unsigned gpnvm)
}
static int samv_flash_unlock(struct target *target,
- unsigned start_sector, unsigned end_sector)
+ unsigned int start_sector, unsigned int end_sector)
{
int r;
uint32_t status;
@@ -251,7 +251,7 @@ static int samv_flash_unlock(struct target *target,
}
static int samv_flash_lock(struct target *target,
- unsigned start_sector, unsigned end_sector)
+ unsigned int start_sector, unsigned int end_sector)
{
uint32_t status;
uint32_t pg;
@@ -419,7 +419,7 @@ static int samv_protect(struct flash_bank *bank, int set, unsigned int first,
}
static int samv_page_read(struct target *target,
- unsigned page_num, uint8_t *buf)
+ unsigned int page_num, uint8_t *buf)
{
uint32_t addr = SAMV_FLASH_BASE + page_num * SAMV_PAGE_SIZE;
int r = target_read_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);
@@ -430,7 +430,7 @@ static int samv_page_read(struct target *target,
}
static int samv_page_write(struct target *target,
- unsigned pagenum, const uint8_t *buf)
+ unsigned int pagenum, const uint8_t *buf)
{
uint32_t status;
const uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE;
@@ -618,7 +618,7 @@ COMMAND_HANDLER(samv_handle_gpnvm_command)
return ERROR_COMMAND_SYNTAX_ERROR;
}
- unsigned v = 0;
+ unsigned int v = 0;
if (!strcmp("show", CMD_ARGV[0])) {
if (who == -1) {
showall:
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 78bc91e..2a15e49 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -806,7 +806,7 @@ int cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **
}
bank->driver_priv = cfi_info;
- for (unsigned i = 6; i < argc; i++) {
+ for (unsigned int i = 6; i < argc; i++) {
if (strcmp(argv[i], "x16_as_x8") == 0)
cfi_info->x16_as_x8 = true;
else if (strcmp(argv[i], "data_swap") == 0)
@@ -2219,8 +2219,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u
uint8_t current_word[CFI_MAX_BUS_WIDTH];
int retval;
- LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
- (int)count, (unsigned)offset);
+ LOG_DEBUG("reading buffer of %" PRIi32 " byte at 0x%8.8" PRIx32, count, offset);
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h
index ec7f474..3a76d98 100644
--- a/src/flash/nor/cfi.h
+++ b/src/flash/nor/cfi.h
@@ -58,10 +58,10 @@ struct cfi_flash_bank {
void *alt_ext;
/* calculated timeouts */
- unsigned word_write_timeout;
- unsigned buf_write_timeout;
- unsigned block_erase_timeout;
- unsigned chip_erase_timeout;
+ unsigned int word_write_timeout;
+ unsigned int buf_write_timeout;
+ unsigned int block_erase_timeout;
+ unsigned int chip_erase_timeout;
/* memory accessors */
int (*write_mem)(struct flash_bank *bank, target_addr_t addr,
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 5e6c971..5c4f2ac 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -164,7 +164,7 @@ int default_flash_verify(struct flash_bank *bank,
void flash_bank_add(struct flash_bank *bank)
{
/* put flash bank in linked list */
- unsigned bank_num = 0;
+ unsigned int bank_num = 0;
if (flash_banks) {
/* find last flash bank */
struct flash_bank *p = flash_banks;
@@ -242,8 +242,8 @@ void flash_free_all_banks(void)
struct flash_bank *get_flash_bank_by_name_noprobe(const char *name)
{
- unsigned requested = get_flash_name_index(name);
- unsigned found = 0;
+ unsigned int requested = get_flash_name_index(name);
+ unsigned int found = 0;
struct flash_bank *bank;
for (bank = flash_banks; bank; bank = bank->next) {
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
index ff175a1..f8cf5e2 100644
--- a/src/flash/nor/core.h
+++ b/src/flash/nor/core.h
@@ -250,7 +250,7 @@ int get_flash_bank_by_num(unsigned int num, struct flash_bank **bank);
* @param bank On output, contains a pointer to the bank or NULL.
* @returns ERROR_OK on success, or an error indicating the problem.
*/
-COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
+COMMAND_HELPER(flash_command_get_bank, unsigned int name_index,
struct flash_bank **bank);
/**
* Retrieves @a bank from a command argument, reporting errors parsing
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 211661e..794566f 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -254,6 +254,7 @@ extern const struct flash_driver cc26xx_flash;
extern const struct flash_driver cc3220sf_flash;
extern const struct flash_driver cfi_flash;
extern const struct flash_driver dsp5680xx_flash;
+extern const struct flash_driver dw_spi_flash;
extern const struct flash_driver efm32_flash;
extern const struct flash_driver em357_flash;
extern const struct flash_driver eneispif_flash;
@@ -273,6 +274,7 @@ extern const struct flash_driver max32xxx_flash;
extern const struct flash_driver mdr_flash;
extern const struct flash_driver mrvlqspi_flash;
extern const struct flash_driver msp432_flash;
+extern const struct flash_driver mspm0_flash;
extern const struct flash_driver niietcm4_flash;
extern const struct flash_driver npcx_flash;
extern const struct flash_driver nrf51_flash;
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index 3435988..67d8624 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -31,6 +31,7 @@ static const struct flash_driver * const flash_drivers[] = {
&cc26xx_flash,
&cfi_flash,
&dsp5680xx_flash,
+ &dw_spi_flash,
&efm32_flash,
&em357_flash,
&eneispif_flash,
@@ -50,6 +51,7 @@ static const struct flash_driver * const flash_drivers[] = {
&mdr_flash,
&mrvlqspi_flash,
&msp432_flash,
+ &mspm0_flash,
&niietcm4_flash,
&npcx_flash,
&nrf5_flash,
@@ -91,7 +93,7 @@ static const struct flash_driver * const flash_drivers[] = {
const struct flash_driver *flash_driver_find_by_name(const char *name)
{
- for (unsigned i = 0; flash_drivers[i]; i++) {
+ for (unsigned int i = 0; flash_drivers[i]; i++) {
if (strcmp(name, flash_drivers[i]->name) == 0)
return flash_drivers[i];
}
diff --git a/src/flash/nor/dw-spi-helper.h b/src/flash/nor/dw-spi-helper.h
new file mode 100644
index 0000000..d353755
--- /dev/null
+++ b/src/flash/nor/dw-spi-helper.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/**
+ * @file
+ * Driver for SPI NOR flash chips connected via DesignWare SPI Core.
+ *
+ * In order to avoid using stack, all helper function arguments are packed
+ * into a single struct, passed by pointer.
+ *
+ * Pointers are represented by 64 bit integers to make structs compatible
+ * with 64 bit targets.
+ *
+ * This file contains helper function argument structures.
+ */
+
+#ifndef OPENOCD_FLASH_NOR_DW_SPI_HELPER_H
+#define OPENOCD_FLASH_NOR_DW_SPI_HELPER_H
+
+#include <stdint.h>
+
+/**
+ * @brief Arguments for transaction helper function.
+ */
+struct dw_spi_transaction {
+ uint64_t buffer;
+ ///< Pointer to data buffer to send over SPI.
+ ///< Return values are stored in place of output data when
+ ///< dw_spi_transaction::read_flag is 1.
+ uint32_t size; ///< Size of dw_spi_transaction::buffer.
+ uint64_t status_reg; ///< Pointer to SR register.
+ uint64_t data_reg; ///< Pointer to DR register.
+ uint8_t read_flag;
+ ///< When 1, store RX FIFO data to dw_spi_transaction::buffer.
+} __attribute__((packed));
+
+/**
+ * @brief Arguments for check_fill helper function.
+ */
+struct dw_spi_check_fill {
+ uint32_t address; ///< Starting address. Sector aligned.
+ uint32_t sector_size; ///< Sector size.
+ uint32_t sector_count; ///< Number of sectors to check.
+ uint64_t status_reg; ///< Pointer to SR register.
+ uint64_t data_reg; ///< Pointer to DR register.
+ uint64_t fill_status_array;
+ ///< Pointer to array describing sectors fill status.
+ ///< 1 if filled, 0 if not filled.
+ uint8_t pattern; ///< Fill pattern.
+ uint8_t read_cmd; ///< Read data command.
+ uint8_t four_byte_mode; ///< Four byte addressing mode flag.
+} __attribute__((packed));
+
+/**
+ * @brief Arguments for erase helper function.
+ */
+struct dw_spi_erase {
+ uint32_t address; ///< First sector address. Sector aligned.
+ uint32_t sector_size; ///< Sector size.
+ uint32_t sector_count; ///< Number of sectors to erase.
+ uint64_t status_reg; ///< Pointer to SR register.
+ uint64_t data_reg; ///< Pointer to DR register.
+ uint8_t read_status_cmd; ///< Read status command.
+ uint8_t write_enable_cmd; ///< Write enable command.
+ uint8_t erase_sector_cmd; ///< Erase sector command.
+ uint8_t write_enable_mask; ///< Write enable mask.
+ uint8_t busy_mask; ///< Busy mask.
+ uint8_t four_byte_mode; ///< Four byte addressing mode flag.
+} __attribute__((packed));
+
+/**
+ * @brief Arguments for program helper function.
+ */
+struct dw_spi_program {
+ uint32_t address;
+ ///< First page address. Page aligned when write is crossing
+ ///< the page boundary.
+ uint32_t page_size; ///< Page size.
+ uint64_t buffer; ///< Data buffer pointer.
+ uint32_t buffer_size; ///< Size of dw_spi_program::buffer.
+ uint64_t status_reg; ///< Pointer to SR register.
+ uint64_t data_reg; ///< Pointer to DR register.
+ uint8_t read_status_cmd; ///< Read status command.
+ uint8_t write_enable_cmd; ///< Write enable command.
+ uint8_t program_cmd; ///< Program command.
+ uint8_t write_enable_mask; ///< Write enable mask.
+ uint8_t busy_mask; ///< Busy mask.
+ uint8_t four_byte_mode; ///< Four byte addressing mode flag.
+} __attribute__((packed));
+
+/**
+ * @brief Arguments for read helper function.
+ */
+struct dw_spi_read {
+ uint32_t address; ///< First sector address.
+ uint64_t buffer; ///< Data buffer pointer.
+ uint32_t buffer_size; ///< Size of dw_spi_read::buffer.
+ uint64_t status_reg; ///< Pointer to SR register.
+ uint64_t data_reg; ///< Pointer to DR register.
+ uint8_t read_cmd; ///< Read data command.
+ uint8_t four_byte_mode; ///< Four byte addressing mode flag.
+} __attribute__((packed));
+
+#endif /* OPENOCD_FLASH_NOR_DW_SPI_HELPER_H */
diff --git a/src/flash/nor/dw-spi.c b/src/flash/nor/dw-spi.c
new file mode 100644
index 0000000..e196547
--- /dev/null
+++ b/src/flash/nor/dw-spi.c
@@ -0,0 +1,1608 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/**
+ * @file
+ * Driver for SPI NOR flash chips connected via DesignWare SPI Core.
+ * Controller's Linux driver is located at drivers/spi/spi-dw-mmio.c.
+ * DW-SPI is used in a number of processors, including Microsemi Jaguar2 and
+ * Ocelot switch chips.
+ *
+ * Serial interface (SI) nCS0 pin, which is usually connected to the external
+ * flash, cannot be controlled via GPIO controller: it is asserted only when
+ * TX FIFO is not empty. Since JTAG is not fast enough to fill TX FIFO and
+ * collect data from RX FIFO at the same time even on the slowest SPI clock
+ * speeds, driver can only operate using functions, loaded in target's memory.
+ * Therefore, it requires the user to set up DRAM controller and provide
+ * work-area.
+ *
+ * In Microsemi devices, serial interface pins may be governed either
+ * by Boot or Master controller. For these devices, additional configuration of
+ * spi_mst address is required to switch between the two.
+ *
+ * Currently supported devices typically have much more RAM then NOR Flash
+ * (Jaguar2 reference design has 256MB RAM and 32MB NOR Flash), so supporting
+ * work-area sizes smaller then transfer buffer seems like the unnecessary
+ * complication.
+ *
+ * This code was tested on Jaguar2 VSC7448 connected to Macronix MX25L25635F.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dw-spi-helper.h"
+#include "imp.h"
+#include "spi.h"
+
+#include <helper/bits.h>
+#include <helper/time_support.h>
+#include <target/algorithm.h>
+#include <target/breakpoints.h>
+#include <target/mips32.h>
+#include <target/target_type.h>
+
+/**
+ * @brief IP block placement map.
+ *
+ * Used for dynamic definition of the register map.
+ *
+ * IP block is used on different chips and placed in different locations.
+ * This structure defines some implementation specific variables.
+ */
+struct dw_spi_regmap {
+ uint32_t freq; ///< Clock frequency.
+ target_addr_t simc; ///< Absolute offset of SIMC register block.
+ target_addr_t spi_mst;
+ ///< Absolute offset of ICPU_CFG:SPI_MST register. 0 if not available.
+ uint8_t si_if_owner_offset;
+ ///< Offset of \ref si_mode bits in ICPU_CFG:SPI_MST.
+};
+
+/**
+ * @brief Register map for Jaguar2 switch devices.
+ */
+static const struct dw_spi_regmap jaguar2_regmap = {
+ .freq = 250000000UL,
+ .simc = 0x70101000UL,
+ .spi_mst = 0x70000024UL,
+ .si_if_owner_offset = 6,
+};
+
+/**
+ * @brief Register map for Ocelot switch devices.
+ */
+static const struct dw_spi_regmap ocelot_regmap = {
+ .freq = 250000000UL,
+ .simc = 0x70101000UL,
+ .spi_mst = 0x70000024UL,
+ .si_if_owner_offset = 4,
+};
+
+#define DW_SPI_IF_OWNER_WIDTH 2 ///< IF owner register field width.
+
+/**
+ * @brief Owner of the SI interface.
+ */
+enum dw_spi_si_mode {
+ DW_SPI_SI_MODE_BOOT = 1,
+ ///< Boot controller maps contents of SPI Flash to memory in read-only mode.
+ DW_SPI_SI_MODE_MASTER = 2,
+ ///< SPI controller mode for reading/writing SPI Flash.
+};
+
+#define DW_SPI_REG_CTRLR0 0x00 ///< General configuration register.
+#define DW_SPI_REG_SIMCEN 0x08 ///< Master controller enable register.
+#define DW_SPI_REG_SER 0x10 ///< Slave select register.
+#define DW_SPI_REG_BAUDR 0x14 ///< Baud rate configuration register.
+#define DW_SPI_REG_SR 0x28 ///< Status register.
+#define DW_SPI_REG_IMR 0x2c ///< Interrupt configuration register.
+#define DW_SPI_REG_DR 0x60 ///< Data register.
+
+#define DW_SPI_REG_CTRLR0_DFS(x) ((x) & GENMASK(3, 0)) ///< Data frame size.
+#define DW_SPI_REG_CTRLR0_FRF(x) (((x) << 4) & GENMASK(5, 4)) ///< SI protocol.
+#define DW_SPI_REG_CTRLR0_SCPH(x) ((!!(x)) << 6) ///< Probe position.
+#define DW_SPI_REG_CTRLR0_SCPOL(x) ((!!(x)) << 7) ///< Probe polarity.
+#define DW_SPI_REG_CTRLR0_TMOD(x) (((x) << 8) & GENMASK(9, 8)) ///< SI mode.
+#define DW_SPI_REG_SIMCEN_SIMCEN(x) (!!(x)) ///< Controller enable.
+#define DW_SPI_REG_SER_SER(x) ((x) & GENMASK(15, 0)) ///< Slave select bitmask.
+#define DW_SPI_REG_BAUDR_SCKDV(x) ((x) & GENMASK(15, 0)) ///< Clock divisor.
+
+/**
+ * @brief Driver private state.
+ */
+struct dw_spi_driver {
+ bool probed; ///< Bank is probed.
+ uint32_t id; ///< Chip ID.
+ unsigned int speed; ///< Flash speed.
+ unsigned int timeout; ///< Flash timeout in milliseconds.
+ uint8_t chip_select_bitmask; ///< Chip select bitmask.
+ bool four_byte_mode; ///< Flash chip is in 32bit address mode.
+ enum dw_spi_si_mode saved_ctrl_mode;
+ ///< Previously selected controller mode.
+ struct dw_spi_regmap regmap; ///< SI controller regmap.
+ const struct flash_device *spi_flash; ///< SPI flash device info.
+};
+
+/**
+ * @brief Register used to pass argument struct to helper functions.
+ */
+#define DW_SPI_ARG_REG "r4"
+
+/**
+ * @brief Default timeout value in ms for flash transaction jobs.
+ */
+#define DW_SPI_TIMEOUT_DEFAULT (600 * 1000)
+
+/**
+ * @brief Timeout value in ms for short flash transactions,
+ * e.g. reading flash ID and status register.
+ */
+#define DW_SPI_TIMEOUT_TRANSACTION 1000
+
+/**
+ * @brief Select SI interface owner.
+ *
+ * Mode selection is skipped if Boot controller not available on target
+ * (i.e. spi_mst command argument is not configured).
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] mode: New controller mode.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_mode(const struct flash_bank *const bank, enum dw_spi_si_mode mode)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ if (!regmap->spi_mst)
+ return ERROR_OK;
+
+ uint32_t ctrl;
+ int ret = target_read_u32(target, regmap->spi_mst, &ctrl);
+ if (ret) {
+ LOG_ERROR("DW SPI SPI:MST register read error");
+ return ret;
+ }
+ ctrl &= ~GENMASK(DW_SPI_IF_OWNER_WIDTH + driver->regmap.si_if_owner_offset,
+ driver->regmap.si_if_owner_offset);
+ ctrl |= mode << driver->regmap.si_if_owner_offset;
+
+ ret = target_write_u32(target, regmap->spi_mst, ctrl);
+ if (ret)
+ LOG_ERROR("DW SPI controller mode configuration error");
+
+ return ret;
+}
+
+/**
+ * @brief Select master controller as SI interface owner.
+ *
+ * Previous interface owner is restored via dw_spi_ctrl_mode_restore() function.
+ * Mode selection is skipped if Boot controller not available on target
+ * (i.e. spi_mst command argument is not configured).
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] mode: New controller mode.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_mode_configure(const struct flash_bank *const bank,
+ enum dw_spi_si_mode mode)
+{
+ struct target *const target = bank->target;
+ struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ if (!regmap->spi_mst)
+ return ERROR_OK;
+
+ uint32_t ctrl;
+ int ret = target_read_u32(target, regmap->spi_mst, &ctrl);
+ if (ret) {
+ LOG_ERROR("DW SPI controller mode query error");
+ return ret;
+ }
+ driver->saved_ctrl_mode =
+ (enum dw_spi_si_mode)((ctrl >> driver->regmap.si_if_owner_offset) &
+ GENMASK(DW_SPI_IF_OWNER_WIDTH, 0));
+
+ return dw_spi_ctrl_mode(bank, mode);
+}
+
+/**
+ * @brief Restore SI controller mode.
+ *
+ * Restore initially configured SI controller mode. Undo configuration done by
+ * dw_spi_ctrl_mode_configure() function.
+ * Mode selection is skipped if Boot controller not available on target
+ * (i.e. spi_mst command argument is not configured).
+ *
+ * @param[in] bank: Flash bank.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_mode_restore(const struct flash_bank *const bank)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+
+ return dw_spi_ctrl_mode(bank, driver->saved_ctrl_mode);
+}
+
+/**
+ * @brief Enable master controller.
+ *
+ * Configuration of the master controller must be done when it is disabled.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] value: New enable state.
+ * @return Command execution status.
+ */
+static int
+dw_spi_master_ctrl_enable(const struct flash_bank *const bank, bool value)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SIMCEN,
+ DW_SPI_REG_SIMCEN_SIMCEN(value));
+ if (ret)
+ LOG_ERROR("DW SPI master controller enable flag configuration error");
+
+ return ret;
+}
+
+/**
+ * @brief Configure SI transfer mode.
+ *
+ * @param[in] bank: Flash bank.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_configure_si(const struct flash_bank *const bank)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ // 8 bit frame; Motorola protocol; middle lo probe; TX RX mode
+ const uint32_t mode = DW_SPI_REG_CTRLR0_DFS(0x7) |
+ DW_SPI_REG_CTRLR0_FRF(0) |
+ DW_SPI_REG_CTRLR0_SCPH(0) |
+ DW_SPI_REG_CTRLR0_SCPOL(0) |
+ DW_SPI_REG_CTRLR0_TMOD(0);
+
+ int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_CTRLR0, mode);
+ if (ret) {
+ LOG_ERROR("DW SPI master controller configuration query error");
+ return ret;
+ }
+
+ ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SER,
+ DW_SPI_REG_SER_SER(driver->chip_select_bitmask));
+ if (ret)
+ LOG_ERROR("DW SPI slave select configuration error");
+
+ return ret;
+}
+
+/**
+ * @brief Configure SI transfer speed.
+ *
+ * @param[in] bank: Flash bank.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_configure_speed(const struct flash_bank *const bank)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ // divisor LSB must be zero
+ const uint16_t div = MIN((regmap->freq / driver->speed), 0xfffe) & 0xfffe;
+
+ int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_BAUDR,
+ DW_SPI_REG_BAUDR_SCKDV(div));
+ if (ret) {
+ LOG_ERROR("DW SPI speed configuration error");
+ return ret;
+ }
+
+ unsigned int speed = regmap->freq / div;
+ LOG_DEBUG("DW SPI setting NOR controller speed to %u kHz", speed / 1000);
+
+ return ret;
+}
+
+/**
+ * @brief Disable SI master controller interrupts.
+ *
+ * @param[in] bank: Flash bank.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_disable_interrupts(const struct flash_bank *const bank)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_IMR, 0);
+ if (ret)
+ LOG_ERROR("DW SPI disable interrupts error");
+
+ return ret;
+}
+
+/**
+ * @brief Do data transaction.
+ *
+ * Buffer data are sent and replaced with received data. Total buffer size
+ * is a sum of TX and RX messages. RX portion of the buffer is initially
+ * filled with dummy values, which get replaced by the message.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in,out] buffer: Data buffer. If \p read flag is set, buffer is
+ * filled with received data.
+ * @param[in] size: \p buffer size.
+ * @param[in] read: The read flag. If set to true, read values will override
+ * \p buffer.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_transaction(const struct flash_bank *const bank,
+ uint8_t *const buffer, size_t size, bool read)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ static const uint8_t target_code[] = {
+#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc"
+ };
+ const size_t target_code_size = sizeof(target_code);
+ const size_t total_working_area_size =
+ target_code_size + sizeof(struct dw_spi_transaction) + size;
+
+ // allocate working area, memory args and data buffer
+ struct working_area *helper;
+ int ret = target_alloc_working_area(target, target_code_size, &helper);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper;
+ }
+
+ struct working_area *helper_args;
+ ret = target_alloc_working_area(target, sizeof(struct dw_spi_transaction),
+ &helper_args);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper_args;
+ }
+
+ struct working_area *target_buffer;
+ ret = target_alloc_working_area(target, size, &target_buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_target_buffer;
+ }
+
+ // write algorithm code and buffer to working areas
+ ret = target_write_buffer(target, helper->address, target_code_size,
+ target_code);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ ret = target_write_buffer(target, target_buffer->address, size, buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ // prepare helper execution
+ struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
+ .isa_mode = MIPS32_ISA_MIPS32 };
+
+ struct reg_param reg_param;
+ init_reg_param(&reg_param, DW_SPI_ARG_REG, 32, PARAM_OUT);
+ struct mem_param mem_param;
+ init_mem_param(&mem_param, helper_args->address, helper_args->size,
+ PARAM_OUT);
+
+ // Set the arguments for the helper
+ buf_set_u32(reg_param.value, 0, 32, helper_args->address);
+
+ struct dw_spi_transaction *helper_args_val =
+ (struct dw_spi_transaction *)mem_param.value;
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
+ target_buffer->address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->size, size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
+ regmap->simc + DW_SPI_REG_SR);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
+ regmap->simc + DW_SPI_REG_DR);
+ helper_args_val->read_flag = read;
+
+ ret = target_run_algorithm(target, 1, &mem_param, 1, &reg_param,
+ helper->address, 0, DW_SPI_TIMEOUT_TRANSACTION,
+ &mips32_algo);
+
+ if (ret) {
+ LOG_ERROR("DW SPI flash algorithm error");
+ goto cleanup;
+ }
+
+ if (read) {
+ ret = target_read_buffer(target, target_buffer->address, size, buffer);
+ if (ret)
+ LOG_ERROR("DW SPI target buffer read error");
+ }
+
+cleanup:
+ destroy_reg_param(&reg_param);
+ destroy_mem_param(&mem_param);
+
+err_write_buffer:
+ target_free_working_area(target, target_buffer);
+err_target_buffer:
+ target_free_working_area(target, helper_args);
+err_helper_args:
+ target_free_working_area(target, helper);
+err_helper:
+
+ return ret;
+}
+
+/**
+ * @brief Check that selected region is filled with pattern.
+ *
+ * This function is used for Flash erase checking.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] address: Starting address. Sector aligned.
+ * @param[in] sector_size: Size of sector.
+ * @param[in] sector_count: Number of sectors.
+ * @param[in] pattern: Fill pattern.
+ * @param[in] read_cmd: Flash read command.
+ * @param[out] buffer: Filled flag array. Must hold \p sector_count number
+ * of entries.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_check_sectors_fill(const struct flash_bank *const bank,
+ uint32_t address, size_t sector_size,
+ size_t sector_count, uint8_t pattern,
+ uint8_t read_cmd, uint8_t *buffer)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ static const uint8_t target_code[] = {
+#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc"
+ };
+ const size_t target_code_size = sizeof(target_code);
+ const size_t total_working_area_size =
+ target_code_size + sizeof(struct dw_spi_check_fill) + sector_count;
+
+ // allocate working area, memory args and data buffer
+ struct working_area *helper;
+ int ret = target_alloc_working_area(target, target_code_size, &helper);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper;
+ }
+
+ struct working_area *helper_args;
+ ret = target_alloc_working_area(target, sizeof(struct dw_spi_check_fill),
+ &helper_args);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper_args;
+ }
+
+ struct working_area *target_buffer;
+ ret = target_alloc_working_area(target, sector_count, &target_buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_target_buffer;
+ }
+
+ // write algorithm code and buffer to working areas
+ ret = target_write_buffer(target, helper->address, target_code_size,
+ target_code);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ // prepare helper execution
+ struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
+ .isa_mode = MIPS32_ISA_MIPS32 };
+
+ struct reg_param reg_param;
+ init_reg_param(&reg_param, DW_SPI_ARG_REG, 32, PARAM_OUT);
+ struct mem_param mem_param;
+ init_mem_param(&mem_param, helper_args->address, helper_args->size,
+ PARAM_OUT);
+
+ // Set the arguments for the helper
+ buf_set_u32(reg_param.value, 0, 32, helper_args->address);
+
+ struct dw_spi_check_fill *helper_args_val =
+ (struct dw_spi_check_fill *)mem_param.value;
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
+ address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size,
+ sector_size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count,
+ sector_count);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
+ regmap->simc + DW_SPI_REG_SR);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
+ regmap->simc + DW_SPI_REG_DR);
+ target_buffer_set_u32(target,
+ (uint8_t *)&helper_args_val->fill_status_array,
+ target_buffer->address);
+ helper_args_val->pattern = pattern;
+ helper_args_val->read_cmd = read_cmd;
+ helper_args_val->four_byte_mode = driver->four_byte_mode;
+
+ ret = target_run_algorithm(target, 1, &mem_param, 1, &reg_param,
+ helper->address, 0, driver->timeout,
+ &mips32_algo);
+
+ if (ret) {
+ LOG_ERROR("DW SPI flash algorithm error");
+ goto cleanup;
+ }
+
+ ret = target_read_buffer(target, target_buffer->address, sector_count,
+ buffer);
+ if (ret)
+ LOG_ERROR("DW SPI target buffer read error");
+
+cleanup:
+ destroy_reg_param(&reg_param);
+ destroy_mem_param(&mem_param);
+
+err_write_buffer:
+ target_free_working_area(target, target_buffer);
+err_target_buffer:
+ target_free_working_area(target, helper_args);
+err_helper_args:
+ target_free_working_area(target, helper);
+err_helper:
+
+ return ret;
+}
+
+/**
+ * @brief Write flash region.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] address: First page address. Page aligned when write is crossing
+ * the page boundary.
+ * @param[in] buffer: Data buffer.
+ * @param[in] buffer_size: \p buffer size.
+ * @param[in] page_size: Size of flash page.
+ * @param[in] stat_cmd: Flash command to read chip status.
+ * @param[in] we_cmd: Flash command to enable write.
+ * @param[in] program_cmd: Flash command to program chip.
+ * @param[in] we_mask: Status byte write enable mask.
+ * @param[in] busy_mask: Status byte write busy mask.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_program(const struct flash_bank *const bank, uint32_t address,
+ const uint8_t *const buffer, size_t buffer_size,
+ uint32_t page_size, uint8_t stat_cmd, uint8_t we_cmd,
+ uint8_t program_cmd, uint8_t we_mask, uint8_t busy_mask)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ static const uint8_t target_code[] = {
+#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc"
+ };
+ const size_t target_code_size = sizeof(target_code);
+ const size_t total_working_area_size =
+ target_code_size + sizeof(struct dw_spi_program) + buffer_size;
+
+ // allocate working area, memory args and data buffer
+ struct working_area *helper;
+ int ret = target_alloc_working_area(target, target_code_size, &helper);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper;
+ }
+
+ struct working_area *helper_args;
+ ret = target_alloc_working_area(target, sizeof(struct dw_spi_program),
+ &helper_args);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper_args;
+ }
+
+ struct working_area *target_buffer;
+ ret = target_alloc_working_area(target, buffer_size, &target_buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_target_buffer;
+ }
+
+ // write algorithm code and buffer to working areas
+ ret = target_write_buffer(target, helper->address, target_code_size,
+ target_code);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ ret = target_write_buffer(target, target_buffer->address, buffer_size,
+ buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ // prepare helper execution
+ struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
+ .isa_mode = MIPS32_ISA_MIPS32 };
+
+ struct reg_param reg_param;
+ init_reg_param(&reg_param, DW_SPI_ARG_REG, 32, PARAM_OUT);
+ struct mem_param mem_param;
+ init_mem_param(&mem_param, helper_args->address, helper_args->size,
+ PARAM_OUT);
+
+ // Set the arguments for the helper
+ buf_set_u32(reg_param.value, 0, 32, helper_args->address);
+ struct dw_spi_program *helper_args_val =
+ (struct dw_spi_program *)mem_param.value;
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
+ address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->page_size,
+ page_size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
+ target_buffer->address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size,
+ buffer_size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
+ regmap->simc + DW_SPI_REG_SR);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
+ regmap->simc + DW_SPI_REG_DR);
+ helper_args_val->read_status_cmd = stat_cmd;
+ helper_args_val->write_enable_cmd = we_cmd;
+ helper_args_val->program_cmd = program_cmd;
+ helper_args_val->write_enable_mask = we_mask;
+ helper_args_val->busy_mask = busy_mask;
+ helper_args_val->four_byte_mode = driver->four_byte_mode;
+
+ ret = target_run_algorithm(target, 1, &mem_param, 1, &reg_param,
+ helper->address, 0, driver->timeout,
+ &mips32_algo);
+ if (ret)
+ LOG_ERROR("DW SPI flash algorithm error");
+
+ destroy_reg_param(&reg_param);
+ destroy_mem_param(&mem_param);
+
+err_write_buffer:
+ target_free_working_area(target, target_buffer);
+err_target_buffer:
+ target_free_working_area(target, helper_args);
+err_helper_args:
+ target_free_working_area(target, helper);
+err_helper:
+
+ return ret;
+}
+
+/**
+ * @brief Erase sectors.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] address: Flash address. Must be sector aligned.
+ * @param[in] sector_size: Size of flash sector.
+ * @param[in] sector_count: Number of sectors to erase.
+ * @param[in] stat_cmd: Flash command to read chip status.
+ * @param[in] we_cmd: Flash command to set enable write.
+ * @param[in] erase_sector_cmd: Flash command to set erase sector.
+ * @param[in] we_mask: Status byte write enable mask.
+ * @param[in] busy_mask: Status byte write busy mask.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_erase_sectors(const struct flash_bank *const bank, uint32_t address,
+ uint32_t sector_size, size_t sector_count,
+ uint8_t stat_cmd, uint8_t we_cmd,
+ uint8_t erase_sector_cmd, uint8_t we_mask,
+ uint8_t busy_mask)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ static const uint8_t target_code[] = {
+#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc"
+ };
+ const size_t target_code_size = sizeof(target_code);
+ const size_t total_working_area_size =
+ target_code_size + sizeof(struct dw_spi_erase);
+
+ // allocate working area and memory args
+ struct working_area *helper;
+ int ret = target_alloc_working_area(target, target_code_size, &helper);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper;
+ }
+
+ struct working_area *helper_args;
+ ret = target_alloc_working_area(target, sizeof(struct dw_spi_erase),
+ &helper_args);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper_args;
+ }
+
+ // write algorithm code to working area
+ ret = target_write_buffer(target, helper->address, target_code_size,
+ target_code);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ // prepare helper execution
+ struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
+ .isa_mode = MIPS32_ISA_MIPS32 };
+
+ struct reg_param reg_param;
+ init_reg_param(&reg_param, DW_SPI_ARG_REG, 32, PARAM_OUT);
+ struct mem_param mem_param;
+ init_mem_param(&mem_param, helper_args->address, helper_args->size,
+ PARAM_OUT);
+
+ // Set the arguments for the helper
+ buf_set_u32(reg_param.value, 0, 32, helper_args->address);
+ struct dw_spi_erase *helper_args_val =
+ (struct dw_spi_erase *)mem_param.value;
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
+ address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size,
+ sector_size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count,
+ sector_count);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
+ regmap->simc + DW_SPI_REG_SR);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
+ regmap->simc + DW_SPI_REG_DR);
+ helper_args_val->read_status_cmd = stat_cmd;
+ helper_args_val->write_enable_cmd = we_cmd;
+ helper_args_val->erase_sector_cmd = erase_sector_cmd;
+ helper_args_val->write_enable_mask = we_mask;
+ helper_args_val->busy_mask = busy_mask;
+ helper_args_val->four_byte_mode = driver->four_byte_mode;
+
+ ret = target_run_algorithm(target, 1, &mem_param, 1, &reg_param,
+ helper->address, 0, driver->timeout,
+ &mips32_algo);
+ if (ret)
+ LOG_ERROR("DW SPI flash algorithm error");
+
+ destroy_reg_param(&reg_param);
+ destroy_mem_param(&mem_param);
+
+err_write_buffer:
+ target_free_working_area(target, helper_args);
+err_helper_args:
+ target_free_working_area(target, helper);
+err_helper:
+
+ return ret;
+}
+
+/**
+ * @brief Read flash data.
+ *
+ * @param[in] bank: Flash bank.
+ * @param[in] address: Flash address.
+ * @param[out] buffer: Data buffer.
+ * @param[in] buffer_size: \p buffer size.
+ * @param[in] read_cmd: Flash command to read data from flash.
+ * @return Command execution status.
+ */
+static int
+dw_spi_ctrl_read(const struct flash_bank *const bank, uint32_t address,
+ uint8_t *buffer, size_t buffer_size, uint8_t read_cmd)
+{
+ struct target *const target = bank->target;
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const struct dw_spi_regmap *const regmap = &driver->regmap;
+
+ static const uint8_t target_code[] = {
+#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc"
+ };
+ const size_t target_code_size = sizeof(target_code);
+ const size_t total_working_area_size =
+ target_code_size + sizeof(struct dw_spi_read) + buffer_size;
+
+ // allocate working area and memory args
+ struct working_area *helper;
+ int ret = target_alloc_working_area(target, target_code_size, &helper);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper;
+ }
+
+ struct working_area *helper_args;
+ ret = target_alloc_working_area(target, sizeof(struct dw_spi_read),
+ &helper_args);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_helper_args;
+ }
+
+ struct working_area *target_buffer;
+ ret = target_alloc_working_area(target, buffer_size, &target_buffer);
+ if (ret) {
+ LOG_ERROR("DW SPI could not allocate working area. Need %zx",
+ total_working_area_size);
+ goto err_target_buffer;
+ }
+
+ // write algorithm code to working area
+ ret = target_write_buffer(target, helper->address, target_code_size,
+ target_code);
+ if (ret) {
+ LOG_ERROR("DW SPI writing to working area error");
+ goto err_write_buffer;
+ }
+
+ // prepare helper execution
+ struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
+ .isa_mode = MIPS32_ISA_MIPS32 };
+
+ struct reg_param reg_param;
+ init_reg_param(&reg_param, DW_SPI_ARG_REG, 32, PARAM_OUT);
+ struct mem_param mem_param;
+ init_mem_param(&mem_param, helper_args->address, helper_args->size,
+ PARAM_OUT);
+
+ // Set the arguments for the helper
+ buf_set_u32(reg_param.value, 0, 32, helper_args->address);
+ struct dw_spi_read *helper_args_val = (struct dw_spi_read *)mem_param.value;
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
+ address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
+ target_buffer->address);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size,
+ buffer_size);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
+ regmap->simc + DW_SPI_REG_SR);
+ target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
+ regmap->simc + DW_SPI_REG_DR);
+ helper_args_val->read_cmd = read_cmd;
+ helper_args_val->four_byte_mode = driver->four_byte_mode;
+
+ ret = target_run_algorithm(target, 1, &mem_param, 1, &reg_param,
+ helper->address, 0, driver->timeout,
+ &mips32_algo);
+ if (ret) {
+ LOG_ERROR("DW SPI flash algorithm error");
+ goto cleanup;
+ }
+
+ ret =
+ target_read_buffer(target, target_buffer->address, buffer_size, buffer);
+ if (ret)
+ LOG_ERROR("DW SPI target buffer read error");
+
+cleanup:
+ destroy_reg_param(&reg_param);
+ destroy_mem_param(&mem_param);
+
+err_write_buffer:
+ target_free_working_area(target, target_buffer);
+err_target_buffer:
+ target_free_working_area(target, helper_args);
+err_helper_args:
+ target_free_working_area(target, helper);
+err_helper:
+
+ return ret;
+}
+
+/**
+ * @brief Read Flash device ID.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_read_id(const struct flash_bank *const bank)
+{
+ struct dw_spi_driver *const driver = bank->driver_priv;
+
+ const size_t buffer_size = 1 + 3 + 1;
+ uint8_t buffer[buffer_size];
+
+ memset(buffer, 0, buffer_size);
+ buffer[0] = SPIFLASH_READ_ID;
+
+ int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true);
+ if (ret) {
+ LOG_ERROR("DW SPI flash ID read error");
+ return ret;
+ }
+
+ buffer[buffer_size - 1] = 0;
+ // use le_to_h_u32 to decode flash ID as per JEDEC SFDP
+ driver->id = le_to_h_u32(buffer + 1);
+ LOG_DEBUG("DW SPI read flash ID %" PRIx32, driver->id);
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Read Flash device status.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[out] status: The status byte.
+ * @return Command execution status.
+ */
+static int
+dw_spi_read_status(const struct flash_bank *const bank, uint8_t *const status)
+{
+ const int buffer_size = 2;
+ uint8_t buffer[buffer_size];
+
+ memset(buffer, 0, buffer_size);
+ buffer[0] = SPIFLASH_READ_STATUS;
+
+ int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true);
+ if (ret) {
+ LOG_ERROR("DW SPI flash status read error");
+ return ret;
+ }
+
+ *status = buffer[1];
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Wait for Flash command to finish.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in] timeout: The timeout in ms.
+ * @return Command execution status.
+ */
+static int
+dw_spi_wait_finish(const struct flash_bank *const bank, unsigned int timeout)
+{
+ const int64_t end_time = timeval_ms() + timeout;
+ while (timeval_ms() <= end_time) {
+ uint8_t status;
+ int ret = dw_spi_read_status(bank, &status);
+ if (ret) {
+ LOG_ERROR("DW SPI status query error");
+ return ret;
+ }
+ if (!(status & SPIFLASH_BSY_BIT))
+ return ERROR_OK;
+
+ alive_sleep(1);
+ }
+
+ LOG_ERROR("DW SPI process timeout");
+ return ERROR_TIMEOUT_REACHED;
+}
+
+/**
+ * @brief Flash device write enable.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_write_enable(const struct flash_bank *const bank)
+{
+ const int buffer_size = 1;
+ uint8_t buffer[buffer_size];
+
+ memset(buffer, 0, buffer_size);
+ buffer[0] = SPIFLASH_WRITE_ENABLE;
+
+ int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, false);
+ if (ret) {
+ LOG_ERROR("DW SPI flash write enable error");
+ return ret;
+ }
+
+ uint8_t status;
+ ret = dw_spi_read_status(bank, &status);
+ if (ret)
+ return ret;
+
+ return status & SPIFLASH_WE_BIT ? ERROR_OK : ERROR_FAIL;
+}
+
+/**
+ * @brief Erase Flash chip.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_erase_chip(const struct flash_bank *const bank)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+
+ const int buffer_size = 1;
+ uint8_t buffer[buffer_size];
+
+ int ret = dw_spi_write_enable(bank);
+ if (ret)
+ return ret;
+
+ memset(buffer, 0, buffer_size);
+ buffer[0] = driver->spi_flash->chip_erase_cmd;
+
+ ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, false);
+ if (ret) {
+ LOG_ERROR("DW SPI erase flash error");
+ return ret;
+ }
+
+ ret = dw_spi_wait_finish(bank, driver->timeout);
+ if (ret) {
+ LOG_ERROR("DW SPI erase flash timeout");
+ return ret;
+ }
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Flash device erase sectors.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in] first: The first sector to erase.
+ * @param[in] last: The last sector to erase.
+ * @return Command execution status.
+ */
+static int
+dw_spi_erase_sectors(const struct flash_bank *const bank, unsigned int first,
+ unsigned int last)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+
+ if (first == 0 && last >= (bank->num_sectors - 1)) {
+ // full erase
+ int ret = dw_spi_erase_chip(bank);
+ if (ret)
+ return ret;
+ } else {
+ // partial erase
+ int ret = dw_spi_ctrl_erase_sectors(bank, bank->sectors[first].offset,
+ driver->spi_flash->sectorsize,
+ last - first + 1,
+ SPIFLASH_READ_STATUS,
+ SPIFLASH_WRITE_ENABLE,
+ driver->spi_flash->erase_cmd,
+ SPIFLASH_WE_BIT, SPIFLASH_BSY_BIT);
+ if (ret) {
+ LOG_ERROR("DW SPI flash erase sectors error");
+ return ret;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Flash bank blank check.
+ */
+static int
+dw_spi_blank_check(struct flash_bank *bank, size_t sector_count,
+ uint8_t pattern)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+
+ uint8_t *erased = malloc(sector_count);
+ if (!erased) {
+ LOG_ERROR("could not allocate memory");
+ return ERROR_FAIL;
+ }
+
+ // set initial erased value to unknown
+ memset(erased, 2, sector_count);
+ for (unsigned int sector_idx = 0; sector_idx < sector_count; sector_idx++)
+ bank->sectors[sector_idx].is_erased = 2;
+
+ int ret = dw_spi_ctrl_check_sectors_fill(bank, 0, bank->sectors[0].size,
+ sector_count, pattern,
+ driver->spi_flash->read_cmd,
+ erased);
+ if (!ret) {
+ for (unsigned int sector_idx = 0; sector_idx < sector_count;
+ sector_idx++)
+ bank->sectors[sector_idx].is_erased = erased[sector_idx];
+ } else {
+ LOG_ERROR("DW SPI flash erase check error");
+ }
+
+ free(erased);
+
+ return ret;
+}
+
+/**
+ * @brief Write buffer to Flash.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in] buffer: Data buffer.
+ * @param[in] offset: Flash address offset.
+ * @param[in] count: \p buffer size.
+ * @return Command execution status.
+ */
+static int
+dw_spi_write_buffer(const struct flash_bank *const bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ const size_t page_size = driver->spi_flash->pagesize;
+
+ // Write unaligned first sector separately as helper function does
+ // not handle this case well.
+ struct {
+ uint32_t address;
+ const uint8_t *buffer;
+ size_t count;
+ } chunks[2] = {
+ { .address = offset, .buffer = buffer, .count = 0 },
+ { .address = offset, .buffer = buffer, .count = count },
+ };
+
+ if (offset % page_size) {
+ // start is not aligned
+ chunks[0].count = MIN(page_size - (offset % page_size), count);
+ chunks[1].count -= chunks[0].count;
+ chunks[1].address += chunks[0].count;
+ chunks[1].buffer += chunks[0].count;
+ }
+
+ for (unsigned int chunk_idx = 0; chunk_idx < ARRAY_SIZE(chunks);
+ chunk_idx++) {
+ if (chunks[chunk_idx].count > 0) {
+ int ret = dw_spi_ctrl_program(bank, chunks[chunk_idx].address,
+ chunks[chunk_idx].buffer,
+ chunks[chunk_idx].count, page_size,
+ SPIFLASH_READ_STATUS,
+ SPIFLASH_WRITE_ENABLE,
+ driver->spi_flash->pprog_cmd,
+ SPIFLASH_WE_BIT, SPIFLASH_BSY_BIT);
+ if (ret) {
+ LOG_ERROR("DW SPI flash write error");
+ return ret;
+ }
+ }
+ }
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Search for Flash chip info.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_spiflash_search(const struct flash_bank *const bank)
+{
+ struct dw_spi_driver *const driver = bank->driver_priv;
+
+ int ret = dw_spi_read_id(bank);
+ if (ret)
+ return ret;
+
+ unsigned int idx = 0;
+ while (flash_devices[idx].name) {
+ if (flash_devices[idx].device_id == driver->id) {
+ driver->spi_flash = &flash_devices[idx];
+ return ERROR_OK;
+ }
+ idx++;
+ }
+
+ LOG_ERROR("DW SPI could not find Flash with ID %" PRIx32
+ " in SPI Flash table: either Flash device is not supported "
+ "or communication speed is too high",
+ driver->id);
+ return ERROR_FAIL;
+}
+
+/**
+ * @brief Handle flash bank command.
+ *
+ * @param[in] CMD_ARGC: Number of arguments.
+ * @param[in] CMD_ARGV: Command arguments.
+ * @return Command execution status.
+ */
+FLASH_BANK_COMMAND_HANDLER(dw_spi_flash_bank_command)
+{
+ unsigned int speed = 1000000;
+ unsigned int timeout = DW_SPI_TIMEOUT_DEFAULT;
+ uint8_t chip_select_bitmask = BIT(0);
+ struct dw_spi_regmap regmap = { 0 };
+
+ if (CMD_ARGC < 6)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ for (unsigned int idx = 6; idx < CMD_ARGC; idx++) {
+ if (strcmp(CMD_ARGV[idx], "-jaguar2") == 0) {
+ // Fast config for Jaguar2 chips.
+ memcpy(&regmap, &jaguar2_regmap, sizeof(jaguar2_regmap));
+ } else if (strcmp(CMD_ARGV[idx], "-ocelot") == 0) {
+ // Fast config for Ocelot chips.
+ memcpy(&regmap, &ocelot_regmap, sizeof(ocelot_regmap));
+ } else if (strcmp(CMD_ARGV[idx], "-freq") == 0) {
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[++idx], regmap.freq);
+ } else if (strcmp(CMD_ARGV[idx], "-simc") == 0) {
+ COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.simc);
+ } else if (strcmp(CMD_ARGV[idx], "-spi_mst") == 0) {
+ COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.spi_mst);
+ } else if (strcmp(CMD_ARGV[idx], "-if_owner_offset") == 0) {
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[++idx],
+ regmap.si_if_owner_offset);
+ } else if (strcmp(CMD_ARGV[idx], "-speed") == 0) {
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], speed);
+ } else if (strcmp(CMD_ARGV[idx], "-timeout") == 0) {
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], timeout);
+ timeout *= 1000; // convert to ms
+ } else if (strcmp(CMD_ARGV[idx], "-chip_select") == 0) {
+ unsigned int cs_bit;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], cs_bit);
+ chip_select_bitmask = BIT(cs_bit);
+ } else {
+ LOG_WARNING("DW SPI unknown argument %s", CMD_ARGV[idx]);
+ }
+ }
+
+ if (!regmap.simc) {
+ LOG_ERROR("DW SPI cannot use boot controller with unconfigured simc");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ bank->driver_priv = malloc(sizeof(struct dw_spi_driver));
+ if (!bank->driver_priv) {
+ LOG_ERROR("could not allocate memory");
+ return ERROR_FAIL;
+ }
+
+ struct dw_spi_driver *driver = bank->driver_priv;
+ memset(driver, 0, sizeof(struct dw_spi_driver));
+ driver->speed = speed;
+ driver->timeout = timeout;
+ driver->chip_select_bitmask = chip_select_bitmask;
+ driver->four_byte_mode = true; // 24bit commands not provided by spi.h
+ memcpy(&driver->regmap, &regmap, sizeof(regmap));
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Assert target is halted.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_assert_halted(const struct flash_bank *const bank)
+{
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return ERROR_OK;
+}
+
+/**
+ * @brief Prepare master controller for transaction.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_master_ctrl_configure(struct flash_bank *bank)
+{
+ int ret = dw_spi_assert_halted(bank);
+ if (ret)
+ return ret;
+ ret = dw_spi_ctrl_mode_configure(bank, DW_SPI_SI_MODE_MASTER);
+ if (ret) {
+ LOG_ERROR("DW SPI switch to master controller mode error");
+ return ret;
+ }
+ ret = dw_spi_master_ctrl_enable(bank, false);
+ if (ret) {
+ LOG_ERROR("DW SPI disable master controller error");
+ return ret;
+ }
+ ret = dw_spi_ctrl_configure_speed(bank);
+ if (ret) {
+ LOG_ERROR("DW SPI speed configuration error");
+ return ret;
+ }
+ ret = dw_spi_ctrl_disable_interrupts(bank);
+ if (ret) {
+ LOG_ERROR("DW SPI disable SPI interrupts error");
+ return ret;
+ }
+ ret = dw_spi_ctrl_configure_si(bank);
+ if (ret) {
+ LOG_ERROR("DW SPI controller configuration error");
+ return ret;
+ }
+ ret = dw_spi_master_ctrl_enable(bank, true);
+ if (ret) {
+ LOG_ERROR("DW SPI enable master controller error");
+ return ret;
+ }
+
+ return ERROR_OK;
+}
+
+/**
+ * @brief Restore SI controller selection.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_master_ctrl_restore(struct flash_bank *bank)
+{
+ int ret = dw_spi_master_ctrl_enable(bank, false);
+ if (ret) {
+ LOG_ERROR("DW SPI disable master controller error");
+ return ret;
+ }
+ ret = dw_spi_ctrl_mode_restore(bank);
+ if (ret) {
+ LOG_ERROR("DW SPI controller restore error");
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Flash bank probe.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_probe(struct flash_bank *bank)
+{
+ struct dw_spi_driver *const driver = bank->driver_priv;
+
+ if (!driver)
+ return ERROR_FAIL;
+
+ if (strcmp(bank->target->type->name, mips_m4k_target.name) != 0 ||
+ bank->target->endianness != TARGET_LITTLE_ENDIAN) {
+ LOG_ERROR("DW SPI currently only supports "
+ "little endian mips_m4k target");
+ return ERROR_TARGET_INVALID;
+ }
+
+ int ret = dw_spi_master_ctrl_configure(bank);
+ if (ret)
+ return ret;
+
+ ret = dw_spi_spiflash_search(bank);
+ if (ret)
+ goto err;
+
+ bank->write_start_alignment = 0;
+ bank->write_end_alignment = 0;
+
+ uint32_t flash_size = driver->spi_flash->size_in_bytes;
+ if (!bank->size) {
+ bank->size = flash_size;
+ LOG_INFO("DW SPI probed flash size 0x%" PRIx32, flash_size);
+ } else {
+ if (flash_size > bank->size)
+ LOG_WARNING("DW SPI probed flash size 0x%" PRIx32
+ " is greater then declared 0x%" PRIx32,
+ flash_size, bank->size);
+ if (flash_size < bank->size) {
+ LOG_ERROR("DW SPI probed flash size 0x%" PRIx32
+ " is smaller then declared 0x%" PRIx32,
+ flash_size, bank->size);
+ ret = ERROR_FLASH_BANK_INVALID;
+ goto err;
+ }
+ }
+ bank->num_sectors = bank->size / driver->spi_flash->sectorsize;
+
+ // free previously allocated in case of reprobing
+ free(bank->sectors);
+
+ bank->sectors =
+ alloc_block_array(0, driver->spi_flash->sectorsize, bank->num_sectors);
+
+ if (!bank->sectors) {
+ LOG_ERROR("could not allocate memory");
+ ret = ERROR_FAIL;
+ goto err;
+ }
+
+ driver->probed = true;
+
+err:
+ dw_spi_master_ctrl_restore(bank);
+ return ret;
+}
+
+/**
+ * @brief Flash bank erase sectors.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in] first: The first sector to erase.
+ * @param[in] last: The last sector to erase.
+ * @return Command execution status.
+ */
+static int
+dw_spi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
+{
+ int ret = dw_spi_master_ctrl_configure(bank);
+ if (ret)
+ return ret;
+
+ ret = dw_spi_erase_sectors(bank, first, last);
+ dw_spi_master_ctrl_restore(bank);
+ return ret;
+}
+
+/**
+ * @brief Flash bank write data.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in] buffer: Data buffer.
+ * @param[in] offset: Flash address offset.
+ * @param[in] count: \p buffer size.
+ * @return Command execution status.
+ */
+static int
+dw_spi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
+ uint32_t count)
+{
+ int ret = dw_spi_master_ctrl_configure(bank);
+ if (ret)
+ return ret;
+
+ ret = dw_spi_write_buffer(bank, buffer, offset, count);
+ dw_spi_master_ctrl_restore(bank);
+ return ret;
+}
+
+/**
+ * @brief Flash bank read data using master controller.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[out] buffer: Data buffer.
+ * @param[in] offset: Flash address offset.
+ * @param[in] count: \p buffer size.
+ * @return Command execution status.
+ */
+static int
+dw_spi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset,
+ uint32_t count)
+{
+ struct dw_spi_driver *const driver = bank->driver_priv;
+
+ int ret = dw_spi_master_ctrl_configure(bank);
+ if (ret)
+ return ret;
+
+ ret = dw_spi_ctrl_read(bank, offset, buffer, count,
+ driver->spi_flash->read_cmd);
+ dw_spi_master_ctrl_restore(bank);
+ return ret;
+}
+
+/**
+ * @brief Flash bank erase check.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_erase_check(struct flash_bank *bank)
+{
+ int ret = dw_spi_master_ctrl_configure(bank);
+ if (ret)
+ return ret;
+
+ ret = dw_spi_blank_check(bank, bank->num_sectors, bank->erased_value);
+
+ dw_spi_master_ctrl_restore(bank);
+ return ret;
+}
+
+/**
+ * @brief Flash bank info.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @param[in,out] cmd Command invocation.
+ * @return Command execution status.
+ */
+static int
+dw_spi_info(struct flash_bank *bank, struct command_invocation *cmd)
+{
+ const struct dw_spi_driver *const driver = bank->driver_priv;
+ command_print(cmd, "model %s", driver->spi_flash->name);
+ command_print(cmd, "ID 0x%" PRIx32, driver->id);
+ command_print_sameline(cmd, "size 0x%" PRIx32, bank->size);
+ return ERROR_OK;
+}
+
+/**
+ * @brief Autoprobe driver.
+ *
+ * @param[in] bank: Flash bank handle.
+ * @return Command execution status.
+ */
+static int
+dw_spi_auto_probe(struct flash_bank *bank)
+{
+ struct dw_spi_driver *driver = bank->driver_priv;
+ if (!driver)
+ return ERROR_FAIL;
+ if (!driver->probed)
+ return dw_spi_probe(bank);
+ return ERROR_OK;
+}
+
+/**
+ * @brief DW-SPI NOR flash functions.
+ */
+const struct flash_driver dw_spi_flash = {
+ .name = "dw-spi",
+ .flash_bank_command = dw_spi_flash_bank_command,
+ .erase = dw_spi_erase,
+ .write = dw_spi_write,
+ .read = dw_spi_read,
+ .probe = dw_spi_probe,
+ .auto_probe = dw_spi_auto_probe,
+ .erase_check = dw_spi_erase_check,
+ .info = dw_spi_info,
+ .verify = default_flash_verify,
+ .free_driver_priv = default_flash_free_driver_priv,
+};
diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c
index 043494c..207346f 100644
--- a/src/flash/nor/em357.c
+++ b/src/flash/nor/em357.c
@@ -709,7 +709,7 @@ static int em357_probe(struct flash_bank *bank)
em357_info->ppage_size = 4;
- LOG_INFO("flash size = %d KiB", num_pages*page_size/1024);
+ LOG_INFO("flash size = %d KiB", num_pages * page_size / 1024);
free(bank->sectors);
diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c
index 9191764..395722c 100644
--- a/src/flash/nor/fespi.c
+++ b/src/flash/nor/fespi.c
@@ -531,7 +531,7 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
bin_size = sizeof(riscv64_bin);
}
- unsigned data_wa_size = 0;
+ unsigned int data_wa_size = 0;
if (target_alloc_working_area(target, bin_size, &algorithm_wa) == ERROR_OK) {
retval = target_write_buffer(target, algorithm_wa->address,
bin_size, bin);
@@ -751,9 +751,9 @@ static int fespi_probe(struct flash_bank *bank)
target_device->name, bank->base);
} else {
- LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
- " with ctrl at " TARGET_ADDR_FMT, fespi_info->ctrl_base,
- bank->base);
+ LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
+ " with ctrl at " TARGET_ADDR_FMT, fespi_info->ctrl_base,
+ bank->base);
}
/* read and decode flash ID; returns in SW mode */
diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c
index 979ae84..2db79ef 100644
--- a/src/flash/nor/fm4.c
+++ b/src/flash/nor/fm4.c
@@ -107,7 +107,7 @@ static int fm4_flash_erase(struct flash_bank *bank, unsigned int first,
struct working_area *workarea;
struct reg_param reg_params[4];
struct armv7m_algorithm armv7m_algo;
- unsigned i;
+ unsigned int i;
int retval;
const uint8_t erase_sector_code[] = {
#include "../../../contrib/loaders/flash/fm4/erase.inc"
@@ -207,7 +207,7 @@ static int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer,
struct armv7m_algorithm armv7m_algo;
uint32_t halfword_count = DIV_ROUND_UP(byte_count, 2);
uint32_t result;
- unsigned i;
+ unsigned int i;
int retval, retval2 = ERROR_OK;
const uint8_t write_block_code[] = {
#include "../../../contrib/loaders/flash/fm4/write.inc"
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index fee3644..85c306b 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -256,7 +256,7 @@
struct kinetis_flash_bank {
struct kinetis_chip *k_chip;
bool probed;
- unsigned bank_number; /* bank number in particular chip */
+ unsigned int bank_number; /* bank number in particular chip */
struct flash_bank *bank;
uint32_t sector_size;
@@ -285,9 +285,9 @@ struct kinetis_chip {
uint32_t fcfg2_maxaddr0_shifted;
uint32_t fcfg2_maxaddr1_shifted;
- unsigned num_pflash_blocks, num_nvm_blocks;
- unsigned pflash_sector_size, nvm_sector_size;
- unsigned max_flash_prog_size;
+ unsigned int num_pflash_blocks, num_nvm_blocks;
+ unsigned int pflash_sector_size, nvm_sector_size;
+ unsigned int max_flash_prog_size;
uint32_t pflash_base;
uint32_t pflash_size;
@@ -337,7 +337,7 @@ struct kinetis_chip {
char name[40];
- unsigned num_banks;
+ unsigned int num_banks;
struct kinetis_flash_bank banks[KINETIS_MAX_BANKS];
};
@@ -425,7 +425,7 @@ static int kinetis_probe_chip_s32k(struct kinetis_chip *k_chip);
static int kinetis_auto_probe(struct flash_bank *bank);
-static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
+static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned int reg, uint32_t value)
{
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
@@ -453,7 +453,7 @@ static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint3
return ERROR_OK;
}
-static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
+static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned int reg, uint32_t *result)
{
struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
if (!ap) {
@@ -479,7 +479,7 @@ static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32
return ERROR_OK;
}
-static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg,
+static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned int reg,
uint32_t mask, uint32_t value, uint32_t timeout_ms)
{
uint32_t val;
@@ -977,7 +977,7 @@ static void kinetis_free_driver_priv(struct flash_bank *bank)
static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
{
- unsigned num_blocks;
+ unsigned int num_blocks;
struct kinetis_flash_bank *k_bank;
struct flash_bank *bank;
char base_name[69], name[87], num[11];
@@ -1038,6 +1038,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
bank->target = k_chip->target;
bank->driver = &kinetis_flash;
bank->default_padded_value = bank->erased_value = 0xff;
+ bank->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;
snprintf(name, sizeof(name), "%s.%s%s",
base_name, class, num);
@@ -1462,7 +1463,7 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf)
uint32_t fprot = 0xffffffff;
uint8_t fsec = 0xfe; /* set MCU unsecure */
uint8_t fdprot = 0xff;
- unsigned num_blocks;
+ unsigned int num_blocks;
uint32_t pflash_bit;
uint8_t dflash_bit;
struct flash_bank *bank_iter;
@@ -1488,7 +1489,22 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf)
kinetis_auto_probe(bank_iter);
- assert(bank_iter->prot_blocks);
+ if (bank_iter->num_prot_blocks == 0) {
+ if (k_bank->flash_class == FC_PFLASH) {
+ LOG_ERROR("BUG: PFLASH bank %u has no protection blocks",
+ bank_idx);
+ } else {
+ LOG_DEBUG("skipping FLEX_NVM bank %u with no prot blocks (EE bkp only)",
+ bank_idx);
+ }
+ continue;
+ }
+
+ if (!bank_iter->prot_blocks) {
+ LOG_ERROR("BUG: bank %u has NULL protection blocks array",
+ bank_idx);
+ continue;
+ }
if (k_bank->flash_class == FC_PFLASH) {
for (unsigned int i = 0; i < bank_iter->num_prot_blocks; i++) {
@@ -2268,12 +2284,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
uint32_t ee_size = 0;
uint32_t pflash_size_k, nvm_size_k, dflash_size_k;
uint32_t pflash_size_m;
- unsigned num_blocks = 0;
- unsigned maxaddr_shift = 13;
+ unsigned int num_blocks = 0;
+ unsigned int maxaddr_shift = 13;
struct target *target = k_chip->target;
- unsigned familyid = 0, subfamid = 0;
- unsigned cpu_mhz = 120;
+ unsigned int familyid = 0, subfamid = 0;
+ unsigned int cpu_mhz = 120;
bool use_nvm_marking = false;
char flash_marking[12], nvm_marking[2];
char name[40];
@@ -2894,7 +2910,7 @@ static int kinetis_probe(struct flash_bank *bank)
{
int result;
uint8_t fcfg2_maxaddr0, fcfg2_pflsh, fcfg2_maxaddr1;
- unsigned num_blocks, first_nvm_bank;
+ unsigned int num_blocks, first_nvm_bank;
uint32_t size_k;
struct kinetis_flash_bank *k_bank = bank->driver_priv;
struct kinetis_chip *k_chip;
@@ -2939,7 +2955,7 @@ static int kinetis_probe(struct flash_bank *bank)
} else if (k_bank->bank_number < num_blocks) {
/* nvm, banks start at address 0x10000000 */
- unsigned nvm_ord = k_bank->bank_number - first_nvm_bank;
+ unsigned int nvm_ord = k_bank->bank_number - first_nvm_bank;
uint32_t limit;
k_bank->flash_class = FC_FLEX_NVM;
@@ -3138,8 +3154,8 @@ static int kinetis_blank_check(struct flash_bank *bank)
COMMAND_HANDLER(kinetis_nvm_partition)
{
int result;
- unsigned bank_idx;
- unsigned num_blocks, first_nvm_bank;
+ unsigned int bank_idx;
+ unsigned int num_blocks, first_nvm_bank;
unsigned long par, log2 = 0, ee1 = 0, ee2 = 0;
enum { SHOW_INFO, DF_SIZE, EEBKP_SIZE } sz_type = SHOW_INFO;
bool enable;
diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c
index c069f3a..8207504 100644
--- a/src/flash/nor/kinetis_ke.c
+++ b/src/flash/nor/kinetis_ke.c
@@ -134,7 +134,7 @@ struct kinetis_ke_flash_bank {
#define MDM_ACCESS_TIMEOUT 3000 /* iterations */
-static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
+static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned int reg, uint32_t value)
{
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
@@ -161,7 +161,7 @@ static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, ui
return ERROR_OK;
}
-static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
+static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned int reg, uint32_t *result)
{
struct adiv5_ap *ap = dap_get_ap(dap, 1);
if (!ap) {
@@ -187,7 +187,7 @@ static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uin
return ERROR_OK;
}
-static int kinetis_ke_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value)
+static int kinetis_ke_mdm_poll_register(struct adiv5_dap *dap, unsigned int reg, uint32_t mask, uint32_t value)
{
uint32_t val;
int retval;
@@ -1005,7 +1005,7 @@ static int kinetis_ke_write(struct flash_bank *bank, const uint8_t *buffer,
result = kinetis_ke_stop_watchdog(bank->target);
if (result != ERROR_OK)
- return result;
+ return result;
result = kinetis_ke_prepare_flash(bank);
if (result != ERROR_OK)
diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index f12eef7..09d35f6 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -272,7 +272,7 @@
#define LPC11XX_REG_SECTORS 24
-typedef enum {
+enum lpc2000_variant {
LPC2000_V1,
LPC2000_V2,
LPC1700,
@@ -282,10 +282,10 @@ typedef enum {
LPC1500,
LPC54100,
LPC_AUTO,
-} lpc2000_variant;
+};
struct lpc2000_flash_bank {
- lpc2000_variant variant;
+ enum lpc2000_variant variant;
uint32_t cclk;
int cmd51_dst_boundary;
int calc_checksum;
diff --git a/src/flash/nor/max32xxx.c b/src/flash/nor/max32xxx.c
index 59a14af..267fd43 100644
--- a/src/flash/nor/max32xxx.c
+++ b/src/flash/nor/max32xxx.c
@@ -202,14 +202,14 @@ static int max32xxx_protect_check(struct flash_bank *bank)
return ERROR_FLASH_BANK_NOT_PROBED;
if (!info->max326xx) {
- for (unsigned i = 0; i < bank->num_sectors; i++)
+ for (unsigned int i = 0; i < bank->num_sectors; i++)
bank->sectors[i].is_protected = -1;
return ERROR_FLASH_OPER_UNSUPPORTED;
}
/* Check the protection */
- for (unsigned i = 0; i < bank->num_sectors; i++) {
+ for (unsigned int i = 0; i < bank->num_sectors; i++) {
if (i%32 == 0)
target_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);
@@ -360,7 +360,7 @@ static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
/* power of two, and multiple of word size */
- static const unsigned buf_min = 128;
+ static const unsigned int buf_min = 128;
/* for small buffers it's faster not to download an algorithm */
if (wcount * 4 < buf_min)
@@ -388,8 +388,8 @@ static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
- target_name(target), (unsigned) buffer_size);
+ LOG_DEBUG("retry target_alloc_working_area(%s, size=%" PRIu32 ")",
+ target_name(target), buffer_size);
}
target_write_buffer(target, write_algorithm->address, sizeof(write_code),
@@ -903,7 +903,7 @@ COMMAND_HANDLER(max32xxx_handle_protection_check_command)
}
LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
- for (unsigned i = 0; i < bank->num_sectors; i += 4) {
+ for (unsigned int i = 0; i < bank->num_sectors; i += 4) {
LOG_WARNING("s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d",
(i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,
(i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,
diff --git a/src/flash/nor/mspm0.c b/src/flash/nor/mspm0.c
new file mode 100644
index 0000000..4731c89
--- /dev/null
+++ b/src/flash/nor/mspm0.c
@@ -0,0 +1,1131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * NOR flash driver for MSPM0L and MSPM0G class of uC from Texas Instruments.
+ *
+ * See:
+ * https://www.ti.com/microcontrollers-mcus-processors/arm-based-microcontrollers/arm-cortex-m0-mcus/overview.html
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imp.h"
+#include <helper/bits.h>
+#include <helper/time_support.h>
+
+/* MSPM0 Region memory map */
+#define MSPM0_FLASH_BASE_NONMAIN 0x41C00000
+#define MSPM0_FLASH_END_NONMAIN 0x41C00400
+#define MSPM0_FLASH_BASE_MAIN 0x0
+#define MSPM0_FLASH_BASE_DATA 0x41D00000
+
+/* MSPM0 FACTORYREGION registers */
+#define MSPM0_FACTORYREGION 0x41C40000
+#define MSPM0_TRACEID (MSPM0_FACTORYREGION + 0x000)
+#define MSPM0_DID (MSPM0_FACTORYREGION + 0x004)
+#define MSPM0_USERID (MSPM0_FACTORYREGION + 0x008)
+#define MSPM0_SRAMFLASH (MSPM0_FACTORYREGION + 0x018)
+
+/* MSPM0 FCTL registers */
+#define FLASH_CONTROL_BASE 0x400CD000
+#define FCTL_REG_DESC (FLASH_CONTROL_BASE + 0x10FC)
+#define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100)
+#define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104)
+#define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120)
+#define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124)
+#define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130)
+#define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0)
+#define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4)
+#define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210)
+#define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0)
+
+/* FCTL_STATCMD[CMDDONE] Bits */
+#define FCTL_STATCMD_CMDDONE_MASK 0x00000001
+#define FCTL_STATCMD_CMDDONE_STATDONE 0x00000001
+
+/* FCTL_STATCMD[CMDPASS] Bits */
+#define FCTL_STATCMD_CMDPASS_MASK 0x00000002
+#define FCTL_STATCMD_CMDPASS_STATPASS 0x00000002
+
+/*
+ * FCTL_CMDEXEC Bits
+ * FCTL_CMDEXEC[VAL] Bits
+ */
+#define FCTL_CMDEXEC_VAL_EXECUTE 0x00000001
+
+/* FCTL_CMDTYPE[COMMAND] Bits */
+#define FCTL_CMDTYPE_COMMAND_PROGRAM 0x00000001
+#define FCTL_CMDTYPE_COMMAND_ERASE 0x00000002
+
+/* FCTL_CMDTYPE[SIZE] Bits */
+#define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000
+#define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040
+
+/* FCTL_FEATURE_VER_B minimum */
+#define FCTL_FEATURE_VER_B 0xA
+
+#define MSPM0_MAX_PROTREGS 3
+
+#define MSPM0_FLASH_TIMEOUT_MS 8000
+#define ERR_STRING_MAX 255
+
+/* SYSCTL BASE */
+#define SYSCTL_BASE 0x400AF000
+#define SYSCTL_SECCFG_SECSTATUS (SYSCTL_BASE + 0x00003048)
+
+/* TI manufacturer ID */
+#define TI_MANUFACTURER_ID 0x17
+
+/* Defines for probe status */
+#define MSPM0_NO_ID_FOUND 0
+#define MSPM0_DEV_ID_FOUND 1
+#define MSPM0_DEV_PART_ID_FOUND 2
+
+struct mspm0_flash_bank {
+ /* chip id register */
+ uint32_t did;
+ /* Device Unique ID register */
+ uint32_t traceid;
+ unsigned char version;
+
+ const char *name;
+
+ /* Decoded flash information */
+ unsigned int data_flash_size_kb;
+ unsigned int main_flash_size_kb;
+ unsigned int main_flash_num_banks;
+ unsigned int sector_size;
+ /* Decoded SRAM information */
+ unsigned int sram_size_kb;
+
+ /* Flash word size: 64 bit = 8, 128bit = 16 bytes */
+ unsigned char flash_word_size_bytes;
+
+ /* Protection register stuff */
+ unsigned int protect_reg_base;
+ unsigned int protect_reg_count;
+
+ /* Flashctl version: A - CMDWEPROTA/B, B- CMDWEPROTB */
+ unsigned char flash_version;
+};
+
+struct mspm0_part_info {
+ const char *part_name;
+ unsigned short part;
+ unsigned char variant;
+};
+
+struct mspm0_family_info {
+ const char *family_name;
+ unsigned short part_num;
+ unsigned char part_count;
+ const struct mspm0_part_info *part_info;
+};
+
+/* https://www.ti.com/lit/ds/symlink/mspm0l1346.pdf Table 8-13 and so on */
+static const struct mspm0_part_info mspm0l_parts[] = {
+ { "MSPM0L1105TDGS20R", 0x51DB, 0x16 },
+ { "MSPM0L1105TDGS28R", 0x51DB, 0x83 },
+ { "MSPM0L1105TDYYR", 0x51DB, 0x54 },
+ { "MSPM0L1105TRGER", 0x51DB, 0x86 },
+ { "MSPM0L1105TRHBR", 0x51DB, 0x68 },
+ { "MSPM0L1106TDGS20R", 0x5552, 0x4B },
+ { "MSPM0L1106TDGS28R", 0x5552, 0x98 },
+ { "MSPM0L1106TDYYR", 0x5552, 0x9D },
+ { "MSPM0L1106TRGER", 0x5552, 0x90 },
+ { "MSPM0L1106TRHBR", 0x5552, 0x53 },
+ { "MSPM0L1303SRGER", 0xef0, 0x17 },
+ { "MSPM0L1303TRGER", 0xef0, 0xe2 },
+ { "MSPM0L1304QDGS20R", 0xd717, 0x91 },
+ { "MSPM0L1304QDGS28R", 0xd717, 0xb6 },
+ { "MSPM0L1304QDYYR", 0xd717, 0xa0 },
+ { "MSPM0L1304QRHBR", 0xd717, 0xa9 },
+ { "MSPM0L1304SDGS20R", 0xd717, 0xfa },
+ { "MSPM0L1304SDGS28R", 0xd717, 0x73 },
+ { "MSPM0L1304SDYYR", 0xd717, 0xb7 },
+ { "MSPM0L1304SRGER", 0xd717, 0x26 },
+ { "MSPM0L1304SRHBR", 0xd717, 0xe4 },
+ { "MSPM0L1304TDGS20R", 0xd717, 0x33 },
+ { "MSPM0L1304TDGS28R", 0xd717, 0xa8 },
+ { "MSPM0L1304TDYYR", 0xd717, 0xf9 },
+ { "MSPM0L1304TRGER", 0xd717, 0xb7 },
+ { "MSPM0L1304TRHBR", 0xd717, 0x5a },
+ { "MSPM0L1305QDGS20R", 0x4d03, 0xb7 },
+ { "MSPM0L1305QDGS28R", 0x4d03, 0x74 },
+ { "MSPM0L1305QDYYR", 0x4d03, 0xec },
+ { "MSPM0L1305QRHBR", 0x4d03, 0x78 },
+ { "MSPM0L1305SDGS20R", 0x4d03, 0xc7 },
+ { "MSPM0L1305SDGS28R", 0x4d03, 0x64 },
+ { "MSPM0L1305SDYYR", 0x4d03, 0x91 },
+ { "MSPM0L1305SRGER", 0x4d03, 0x73 },
+ { "MSPM0L1305SRHBR", 0x4d03, 0x2d },
+ { "MSPM0L1305TDGS20R", 0x4d03, 0xa0 },
+ { "MSPM0L1305TDGS28R", 0x4d03, 0xfb },
+ { "MSPM0L1305TDYYR", 0x4d03, 0xde },
+ { "MSPM0L1305TRGER", 0x4d03, 0xea },
+ { "MSPM0L1305TRHBR", 0x4d03, 0x85 },
+ { "MSPM0L1306QDGS20R", 0xbb70, 0x59 },
+ { "MSPM0L1306QDGS28R", 0xbb70, 0xf7 },
+ { "MSPM0L1306QDYYR", 0xbb70, 0x9f },
+ { "MSPM0L1306QRHBR", 0xbb70, 0xc2 },
+ { "MSPM0L1306SDGS20R", 0xbb70, 0xf4 },
+ { "MSPM0L1306SDGS28R", 0xbb70, 0x5 },
+ { "MSPM0L1306SDYYR", 0xbb70, 0xe },
+ { "MSPM0L1306SRGER", 0xbb70, 0x7f },
+ { "MSPM0L1306SRHBR", 0xbb70, 0x3c },
+ { "MSPM0L1306TDGS20R", 0xbb70, 0xa },
+ { "MSPM0L1306TDGS28R", 0xbb70, 0x63 },
+ { "MSPM0L1306TDYYR", 0xbb70, 0x35 },
+ { "MSPM0L1306TRGER", 0xbb70, 0xaa },
+ { "MSPM0L1306TRHBR", 0xbb70, 0x52 },
+ { "MSPM0L1343TDGS20R", 0xb231, 0x2e },
+ { "MSPM0L1344TDGS20R", 0x40b0, 0xd0 },
+ { "MSPM0L1345TDGS28R", 0x98b4, 0x74 },
+ { "MSPM0L1346TDGS28R", 0xf2b5, 0xef },
+};
+
+/* https://www.ti.com/lit/ds/symlink/mspm0g3506.pdf Table 8-20 */
+static const struct mspm0_part_info mspm0g_parts[] = {
+ { "MSPM0G1105TPTR", 0x8934, 0xD },
+ { "MSPM0G1105TRGZR", 0x8934, 0xFE },
+ { "MSPM0G1106TPMR", 0x477B, 0xD4 },
+ { "MSPM0G1106TPTR", 0x477B, 0x71 },
+ { "MSPM0G1106TRGZR", 0x477B, 0xBB },
+ { "MSPM0G1106TRHBR", 0x477B, 0x0 },
+ { "MSPM0G1107TDGS28R", 0x807B, 0x82 },
+ { "MSPM0G1107TPMR", 0x807B, 0xB3 },
+ { "MSPM0G1107TPTR", 0x807B, 0x32 },
+ { "MSPM0G1107TRGER", 0x807B, 0x79 },
+ { "MSPM0G1107TRGZR", 0x807B, 0x20 },
+ { "MSPM0G1107TRHBR", 0x807B, 0xBC },
+ { "MSPM0G1505SDGS28R", 0x13C4, 0x73 },
+ { "MSPM0G1505SPMR", 0x13C4, 0x53 },
+ { "MSPM0G1505SPTR", 0x13C4, 0x3E },
+ { "MSPM0G1505SRGER", 0x13C4, 0x47 },
+ { "MSPM0G1505SRGZR", 0x13C4, 0x34 },
+ { "MSPM0G1505SRHBR", 0x13C4, 0x30 },
+ { "MSPM0G1506SDGS28R", 0x5AE0, 0x3A },
+ { "MSPM0G1506SPMR", 0x5AE0, 0xF6 },
+ { "MSPM0G1506SRGER", 0x5AE0, 0x67 },
+ { "MSPM0G1506SRGZR", 0x5AE0, 0x75 },
+ { "MSPM0G1506SRHBR", 0x5AE0, 0x57 },
+ { "MSPM0G1507SDGS28R", 0x2655, 0x6D },
+ { "MSPM0G1507SPMR", 0x2655, 0x97 },
+ { "MSPM0G1507SRGER", 0x2655, 0x83 },
+ { "MSPM0G1507SRGZR", 0x2655, 0xD3 },
+ { "MSPM0G1507SRHBR", 0x2655, 0x4D },
+ { "MSPM0G3105SDGS20R", 0x4749, 0x21 },
+ { "MSPM0G3105SDGS28R", 0x4749, 0xDD },
+ { "MSPM0G3105SRHBR", 0x4749, 0xBE },
+ { "MSPM0G3106SDGS20R", 0x54C7, 0xD2 },
+ { "MSPM0G3106SDGS28R", 0x54C7, 0xB9 },
+ { "MSPM0G3106SRHBR", 0x54C7, 0x67 },
+ { "MSPM0G3107SDGS20R", 0xAB39, 0x5C },
+ { "MSPM0G3107SDGS28R", 0xAB39, 0xCC },
+ { "MSPM0G3107SRHBR", 0xAB39, 0xB7 },
+ { "MSPM0G3505SDGS28R", 0xc504, 0x8e },
+ { "MSPM0G3505SPMR", 0xc504, 0x1d },
+ { "MSPM0G3505SPTR", 0xc504, 0x93 },
+ { "MSPM0G3505SRGZR", 0xc504, 0xc7 },
+ { "MSPM0G3505SRHBR", 0xc504, 0xe7 },
+ { "MSPM0G3505TDGS28R", 0xc504, 0xdf },
+ { "MSPM0G3506SDGS28R", 0x151f, 0x8 },
+ { "MSPM0G3506SPMR", 0x151f, 0xd4 },
+ { "MSPM0G3506SPTR", 0x151f, 0x39 },
+ { "MSPM0G3506SRGZR", 0x151f, 0xfe },
+ { "MSPM0G3506SRHBR", 0x151f, 0xb5 },
+ { "MSPM0G3507SDGS28R", 0xae2d, 0xca },
+ { "MSPM0G3507SPMR", 0xae2d, 0xc7 },
+ { "MSPM0G3507SPTR", 0xae2d, 0x3f },
+ { "MSPM0G3507SRGZR", 0xae2d, 0xf7 },
+ { "MSPM0G3507SRHBR", 0xae2d, 0x4c },
+ { "M0G3107QPMRQ1", 0x4e2f, 0x51 },
+ { "M0G3107QPTRQ1", 0x4e2f, 0xc7},
+ { "M0G3107QRGZRQ1", 0x4e2f, 0x8a },
+ { "M0G3107QRHBRQ1", 0x4e2f, 0x9a},
+ { "M0G3107QDGS28RQ1", 0x4e2f, 0xd5},
+ { "M0G3107QDGS28RQ1", 0x4e2f, 0x67},
+ { "M0G3107QDGS20RQ1", 0x4e2f, 0xfd},
+ { "M0G3106QPMRQ1", 0x54C7, 0x08},
+ { "M0G3105QDGS32RQ1", 0x1349, 0x08},
+ { "M0G3106QPTRQ1", 0x54C7, 0x3F},
+ { "M0G3105QDGS28RQ1", 0x1349, 0x1B},
+ { "M0G3106QRGZRQ1", 0x94AD, 0xE6},
+ { "M0G3105QDGS20RQ1", 0x1349, 0xFB},
+ { "M0G3106QRHBRQ1", 0x94AD, 0x20},
+ { "M0G3106QDGS32RQ1", 0x94AD, 0x8D},
+ { "M0G3106QDGS28RQ1", 0x94AD, 0x03},
+ { "M0G3106QDGS20RQ1", 0x94AD, 0x6F},
+ { "M0G3105QPMRQ1", 0x1349, 0xD0},
+ { "M0G3105QPTRQ1", 0x1349, 0xEF},
+ { "M0G3105QRGZRQ1", 0x1349, 0x70},
+ { "M0G3105QRHBRQ1", 0x1349, 0x01},
+};
+
+/* https://www.ti.com/lit/gpn/mspm0c1104 Table 8-12 and so on */
+static const struct mspm0_part_info mspm0c_parts[] = {
+ { "MSPS003F4SPW20R", 0x57b3, 0x70},
+ { "MSPM0C1104SDGS20R", 0x57b3, 0x71},
+ { "MSPM0C1104SRUKR", 0x57b3, 0x73},
+ { "MSPM0C1104SDYYR", 0x57b3, 0x75},
+ { "MSPM0C1104SDDFR", 0x57b3, 0x77},
+ { "MSPM0C1104SDSGR", 0x57b3, 0x79},
+};
+
+/* https://www.ti.com/lit/gpn/MSPM0L2228 Table 8-16 and so on */
+static const struct mspm0_part_info mspm0lx22x_parts[] = {
+ { "MSPM0L1227SRGER", 0x7C32, 0xF1},
+ { "MSPM0L1227SPTR", 0x7C32, 0xC9},
+ { "MSPM0L1227SPMR", 0x7C32, 0x1C},
+ { "MSPM0L1227SPNAR", 0x7C32, 0x91},
+ { "MSPM0L1227SPNR", 0x7C32, 0x39},
+ { "MSPM0L1228SRGER", 0x33F7, 0x13},
+ { "MSPM0L1228SRHBR", 0x33F7, 0x3A},
+ { "MSPM0L1228SRGZR", 0x33F7, 0xBC},
+ { "MSPM0L1228SPTR", 0x33F7, 0xF8},
+ { "MSPM0L1228SPMR", 0x33F7, 0xCE},
+ { "MSPM0L1228SPNAR", 0x33F7, 0x59},
+ { "MSPM0L1228SPNR", 0x33F7, 0x7},
+ { "MSPM0L2227SRGZR", 0x5E8F, 0x90},
+ { "MSPM0L2227SPTR", 0x5E8F, 0xA},
+ { "MSPM0L2227SPMR", 0x5E8F, 0x6D},
+ { "MSPM0L2227SPNAR", 0x5E8F, 0x24},
+ { "MSPM0L2227SPNR", 0x5E8F, 0x68},
+ { "MSPM0L2228SRGZR", 0x2C38, 0xB8},
+ { "MSPM0L2228SPTR", 0x2C38, 0x25},
+ { "MSPM0L2228SPMR", 0x2C38, 0x6E},
+ { "MSPM0L2228SPNAR", 0x2C38, 0x63},
+ { "MSPM0L2228SPNR", 0x2C38, 0x3C},
+};
+
+static const struct mspm0_family_info mspm0_finf[] = {
+ { "MSPM0L", 0xbb82, ARRAY_SIZE(mspm0l_parts), mspm0l_parts },
+ { "MSPM0Lx22x", 0xbb9f, ARRAY_SIZE(mspm0lx22x_parts), mspm0lx22x_parts },
+ { "MSPM0G", 0xbb88, ARRAY_SIZE(mspm0g_parts), mspm0g_parts },
+ { "MSPM0C", 0xbba1, ARRAY_SIZE(mspm0c_parts), mspm0c_parts },
+};
+
+/*
+ * OpenOCD command interface
+ */
+
+/*
+ * flash_bank mspm0 <base> <size> 0 0 <target#>
+ */
+FLASH_BANK_COMMAND_HANDLER(mspm0_flash_bank_command)
+{
+ struct mspm0_flash_bank *mspm0_info;
+
+ switch (bank->base) {
+ case MSPM0_FLASH_BASE_NONMAIN:
+ case MSPM0_FLASH_BASE_MAIN:
+ case MSPM0_FLASH_BASE_DATA:
+ break;
+ default:
+ LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FAIL;
+ }
+
+ mspm0_info = calloc(1, sizeof(struct mspm0_flash_bank));
+ if (!mspm0_info) {
+ LOG_ERROR("%s: Out of memory for mspm0_info!", __func__);
+ return ERROR_FAIL;
+ }
+
+ bank->driver_priv = mspm0_info;
+
+ mspm0_info->sector_size = 0x400;
+
+ return ERROR_OK;
+}
+
+/*
+ * Chip identification and status
+ */
+static int get_mspm0_info(struct flash_bank *bank, struct command_invocation *cmd)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+
+ if (mspm0_info->did == 0)
+ return ERROR_FLASH_BANK_NOT_PROBED;
+
+ command_print_sameline(cmd,
+ "\nTI MSPM0 information: Chip is "
+ "%s rev %d Device Unique ID: 0x%" PRIu32 "\n",
+ mspm0_info->name, mspm0_info->version,
+ mspm0_info->traceid);
+ command_print_sameline(cmd,
+ "main flash: %uKiB in %u bank(s), sram: %uKiB, data flash: %uKiB",
+ mspm0_info->main_flash_size_kb,
+ mspm0_info->main_flash_num_banks, mspm0_info->sram_size_kb,
+ mspm0_info->data_flash_size_kb);
+
+ return ERROR_OK;
+}
+
+/* Extract a bitfield helper */
+static unsigned int mspm0_extract_val(unsigned int var, unsigned char hi, unsigned char lo)
+{
+ return (var & GENMASK(hi, lo)) >> lo;
+}
+
+static int mspm0_read_part_info(struct flash_bank *bank)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+ struct target *target = bank->target;
+ const struct mspm0_family_info *minfo = NULL;
+
+ /* Read and parse chip identification and flash version register */
+ uint32_t did;
+ int retval = target_read_u32(target, MSPM0_DID, &did);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to read device ID");
+ return retval;
+ }
+ retval = target_read_u32(target, MSPM0_TRACEID, &mspm0_info->traceid);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to read trace ID");
+ return retval;
+ }
+ uint32_t userid;
+ retval = target_read_u32(target, MSPM0_USERID, &userid);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to read user ID");
+ return retval;
+ }
+ uint32_t flashram;
+ retval = target_read_u32(target, MSPM0_SRAMFLASH, &flashram);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to read sramflash register");
+ return retval;
+ }
+ uint32_t flashdesc;
+ retval = target_read_u32(target, FCTL_REG_DESC, &flashdesc);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to read flashctl description register");
+ return retval;
+ }
+
+ unsigned char version = mspm0_extract_val(did, 31, 28);
+ unsigned short pnum = mspm0_extract_val(did, 27, 12);
+ unsigned char variant = mspm0_extract_val(userid, 23, 16);
+ unsigned short part = mspm0_extract_val(userid, 15, 0);
+ unsigned short manufacturer = mspm0_extract_val(did, 11, 1);
+
+ /*
+ * Valid DIE and manufacturer ID?
+ * Check the ALWAYS_1 bit to be 1 and manufacturer to be 0x17. All MSPM0
+ * devices within the Device ID field of the factory constants will
+ * always read 0x17 as it is TI's JEDEC bank and company code. If 1
+ * and 0x17 is not read from their respective registers then it truly
+ * is not a MSPM0 device so we will return an error instead of
+ * going any further.
+ */
+ if (!(did & BIT(0)) || !(manufacturer & TI_MANUFACTURER_ID)) {
+ LOG_WARNING("Unknown Device ID[0x%" PRIx32 "], cannot identify target",
+ did);
+ LOG_DEBUG("did 0x%" PRIx32 ", traceid 0x%" PRIx32 ", userid 0x%" PRIx32
+ ", flashram 0x%" PRIx32 "", did, mspm0_info->traceid, userid,
+ flashram);
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
+ /* Initialize master index selector and probe status*/
+ unsigned char minfo_idx = 0xff;
+ unsigned char probe_status = MSPM0_NO_ID_FOUND;
+
+ /* Check if we at least know the family of devices */
+ for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_finf); i++) {
+ if (mspm0_finf[i].part_num == pnum) {
+ minfo_idx = i;
+ minfo = &mspm0_finf[i];
+ probe_status = MSPM0_DEV_ID_FOUND;
+ break;
+ }
+ }
+
+ /* Initialize part index selector*/
+ unsigned char pinfo_idx = 0xff;
+
+ /*
+ * If we can identify the part number then we will attempt to identify
+ * the specific chip. Otherwise, if we do not know the part number then
+ * it would be useless to identify the specific chip.
+ */
+ if (probe_status == MSPM0_DEV_ID_FOUND) {
+ /* Can we specifically identify the chip */
+ for (unsigned int i = 0; i < minfo->part_count; i++) {
+ if (minfo->part_info[i].part == part
+ && minfo->part_info[i].variant == variant) {
+ pinfo_idx = i;
+ probe_status = MSPM0_DEV_PART_ID_FOUND;
+ break;
+ }
+ }
+ }
+
+ /*
+ * We will check the status of our probe within this switch-case statement
+ * using these three scenarios.
+ *
+ * 1) Device, part, and variant ID is unknown.
+ * 2) Device ID is known but the part/variant ID is unknown.
+ * 3) Device ID and part/variant ID is known
+ *
+ * For scenario 1, we allow the user to continue because if the
+ * manufacturer matches TI's JEDEC value and ALWAYS_1 from the device ID
+ * field is correct then the assumption the user is using an MSPM0 device
+ * can be made.
+ */
+ switch (probe_status) {
+ case MSPM0_NO_ID_FOUND:
+ mspm0_info->name = "mspm0x";
+ LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
+ "], unknown DeviceID[0x%x"
+ "]. Attempting to proceed as %s.", part, variant, pnum,
+ mspm0_info->name);
+ break;
+ case MSPM0_DEV_ID_FOUND:
+ mspm0_info->name = mspm0_finf[minfo_idx].family_name;
+ LOG_INFO("Unidentified PART[0x%x]/variant[0x%x"
+ "], known DeviceID[0x%x"
+ "]. Attempting to proceed as %s.", part, variant, pnum,
+ mspm0_info->name);
+ break;
+ case MSPM0_DEV_PART_ID_FOUND:
+ default:
+ mspm0_info->name = mspm0_finf[minfo_idx].part_info[pinfo_idx].part_name;
+ LOG_DEBUG("Part: %s detected", mspm0_info->name);
+ break;
+ }
+
+ mspm0_info->did = did;
+ mspm0_info->version = version;
+ mspm0_info->data_flash_size_kb = mspm0_extract_val(flashram, 31, 26);
+ mspm0_info->main_flash_size_kb = mspm0_extract_val(flashram, 11, 0);
+ mspm0_info->main_flash_num_banks = mspm0_extract_val(flashram, 13, 12) + 1;
+ mspm0_info->sram_size_kb = mspm0_extract_val(flashram, 25, 16);
+ mspm0_info->flash_version = mspm0_extract_val(flashdesc, 15, 12);
+
+ /*
+ * Hardcode flash_word_size unless we find some other pattern
+ * See section 7.7 (Foot note mentions the flash word size).
+ * almost all values seem to be 8 bytes, but if there are variance,
+ * then we should update mspm0_part_info structure with this info.
+ */
+ mspm0_info->flash_word_size_bytes = 8;
+
+ LOG_DEBUG("Detected: main flash: %uKb in %u banks, sram: %uKb, data flash: %uKb",
+ mspm0_info->main_flash_size_kb, mspm0_info->main_flash_num_banks,
+ mspm0_info->sram_size_kb, mspm0_info->data_flash_size_kb);
+
+ return ERROR_OK;
+}
+
+/*
+ * Decode error values
+ */
+static const struct {
+ const unsigned char bit_offset;
+ const char *fail_string;
+} mspm0_fctl_fail_decode_strings[] = {
+ { 2, "CMDINPROGRESS" },
+ { 4, "FAILWEPROT" },
+ { 5, "FAILVERIFY" },
+ { 6, "FAILILLADDR" },
+ { 7, "FAILMODE" },
+ { 12, "FAILMISC" },
+};
+
+static const char *mspm0_fctl_translate_ret_err(unsigned int return_code)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(mspm0_fctl_fail_decode_strings); i++) {
+ if (return_code & BIT(mspm0_fctl_fail_decode_strings[i].bit_offset))
+ return mspm0_fctl_fail_decode_strings[i].fail_string;
+ }
+
+ /* If unknown error notify the user*/
+ return "FAILUNKNOWN";
+}
+
+static int mspm0_fctl_get_sector_reg(struct flash_bank *bank, unsigned int addr,
+ unsigned int *reg, unsigned int *sector_mask)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+ struct target *target = bank->target;
+ int ret = ERROR_OK;
+ unsigned int sector_num = (addr >> 10);
+ unsigned int sector_in_bank = sector_num;
+ unsigned int phys_sector_num = sector_num;
+ uint32_t sysctl_sec_status;
+ unsigned int exec_upper_bank;
+
+ /*
+ * If the device has dual banks we will need to check if it is configured
+ * to execute from the upper bank. In the scenario that we are executing
+ * from upper bank then we will need to protect it using CMDWEPROTA rather
+ * than CMDWEPROTB. We also need to take into account what sector
+ * we're using when going between banks.
+ */
+ if (mspm0_info->main_flash_num_banks > 1 &&
+ bank->base == MSPM0_FLASH_BASE_MAIN) {
+ ret = target_read_u32(target, SYSCTL_SECCFG_SECSTATUS, &sysctl_sec_status);
+ if (ret != ERROR_OK)
+ return ret;
+ exec_upper_bank = mspm0_extract_val(sysctl_sec_status, 12, 12);
+ if (exec_upper_bank) {
+ if (sector_num > (mspm0_info->main_flash_size_kb / 2)) {
+ phys_sector_num =
+ sector_num - (mspm0_info->main_flash_size_kb / 2);
+ } else {
+ phys_sector_num =
+ sector_num + (mspm0_info->main_flash_size_kb / 2);
+ }
+ }
+ sector_in_bank =
+ sector_num % (mspm0_info->main_flash_size_kb /
+ mspm0_info->main_flash_num_banks);
+ }
+
+ /*
+ * NOTE: MSPM0 devices of version A will use CMDWEPROTA and CMDWEPROTB
+ * for MAIN flash. CMDWEPROTC is included in the TRM/DATASHEET but for
+ * all practical purposes, it is considered reserved. If the flash
+ * version on the device is version B, then we will only use
+ * CMDWEPROTB for MAIN and DATA flash if the device has it.
+ */
+ switch (bank->base) {
+ case MSPM0_FLASH_BASE_MAIN:
+ case MSPM0_FLASH_BASE_DATA:
+ if (mspm0_info->flash_version < FCTL_FEATURE_VER_B) {
+ /* Use CMDWEPROTA */
+ if (phys_sector_num < 32) {
+ *sector_mask = BIT(phys_sector_num);
+ *reg = FCTL_REG_CMDWEPROTA;
+ }
+
+ /* Use CMDWEPROTB */
+ if (phys_sector_num >= 32 && sector_in_bank < 256) {
+ /* Dual bank system */
+ if (mspm0_info->main_flash_num_banks > 1)
+ *sector_mask = BIT(sector_in_bank / 8);
+ else /* Single bank system */
+ *sector_mask = BIT((sector_in_bank - 32) / 8);
+ *reg = FCTL_REG_CMDWEPROTB;
+ }
+ } else {
+ *sector_mask = BIT((sector_in_bank / 8) % 32);
+ *reg = FCTL_REG_CMDWEPROTB;
+ }
+ break;
+ case MSPM0_FLASH_BASE_NONMAIN:
+ *sector_mask = BIT(sector_num % 32);
+ *reg = FCTL_REG_CMDWEPROTNM;
+ break;
+ default:
+ /*
+ * Not expected to reach here due to check in mspm0_address_check()
+ * but adding it as another layer of safety.
+ */
+ ret = ERROR_FLASH_DST_OUT_OF_BANK;
+ break;
+ }
+
+ if (ret != ERROR_OK)
+ LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
+
+ return ret;
+}
+
+static int mspm0_address_check(struct flash_bank *bank, unsigned int addr)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+ unsigned int flash_main_size = mspm0_info->main_flash_size_kb * 1024;
+ unsigned int flash_data_size = mspm0_info->data_flash_size_kb * 1024;
+ int ret = ERROR_FLASH_SECTOR_INVALID;
+
+ /*
+ * Before unprotecting any memory lets make sure that the address and
+ * bank given is a known bank and whether or not the address falls under
+ * the proper bank.
+ */
+ switch (bank->base) {
+ case MSPM0_FLASH_BASE_MAIN:
+ if (addr <= (MSPM0_FLASH_BASE_MAIN + flash_main_size))
+ ret = ERROR_OK;
+ break;
+ case MSPM0_FLASH_BASE_NONMAIN:
+ if (addr >= MSPM0_FLASH_BASE_NONMAIN && addr <= MSPM0_FLASH_END_NONMAIN)
+ ret = ERROR_OK;
+ break;
+ case MSPM0_FLASH_BASE_DATA:
+ if (addr >= MSPM0_FLASH_BASE_DATA &&
+ addr <= (MSPM0_FLASH_BASE_DATA + flash_data_size))
+ ret = ERROR_OK;
+ break;
+ default:
+ ret = ERROR_FLASH_DST_OUT_OF_BANK;
+ break;
+ }
+
+ return ret;
+}
+
+static int mspm0_fctl_unprotect_sector(struct flash_bank *bank, unsigned int addr)
+{
+ struct target *target = bank->target;
+ unsigned int reg = 0x0;
+ uint32_t sector_mask = 0x0;
+ int ret;
+
+ ret = mspm0_address_check(bank, addr);
+ switch (ret) {
+ case ERROR_FLASH_SECTOR_INVALID:
+ LOG_ERROR("Unable to map sector protect reg for address 0x%08x", addr);
+ break;
+ case ERROR_FLASH_DST_OUT_OF_BANK:
+ LOG_ERROR("Unable to determine which bank to use 0x%08x", addr);
+ break;
+ default:
+ mspm0_fctl_get_sector_reg(bank, addr, &reg, &sector_mask);
+ ret = target_write_u32(target, reg, ~sector_mask);
+ break;
+ }
+
+ return ret;
+}
+
+static int mspm0_fctl_cfg_command(struct flash_bank *bank,
+ uint32_t addr,
+ uint32_t cmd,
+ uint32_t byte_en)
+{
+ struct target *target = bank->target;
+
+ /*
+ * Configure the flash operation within the CMDTYPE register, byte_en
+ * bits if needed, and then set the address where the flash operation
+ * will execute.
+ */
+ int retval = target_write_u32(target, FCTL_REG_CMDTYPE, cmd);
+ if (retval != ERROR_OK)
+ return retval;
+ if (byte_en != 0) {
+ retval = target_write_u32(target, FCTL_REG_CMDBYTEN, byte_en);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ return target_write_u32(target, FCTL_REG_CMDADDR, addr);
+}
+
+static int mspm0_fctl_wait_cmd_ok(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ uint32_t return_code = 0;
+ int64_t start_ms;
+ int64_t elapsed_ms;
+
+ start_ms = timeval_ms();
+ while ((return_code & FCTL_STATCMD_CMDDONE_MASK) != FCTL_STATCMD_CMDDONE_STATDONE) {
+ int retval = target_read_u32(target, FCTL_REG_STATCMD, &return_code);
+ if (retval != ERROR_OK)
+ return retval;
+
+ elapsed_ms = timeval_ms() - start_ms;
+ if (elapsed_ms > 500)
+ keep_alive();
+ if (elapsed_ms > MSPM0_FLASH_TIMEOUT_MS)
+ break;
+ }
+
+ if ((return_code & FCTL_STATCMD_CMDPASS_MASK) != FCTL_STATCMD_CMDPASS_STATPASS) {
+ LOG_ERROR("Flash command failed: %s", mspm0_fctl_translate_ret_err(return_code));
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
+static int mspm0_fctl_sector_erase(struct flash_bank *bank, uint32_t addr)
+{
+ struct target *target = bank->target;
+
+ /*
+ * TRM Says:
+ * Note that the CMDWEPROTx registers are reset to a protected state
+ * at the end of all program and erase operations. These registers
+ * must be re-configured by software before a new operation is
+ * initiated.
+ *
+ * This means that as we start erasing sector by sector, the protection
+ * registers are reset and need to be unprotected *again* for the next
+ * erase operation. Unfortunately, this means that we cannot do a unitary
+ * unprotect operation independent of flash erase operation
+ */
+ int retval = mspm0_fctl_unprotect_sector(bank, addr);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Unprotecting sector of memory at address 0x%08" PRIx32
+ " failed", addr);
+ return retval;
+ }
+
+ /* Actual erase operation */
+ retval = mspm0_fctl_cfg_command(bank, addr,
+ (FCTL_CMDTYPE_COMMAND_ERASE | FCTL_CMDTYPE_SIZE_SECTOR), 0);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_VAL_EXECUTE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return mspm0_fctl_wait_cmd_ok(bank);
+}
+
+static int mspm0_protect_check(struct flash_bank *bank)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+
+ if (mspm0_info->did == 0)
+ return ERROR_FLASH_BANK_NOT_PROBED;
+
+ /*
+ * TRM Says:
+ * Note that the CMDWEPROTx registers are reset to a protected state
+ * at the end of all program and erase operations. These registers
+ * must be re-configured by software before a new operation is
+ * initiated.
+ *
+ * This means that when any flash operation is performed at a block level,
+ * the block is locked back again. This prevents usage where we can set a
+ * protection level once at the flash level and then do erase / write
+ * operation without touching the protection register (since it is
+ * reset by hardware automatically). In effect, we cannot use the hardware
+ * defined protection scheme in openOCD.
+ *
+ * To deal with this protection scheme, the CMDWEPROTx register that
+ * correlates to the sector is modified at the time of operation and as far
+ * openOCD is concerned, the flash operates as completely un-protected
+ * flash.
+ */
+ for (unsigned int i = 0; i < bank->num_sectors; i++)
+ bank->sectors[i].is_protected = 0;
+
+ return ERROR_OK;
+}
+
+static int mspm0_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
+{
+ struct target *target = bank->target;
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+ int retval = ERROR_OK;
+ uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Please halt target for erasing flash");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (mspm0_info->did == 0)
+ return ERROR_FLASH_BANK_NOT_PROBED;
+
+ /* Pick a copy of the current protection config for later restoration */
+ for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
+ retval = target_read_u32(target,
+ mspm0_info->protect_reg_base + (i * 4),
+ &protect_reg_cache[i]);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed saving flashctl protection status");
+ return retval;
+ }
+ }
+
+ switch (bank->base) {
+ case MSPM0_FLASH_BASE_MAIN:
+ for (unsigned int csa = first; csa <= last; csa++) {
+ unsigned int addr = csa * mspm0_info->sector_size;
+ retval = mspm0_fctl_sector_erase(bank, addr);
+ if (retval != ERROR_OK)
+ LOG_ERROR("Sector erase on MAIN failed at address 0x%08x "
+ "(sector: %u)", addr, csa);
+ }
+ break;
+ case MSPM0_FLASH_BASE_NONMAIN:
+ retval = mspm0_fctl_sector_erase(bank, MSPM0_FLASH_BASE_NONMAIN);
+ if (retval != ERROR_OK)
+ LOG_ERROR("Sector erase on NONMAIN failed");
+ break;
+ case MSPM0_FLASH_BASE_DATA:
+ for (unsigned int csa = first; csa <= last; csa++) {
+ unsigned int addr = (MSPM0_FLASH_BASE_DATA +
+ (csa * mspm0_info->sector_size));
+ retval = mspm0_fctl_sector_erase(bank, addr);
+ if (retval != ERROR_OK)
+ LOG_ERROR("Sector erase on DATA bank failed at address 0x%08x "
+ "(sector: %u)", addr, csa);
+ }
+ break;
+ default:
+ LOG_ERROR("Invalid memory region access");
+ retval = ERROR_FLASH_BANK_INVALID;
+ break;
+ }
+
+ /* If there were any issues in our checks, return the error */
+ if (retval != ERROR_OK)
+ return retval;
+
+ /*
+ * TRM Says:
+ * Note that the CMDWEPROTx registers are reset to a protected state
+ * at the end of all program and erase operations. These registers
+ * must be re-configured by software before a new operation is
+ * initiated
+ * Let us just Dump the protection registers back to the system.
+ * That way we retain the protection status as requested by the user
+ */
+ for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
+ retval = target_write_u32(target, mspm0_info->protect_reg_base + (i * 4),
+ protect_reg_cache[i]);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed re-applying protection status of flashctl");
+ return retval;
+ }
+ }
+
+ return retval;
+}
+
+static int mspm0_write(struct flash_bank *bank, const unsigned char *buffer,
+ unsigned int offset, unsigned int count)
+{
+ struct target *target = bank->target;
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+ uint32_t protect_reg_cache[MSPM0_MAX_PROTREGS];
+ int retval;
+
+ /*
+ * XXX: TRM Says:
+ * The number of program operations applied to a given word line must be
+ * monitored to ensure that the maximum word line program limit before
+ * erase is not violated.
+ *
+ * There is no reasonable way we can maintain that state in OpenOCD. So,
+ * Let the manufacturing path figure this out.
+ */
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Please halt target for programming flash");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (mspm0_info->did == 0)
+ return ERROR_FLASH_BANK_NOT_PROBED;
+
+ /*
+ * Pick a copy of the current protection config for later restoration
+ * We need to restore these regs after every write, so instead of trying
+ * to figure things out on the fly, we just context save and restore
+ */
+ for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
+ retval = target_read_u32(target,
+ mspm0_info->protect_reg_base + (i * 4),
+ &protect_reg_cache[i]);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed saving flashctl protection status");
+ return retval;
+ }
+ }
+
+ /* Add proper memory offset for bank being written to */
+ unsigned int addr = bank->base + offset;
+
+ while (count) {
+ unsigned int num_bytes_to_write;
+ uint32_t bytes_en;
+
+ /*
+ * If count is not 64 bit aligned, we will do byte wise op to keep things simple
+ * Usually this might mean we need to additional write ops towards
+ * trailing edge, but that is a tiny penalty for image downloads.
+ * NOTE: we are going to assume the device does not support multi-word
+ * programming - there does not seem to be discoverability!
+ */
+ if (count < mspm0_info->flash_word_size_bytes)
+ num_bytes_to_write = count;
+ else
+ num_bytes_to_write = mspm0_info->flash_word_size_bytes;
+
+ /* Data bytes to write */
+ bytes_en = (1 << num_bytes_to_write) - 1;
+ /* ECC chunks to write */
+ switch (mspm0_info->flash_word_size_bytes) {
+ case 8:
+ bytes_en |= BIT(8);
+ break;
+ case 16:
+ bytes_en |= BIT(16);
+ bytes_en |= (num_bytes_to_write > 8) ? BIT(17) : 0;
+ break;
+ default:
+ LOG_ERROR("Invalid flash_word_size_bytes %d",
+ mspm0_info->flash_word_size_bytes);
+ return ERROR_FAIL;
+ }
+
+ retval = mspm0_fctl_cfg_command(bank, addr,
+ (FCTL_CMDTYPE_COMMAND_PROGRAM | FCTL_CMDTYPE_SIZE_ONEWORD),
+ bytes_en);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = mspm0_fctl_unprotect_sector(bank, addr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_buffer(target, FCTL_REG_CMDDATA0, num_bytes_to_write, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+
+ addr += num_bytes_to_write;
+ buffer += num_bytes_to_write;
+ count -= num_bytes_to_write;
+
+ retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_VAL_EXECUTE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = mspm0_fctl_wait_cmd_ok(bank);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ /*
+ * TRM Says:
+ * Note that the CMDWEPROTx registers are reset to a protected state
+ * at the end of all program and erase operations. These registers
+ * must be re-configured by software before a new operation is
+ * initiated
+ * Let us just Dump the protection registers back to the system.
+ * That way we retain the protection status as requested by the user
+ */
+ for (unsigned int i = 0; i < mspm0_info->protect_reg_count; i++) {
+ retval = target_write_u32(target,
+ mspm0_info->protect_reg_base + (i * 4),
+ protect_reg_cache[i]);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed re-applying protection status of flashctl");
+ return retval;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+static int mspm0_probe(struct flash_bank *bank)
+{
+ struct mspm0_flash_bank *mspm0_info = bank->driver_priv;
+
+ /*
+ * If this is a mspm0 chip, it has flash; probe() is just
+ * to figure out how much is present. Only do it once.
+ */
+ if (mspm0_info->did != 0)
+ return ERROR_OK;
+
+ /*
+ * mspm0_read_part_info() already handled error checking and
+ * reporting. Note that it doesn't write, so we don't care about
+ * whether the target is halted or not.
+ */
+ int retval = mspm0_read_part_info(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (bank->sectors) {
+ free(bank->sectors);
+ bank->sectors = NULL;
+ }
+
+ bank->write_start_alignment = 4;
+ bank->write_end_alignment = 4;
+
+ switch (bank->base) {
+ case MSPM0_FLASH_BASE_NONMAIN:
+ bank->size = 1024;
+ bank->num_sectors = 0x1;
+ mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTNM;
+ mspm0_info->protect_reg_count = 1;
+ break;
+ case MSPM0_FLASH_BASE_MAIN:
+ bank->size = (mspm0_info->main_flash_size_kb * 1024);
+ bank->num_sectors = bank->size / mspm0_info->sector_size;
+ /*
+ * If the feature version bit read from the FCTL_REG_DESC is
+ * greater than or equal to 0xA then it means that the device
+ * will exclusively use CMDWEPROTB ONLY for MAIN memory protection
+ */
+ if (mspm0_info->flash_version >= FCTL_FEATURE_VER_B) {
+ mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
+ mspm0_info->protect_reg_count = 1;
+ } else {
+ mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTA;
+ mspm0_info->protect_reg_count = 3;
+ }
+ break;
+ case MSPM0_FLASH_BASE_DATA:
+ if (!mspm0_info->data_flash_size_kb) {
+ LOG_INFO("Data region NOT available!");
+ bank->size = 0x0;
+ bank->num_sectors = 0x0;
+ return ERROR_OK;
+ }
+ /*
+ * Any MSPM0 device containing data bank will have a flashctl
+ * feature version of 0xA or higher. Since data bank is treated
+ * like MAIN memory, it will also exclusively use CMDWEPROTB for
+ * protection.
+ */
+ bank->size = (mspm0_info->data_flash_size_kb * 1024);
+ bank->num_sectors = bank->size / mspm0_info->sector_size;
+ mspm0_info->protect_reg_base = FCTL_REG_CMDWEPROTB;
+ mspm0_info->protect_reg_count = 1;
+ break;
+ default:
+ LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT,
+ bank->base);
+ return ERROR_FAIL;
+ }
+
+ bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
+ if (!bank->sectors) {
+ LOG_ERROR("Out of memory for sectors!");
+ return ERROR_FAIL;
+ }
+ for (unsigned int i = 0; i < bank->num_sectors; i++) {
+ bank->sectors[i].offset = i * mspm0_info->sector_size;
+ bank->sectors[i].size = mspm0_info->sector_size;
+ bank->sectors[i].is_erased = -1;
+ }
+
+ return ERROR_OK;
+}
+
+const struct flash_driver mspm0_flash = {
+ .name = "mspm0",
+ .flash_bank_command = mspm0_flash_bank_command,
+ .erase = mspm0_erase,
+ .protect = NULL,
+ .write = mspm0_write,
+ .read = default_flash_read,
+ .probe = mspm0_probe,
+ .auto_probe = mspm0_probe,
+ .erase_check = default_flash_blank_check,
+ .protect_check = mspm0_protect_check,
+ .info = get_mspm0_info,
+ .free_driver_priv = default_flash_free_driver_priv,
+};
diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c
index 0c36e2c..aaf0726 100644
--- a/src/flash/nor/niietcm4.c
+++ b/src/flash/nor/niietcm4.c
@@ -311,7 +311,7 @@ static int niietcm4_uflash_page_erase(struct flash_bank *bank, int page_num, int
/* status check */
retval = niietcm4_uopstatus_check(bank);
if (retval != ERROR_OK)
- return retval;
+ return retval;
return retval;
}
@@ -394,7 +394,7 @@ COMMAND_HANDLER(niietcm4_handle_uflash_read_byte_command)
uint32_t uflash_data;
if (strcmp("info", CMD_ARGV[0]) == 0)
- uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
+ uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
else if (strcmp("main", CMD_ARGV[0]) == 0)
uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ;
else
@@ -539,7 +539,7 @@ COMMAND_HANDLER(niietcm4_handle_uflash_erase_command)
int mem_type;
if (strcmp("info", CMD_ARGV[0]) == 0)
- mem_type = 1;
+ mem_type = 1;
else if (strcmp("main", CMD_ARGV[0]) == 0)
mem_type = 0;
else
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index f07433e..5cb552a 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -117,20 +117,24 @@ struct nrf5_map {
struct nrf5_info {
unsigned int refcount;
+ bool chip_probed;
struct nrf5_bank {
struct nrf5_info *chip;
bool probed;
} bank[2];
+
struct target *target;
- /* chip identification stored in nrf5_probe() for use in nrf5_info() */
+ /* chip identification stored in nrf5_probe_chip()
+ * for use in nrf5_info() and nrf5_setup_bank() */
bool ficr_info_valid;
struct nrf52_ficr_info ficr_info;
const struct nrf5_device_spec *spec;
uint16_t hwid;
enum nrf5_features features;
- unsigned int flash_size_kb;
+ uint32_t flash_page_size;
+ uint32_t flash_num_sectors;
unsigned int ram_size_kb;
const struct nrf5_map *map;
@@ -341,16 +345,19 @@ const struct flash_driver nrf5_flash, nrf51_flash;
static bool nrf5_bank_is_probed(const struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
-
return nbank->probed;
}
-static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+static bool nrf5_chip_is_probed(const struct flash_bank *bank)
{
+ struct nrf5_bank *nbank = bank->driver_priv;
struct nrf5_info *chip = nbank->chip;
- assert(chip);
+ return chip->chip_probed;
+}
+static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+{
+ struct nrf5_info *chip = nbank->chip;
return nbank == &chip->bank[1];
}
@@ -470,9 +477,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
uint32_t clenr0;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
res = target_read_u32(chip->target, NRF51_FICR_CLENR0,
&clenr0);
@@ -501,9 +506,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
static int nrf52_protect_check_bprot(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
static uint32_t nrf5_bprot_offsets[4] = { 0x600, 0x604, 0x610, 0x614 };
uint32_t bprot_reg = 0;
@@ -528,9 +531,7 @@ static int nrf52_protect_check_bprot(struct flash_bank *bank)
static int nrf5_protect_check(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR cannot be write protected so just return early */
if (nrf5_bank_is_uicr(nbank))
@@ -554,9 +555,7 @@ static int nrf51_protect_clenr0(struct flash_bank *bank, int set, unsigned int f
uint32_t clenr0, ppfc;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
if (first != 0) {
LOG_ERROR("Code region 0 must start at the beginning of the bank");
@@ -614,9 +613,7 @@ static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,
unsigned int last)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR cannot be write protected so just bail out early */
if (nrf5_bank_is_uicr(nbank)) {
@@ -701,16 +698,15 @@ static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsig
static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
char chip_type_str[256];
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
return ERROR_FAIL;
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM",
- chip_type_str, chip->flash_size_kb, chip->ram_size_kb);
+ chip_type_str, flash_size_kb, chip->ram_size_kb);
return ERROR_OK;
}
@@ -838,14 +834,12 @@ static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size)
return res;
}
-static int nrf5_probe(struct flash_bank *bank)
+static int nrf5_probe_chip(struct flash_bank *bank)
{
int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
struct target *target = chip->target;
chip->spec = NULL;
@@ -968,9 +962,8 @@ static int nrf5_probe(struct flash_bank *bank)
}
/* The value stored in FICR CODEPAGESIZE is the number of bytes in one page of FLASH. */
- uint32_t flash_page_size;
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codepagesize,
- &flash_page_size);
+ &chip->flash_page_size);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code page size");
return res;
@@ -978,69 +971,93 @@ static int nrf5_probe(struct flash_bank *bank)
/* Note the register name is misleading,
* FICR CODESIZE is the number of pages in flash memory, not the number of bytes! */
- uint32_t num_sectors;
res = target_read_u32(chip->target, ficr_base + ficr_offsets->codesize,
- &num_sectors);
+ &chip->flash_num_sectors);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code memory size");
return res;
}
- chip->flash_size_kb = num_sectors * flash_page_size / 1024;
+ char chip_type_str[256];
+ if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
+ return ERROR_FAIL;
- if (!chip->bank[0].probed && !chip->bank[1].probed) {
- char chip_type_str[256];
- if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
- return ERROR_FAIL;
- const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
- LOG_INFO("%s%s %ukB Flash, %ukB RAM",
- device_is_unknown ? "Unknown device: " : "",
- chip_type_str,
- chip->flash_size_kb,
- chip->ram_size_kb);
- }
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
+ const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
+ LOG_INFO("%s%s %ukB Flash, %ukB RAM",
+ device_is_unknown ? "Unknown device: " : "",
+ chip_type_str,
+ flash_size_kb,
+ chip->ram_size_kb);
- free(bank->sectors);
+ chip->chip_probed = true;
+ return ERROR_OK;
+}
+
+static int nrf5_setup_bank(struct flash_bank *bank)
+{
+ struct nrf5_bank *nbank = bank->driver_priv;
+ struct nrf5_info *chip = nbank->chip;
if (bank->base == chip->map->flash_base) {
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
/* Sanity check */
- if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb)
+ if (chip->spec && flash_size_kb != chip->spec->flash_size_kb)
LOG_WARNING("Chip's reported Flash capacity does not match expected one");
- if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash)
+ if (chip->ficr_info_valid && flash_size_kb != chip->ficr_info.flash)
LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
- bank->num_sectors = num_sectors;
- bank->size = num_sectors * flash_page_size;
+ bank->num_sectors = chip->flash_num_sectors;
+ bank->size = chip->flash_num_sectors * chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
chip->bank[0].probed = true;
- } else {
+ } else if (bank->base == chip->map->uicr_base) {
/* UICR bank */
bank->num_sectors = 1;
- bank->size = flash_page_size;
+ bank->size = chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
bank->sectors[0].is_protected = 0;
chip->bank[1].probed = true;
+ } else {
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
return ERROR_OK;
}
+static int nrf5_probe(struct flash_bank *bank)
+{
+ /* probe always reads actual info from the device */
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+
+ return nrf5_setup_bank(bank);
+}
+
static int nrf5_auto_probe(struct flash_bank *bank)
{
if (nrf5_bank_is_probed(bank))
return ERROR_OK;
- return nrf5_probe(bank);
+ if (!nrf5_chip_is_probed(bank)) {
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ return nrf5_setup_bank(bank);
}
@@ -1214,9 +1231,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
assert(offset % 4 == 0);
assert(count % 4 == 0);
@@ -1276,9 +1291,7 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR CLENR0 based protection used on nRF51 prevents erase
* absolutely silently. NVMC has no flag to indicate the protection
@@ -1322,7 +1335,6 @@ error:
static void nrf5_free_driver_priv(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
if (!chip)
return;
@@ -1372,8 +1384,8 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
case NRF53NET_UICR_BASE:
break;
default:
- LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
- return ERROR_FAIL;
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
chip = nrf5_get_chip(bank->target);
@@ -1418,17 +1430,13 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command)
if (res != ERROR_OK)
return res;
- assert(bank);
-
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
if (chip->features & NRF5_FEATURE_SERIES_51) {
uint32_t ppfc;
diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c
index e00c365..61af908 100644
--- a/src/flash/nor/ocl.c
+++ b/src/flash/nor/ocl.c
@@ -160,7 +160,7 @@ static int ocl_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of
retval = embeddedice_send(ocl->jtag_info, dcc_buffer, dcc_bufptr-dcc_buffer);
if (retval != ERROR_OK) {
free(dcc_buffer);
- return retval;
+ return retval;
}
/* wait for response, fixed timeout of 1 s */
diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c
index 1064fa9..72cf0ee 100644
--- a/src/flash/nor/psoc4.c
+++ b/src/flash/nor/psoc4.c
@@ -384,15 +384,15 @@ static int psoc4_get_silicon_id(struct flash_bank *bank, uint32_t *silicon_id, u
* bit 7..0 family ID (lowest 8 bits)
*/
if (silicon_id)
- *silicon_id = ((part0 & 0x0000ffff) << 16)
- | ((part0 & 0x00ff0000) >> 8)
- | (part1 & 0x000000ff);
+ *silicon_id = ((part0 & 0x0000ffff) << 16)
+ | ((part0 & 0x00ff0000) >> 8)
+ | (part1 & 0x000000ff);
if (family_id)
- *family_id = part1 & 0x0fff;
+ *family_id = part1 & 0x0fff;
if (protection)
- *protection = (part1 >> 12) & 0x0f;
+ *protection = (part1 >> 12) & 0x0f;
return ERROR_OK;
}
diff --git a/src/flash/nor/psoc5lp.c b/src/flash/nor/psoc5lp.c
index 407efbc..e8c9019 100644
--- a/src/flash/nor/psoc5lp.c
+++ b/src/flash/nor/psoc5lp.c
@@ -102,10 +102,10 @@
struct psoc5lp_device {
uint32_t id;
- unsigned fam;
- unsigned speed_mhz;
- unsigned flash_kb;
- unsigned eeprom_kb;
+ unsigned int fam;
+ unsigned int speed_mhz;
+ unsigned int flash_kb;
+ unsigned int eeprom_kb;
};
/*
@@ -245,7 +245,7 @@ static int psoc5lp_find_device(struct target *target,
const struct psoc5lp_device **device)
{
uint32_t device_id;
- unsigned i;
+ unsigned int i;
int retval;
*device = NULL;
@@ -381,9 +381,9 @@ static int psoc5lp_spc_load_byte(struct target *target,
}
static int psoc5lp_spc_load_row(struct target *target,
- uint8_t array_id, const uint8_t *data, unsigned row_size)
+ uint8_t array_id, const uint8_t *data, unsigned int row_size)
{
- unsigned i;
+ unsigned int i;
int retval;
retval = psoc5lp_spc_write_opcode(target, SPC_LOAD_ROW);
@@ -853,7 +853,7 @@ static int psoc5lp_eeprom_write(struct flash_bank *bank,
{
struct target *target = bank->target;
uint8_t temp[2];
- unsigned row;
+ unsigned int row;
int retval;
if (offset % EEPROM_ROW_SIZE != 0) {
@@ -1124,7 +1124,7 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
struct working_area *code_area, *even_row_area, *odd_row_area;
uint32_t row_size;
uint8_t temp[2], buf[12], ecc_bytes[ROW_ECC_SIZE];
- unsigned array_id, row;
+ unsigned int array_id, row;
int i, retval;
if (offset + byte_count > bank->size) {
@@ -1183,7 +1183,7 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
row < ROWS_PER_BLOCK && byte_count > 0; row++) {
bool even_row = (row % 2 == 0);
struct working_area *data_area = even_row ? even_row_area : odd_row_area;
- unsigned len = MIN(ROW_SIZE, byte_count);
+ unsigned int len = MIN(ROW_SIZE, byte_count);
LOG_DEBUG("Writing load command for array %u row %u at " TARGET_ADDR_FMT,
array_id, row, data_area->address);
@@ -1307,8 +1307,8 @@ static int psoc5lp_protect_check(struct flash_bank *bank)
{
struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
uint8_t row_data[ROW_SIZE];
- const unsigned protection_bytes_per_sector = ROWS_PER_SECTOR * 2 / 8;
- unsigned i, k, num_sectors;
+ const unsigned int protection_bytes_per_sector = ROWS_PER_SECTOR * 2 / 8;
+ unsigned int i, k, num_sectors;
int retval;
if (bank->target->state != TARGET_HALTED) {
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index 859b3e9..662910a 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -223,6 +223,8 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
{
int hr;
uint32_t reg_val;
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
struct timeout to;
timeout_init(&to, IPC_TIMEOUT_MS);
@@ -244,7 +246,7 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
return ERROR_OK;
}
- if (target->coreid) {
+ if (!is_cm0) {
LOG_WARNING("SROM API calls via CM4 target are supported on single-core PSoC6 devices only. "
"Please perform all Flash-related operations via CM0+ target on dual-core devices.");
}
@@ -485,7 +487,7 @@ static int psoc6_get_info(struct flash_bank *bank, struct command_invocation *cm
{
struct psoc6_target_info *psoc6_info = bank->driver_priv;
- if (psoc6_info->is_probed == false)
+ if (!psoc6_info->is_probed)
return ERROR_FAIL;
int hr = get_silicon_id(bank->target, &psoc6_info->silicon_id, &psoc6_info->protection);
@@ -886,7 +888,8 @@ static int handle_reset_halt(struct target *target)
{
int hr;
uint32_t reset_addr;
- bool is_cm0 = (target->coreid == 0);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
/* Halt target device */
if (target->state != TARGET_HALTED) {
diff --git a/src/flash/nor/rsl10.c b/src/flash/nor/rsl10.c
index c286e9a..c330997 100644
--- a/src/flash/nor/rsl10.c
+++ b/src/flash/nor/rsl10.c
@@ -155,11 +155,6 @@ static int rsl10_get_probed_chip_if_halted(struct flash_bank *bank, struct rsl10
static int rsl10_protect_check(struct flash_bank *bank)
{
- struct rsl10_bank *nbank = bank->driver_priv;
- struct rsl10_info *chip = nbank->chip;
-
- assert(chip);
-
uint32_t status;
int retval = target_read_u32(bank->target, RSL10_FLASH_REG_IF_STATUS, &status);
diff --git a/src/flash/nor/sfdp.c b/src/flash/nor/sfdp.c
index 5bfb541..8e25ba6 100644
--- a/src/flash/nor/sfdp.c
+++ b/src/flash/nor/sfdp.c
@@ -12,7 +12,6 @@
#include "spi.h"
#include "sfdp.h"
-#define SFDP_MAGIC 0x50444653
#define SFDP_ACCESS_PROT 0xFF
#define SFDP_BASIC_FLASH 0xFF00
#define SFDP_4BYTE_ADDR 0xFF84
@@ -100,11 +99,11 @@ int spi_sfdp(struct flash_bank *bank, struct flash_device *dev,
goto err;
for (k = 0; k < nph; k++) {
- uint8_t words = (pheaders[k].revision >> 24) & 0xFF;
+ unsigned int words = (pheaders[k].revision >> 24) & 0xFF;
uint16_t id = (((pheaders[k].ptr) >> 16) & 0xFF00) | (pheaders[k].revision & 0xFF);
uint32_t ptr = pheaders[k].ptr & 0xFFFFFF;
- LOG_DEBUG("pheader %d len=0x%02" PRIx8 " id=0x%04" PRIx16
+ LOG_DEBUG("pheader %d len=0x%02x id=0x%04" PRIx16
" ptr=0x%06" PRIx32, k, words, id, ptr);
/* retrieve parameter table */
diff --git a/src/flash/nor/sfdp.h b/src/flash/nor/sfdp.h
index 1c9af32..0d43519 100644
--- a/src/flash/nor/sfdp.h
+++ b/src/flash/nor/sfdp.h
@@ -7,6 +7,8 @@
#ifndef OPENOCD_FLASH_NOR_SFDP_H
#define OPENOCD_FLASH_NOR_SFDP_H
+#define SFDP_MAGIC 0x50444653
+
/* per JESD216D 'addr' is *byte* based but must be word aligned,
* 'buffer' is word based, word aligned and always little-endian encoded,
* in the flash, 'addr_len' is 3 or 4, 'dummy' ***usually*** 8
@@ -16,7 +18,7 @@
*
* buffer contents is supposed to be returned in ***host*** endianness */
typedef int (*read_sfdp_block_t)(struct flash_bank *bank, uint32_t addr,
- uint32_t words, uint32_t *buffer);
+ unsigned int words, uint32_t *buffer);
extern int spi_sfdp(struct flash_bank *bank, struct flash_device *dev,
read_sfdp_block_t read_sfdp_block);
diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c
index 42550d0..58d7913 100644
--- a/src/flash/nor/sim3x.c
+++ b/src/flash/nor/sim3x.c
@@ -859,7 +859,7 @@ static int sim3x_flash_info(struct flash_bank *bank, struct command_invocation *
* reg 3:2 - register
* reg 1:0 - no effect
*/
-static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
+static int ap_write_register(struct adiv5_dap *dap, unsigned int reg, uint32_t value)
{
LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value);
@@ -886,7 +886,7 @@ static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value
return ERROR_OK;
}
-static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
+static int ap_read_register(struct adiv5_dap *dap, unsigned int reg, uint32_t *result)
{
struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
if (!ap) {
@@ -912,7 +912,7 @@ static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *resul
return ERROR_OK;
}
-static int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout)
+static int ap_poll_register(struct adiv5_dap *dap, unsigned int reg, uint32_t mask, uint32_t value, int timeout)
{
uint32_t val;
int retval;
diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c
index eab6244..1f53b2f 100644
--- a/src/flash/nor/stellaris.c
+++ b/src/flash/nor/stellaris.c
@@ -530,7 +530,7 @@ static void stellaris_set_flash_timing(struct flash_bank *bank)
target_write_u32(target, SCB_BASE | USECRL, usecrl);
}
-static const unsigned rcc_xtal[32] = {
+static const unsigned int rcc_xtal[32] = {
[0x00] = 1000000, /* no pll */
[0x01] = 1843200, /* no pll */
[0x02] = 2000000, /* no pll */
@@ -569,7 +569,7 @@ static void stellaris_read_clock_info(struct flash_bank *bank)
struct stellaris_flash_bank *stellaris_info = bank->driver_priv;
struct target *target = bank->target;
uint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;
- unsigned xtal;
+ unsigned int xtal;
unsigned long mainfreq;
target_read_u32(target, SCB_BASE | RCC, &rcc);
@@ -1029,7 +1029,7 @@ static int stellaris_write_block(struct flash_bank *bank,
int retval = ERROR_OK;
/* power of two, and multiple of word size */
- static const unsigned buf_min = 128;
+ static const unsigned int buf_min = 128;
/* for small buffers it's faster not to download an algorithm */
if (wcount * 4 < buf_min)
@@ -1056,8 +1056,8 @@ static int stellaris_write_block(struct flash_bank *bank,
target_free_working_area(target, write_algorithm);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
- target_name(target), (unsigned) buffer_size);
+ LOG_DEBUG("retry target_alloc_working_area(%s, size=%" PRIu32 ")",
+ target_name(target), buffer_size);
}
target_write_buffer(target, write_algorithm->address,
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 0399385..fa57db8 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -120,6 +120,18 @@
* http://www.st.com/resource/en/reference_manual/dm00346336.pdf
*/
+/* STM32U0xxx series for reference.
+ *
+ * RM0503 (STM32U0xx)
+ * https://www.st.com/resource/en/reference_manual/rm0503-stm32u0-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
+ */
+
+/* STM32U5xxx series for reference.
+ *
+ * RM0456 (STM32U5xx)
+ * http://www.st.com/resource/en/reference_manual/dm00477635.pdf
+ */
+
/* Erase time can be as high as 25ms, 10x this and assume it's toast... */
#define FLASH_ERASE_TIMEOUT 250
@@ -272,7 +284,7 @@ struct stm32l4_wrp {
};
/* human readable list of families this drivers supports (sorted alphabetically) */
-static const char *device_families = "STM32C0/G0/G4/L4/L4+/L5/U5/WB/WL";
+static const char *device_families = "STM32C0/G0/G4/L4/L4+/L5/U0/U5/WB/WL";
static const struct stm32l4_rev stm32l47_l48xx_revs[] = {
{ 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" }
@@ -291,6 +303,10 @@ static const struct stm32l4_rev stm32c03xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" },
};
+static const struct stm32l4_rev stm32c071xx_revs[] = {
+ { 0x1001, "Z" },
+};
+
static const struct stm32l4_rev stm32g05_g06xx_revs[] = {
{ 0x1000, "A" },
};
@@ -319,6 +335,10 @@ static const struct stm32l4_rev stm32g0b_g0cxx_revs[] = {
{ 0x1000, "A" },
};
+static const struct stm32l4_rev stm32u0xx_revs[] = {
+ { 0x1000, "A" },
+};
+
static const struct stm32l4_rev stm32g43_g44xx_revs[] = {
{ 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" },
};
@@ -344,9 +364,21 @@ static const struct stm32l4_rev stm32g49_g4axx_revs[] = {
{ 0x1000, "A" },
};
+static const struct stm32l4_rev stm32u53_u54xx_revs[] = {
+ { 0x1000, "A" }, { 0x1001, "Z" },
+};
+
static const struct stm32l4_rev stm32u57_u58xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2000, "B" },
- { 0x2001, "X" }, { 0x3000, "C" },
+ { 0x2001, "X" }, { 0x3000, "C" }, { 0x3001, "W" }, { 0x3007, "U" },
+};
+
+static const struct stm32l4_rev stm32u59_u5axx_revs[] = {
+ { 0x3001, "X" }, { 0x3002, "W" },
+};
+
+static const struct stm32l4_rev stm32u5f_u5gxx_revs[] = {
+ { 0x1000, "A" }, { 0x1001, "Z" },
};
static const struct stm32l4_rev stm32wba5x_revs[] = {
@@ -419,6 +451,30 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32C071XX,
+ .revs = stm32c071xx_revs,
+ .num_revs = ARRAY_SIZE(stm32c071xx_revs),
+ .device_str = "STM32C071xx",
+ .max_flash_size_kb = 128,
+ .flags = F_NONE,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x1FFF75A0,
+ .otp_base = 0x1FFF7000,
+ .otp_size = 1024,
+ },
+ {
+ .id = DEVID_STM32U53_U54XX,
+ .revs = stm32u53_u54xx_revs,
+ .num_revs = ARRAY_SIZE(stm32u53_u54xx_revs),
+ .device_str = "STM32U535/U545",
+ .max_flash_size_kb = 512,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32G05_G06XX,
.revs = stm32g05_g06xx_revs,
.num_revs = ARRAY_SIZE(stm32g05_g06xx_revs),
@@ -575,6 +631,42 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32U031XX,
+ .revs = stm32u0xx_revs,
+ .num_revs = ARRAY_SIZE(stm32u0xx_revs),
+ .device_str = "STM32U031xx",
+ .max_flash_size_kb = 64,
+ .flags = F_NONE,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x1FFF3EA0,
+ .otp_base = 0x1FFF6800,
+ .otp_size = 1024,
+ },
+ {
+ .id = DEVID_STM32U073_U083XX,
+ .revs = stm32u0xx_revs,
+ .num_revs = ARRAY_SIZE(stm32u0xx_revs),
+ .device_str = "STM32U073/U083xx",
+ .max_flash_size_kb = 256,
+ .flags = F_NONE,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x1FFF6EA0,
+ .otp_base = 0x1FFF6800,
+ .otp_size = 1024,
+ },
+ {
+ .id = DEVID_STM32U59_U5AXX,
+ .revs = stm32u59_u5axx_revs,
+ .num_revs = ARRAY_SIZE(stm32u59_u5axx_revs),
+ .device_str = "STM32U59/U5Axx",
+ .max_flash_size_kb = 4096,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32U57_U58XX,
.revs = stm32u57_u58xx_revs,
.num_revs = ARRAY_SIZE(stm32u57_u58xx_revs),
@@ -587,6 +679,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 512,
},
{
+ .id = DEVID_STM32U5F_U5GXX,
+ .revs = stm32u5f_u5gxx_revs,
+ .num_revs = ARRAY_SIZE(stm32u5f_u5gxx_revs),
+ .device_str = "STM32U5F/U5Gxx",
+ .max_flash_size_kb = 4096,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32WBA5X,
.revs = stm32wba5x_revs,
.num_revs = ARRAY_SIZE(stm32wba5x_revs),
@@ -679,7 +783,8 @@ struct range {
};
static void bitmap_to_ranges(unsigned long *bitmap, unsigned int nbits,
- struct range *ranges, unsigned int *ranges_count) {
+ struct range *ranges, unsigned int *ranges_count)
+{
*ranges_count = 0;
bool last_bit = 0, cur_bit;
for (unsigned int i = 0; i < nbits; i++) {
@@ -1916,8 +2021,11 @@ static int stm32l4_probe(struct flash_bank *bank)
case DEVID_STM32L43_L44XX:
case DEVID_STM32C01XX:
case DEVID_STM32C03XX:
+ case DEVID_STM32C071XX:
case DEVID_STM32G05_G06XX:
case DEVID_STM32G07_G08XX:
+ case DEVID_STM32U031XX:
+ case DEVID_STM32U073_U083XX:
case DEVID_STM32L45_L46XX:
case DEVID_STM32L41_L42XX:
case DEVID_STM32G03_G04XX:
@@ -2000,10 +2108,23 @@ static int stm32l4_probe(struct flash_bank *bank)
stm32l4_info->bank1_sectors = num_pages / 2;
}
break;
+ case DEVID_STM32U53_U54XX:
case DEVID_STM32U57_U58XX:
- /* if flash size is max (2M) the device is always dual bank
- * otherwise check DUALBANK
+ case DEVID_STM32U59_U5AXX:
+ case DEVID_STM32U5F_U5GXX:
+ /* according to RM0456 Rev 4, Chapter 7.3.1 and 7.9.13
+ * U53x/U54x have 512K max flash size:
+ * 512K variants are always in DUAL BANK mode
+ * 256K and 128K variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U57x/U58x have 2M max flash size:
+ * 2M variants are always in DUAL BANK mode
+ * 1M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U59x/U5Ax/U5Fx/U5Gx have 4M max flash size:
+ * 4M variants are always in DUAL BANK mode
+ * 2M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * Note: flash banks are always contiguous
*/
+
page_size_kb = 8;
num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages;
@@ -2572,7 +2693,7 @@ static const struct command_registration stm32l4_exec_command_handlers[] = {
.name = "option_write",
.handler = stm32l4_handle_option_write_command,
.mode = COMMAND_EXEC,
- .usage = "bank_id reg_offset value mask",
+ .usage = "bank_id reg_offset value [mask]",
.help = "Write device option bit fields with provided value.",
},
{
diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h
index 3dc0909..3199d4f 100644
--- a/src/flash/nor/stm32l4x.h
+++ b/src/flash/nor/stm32l4x.h
@@ -89,7 +89,9 @@
#define DEVID_STM32L43_L44XX 0x435
#define DEVID_STM32C01XX 0x443
#define DEVID_STM32C03XX 0x453
+#define DEVID_STM32U53_U54XX 0x455
#define DEVID_STM32G05_G06XX 0x456
+#define DEVID_STM32U031XX 0x459
#define DEVID_STM32G07_G08XX 0x460
#define DEVID_STM32L49_L4AXX 0x461
#define DEVID_STM32L45_L46XX 0x462
@@ -101,9 +103,13 @@
#define DEVID_STM32L4R_L4SXX 0x470
#define DEVID_STM32L4P_L4QXX 0x471
#define DEVID_STM32L55_L56XX 0x472
+#define DEVID_STM32U5F_U5GXX 0x476
#define DEVID_STM32G49_G4AXX 0x479
+#define DEVID_STM32U59_U5AXX 0x481
#define DEVID_STM32U57_U58XX 0x482
+#define DEVID_STM32U073_U083XX 0x489
#define DEVID_STM32WBA5X 0x492
+#define DEVID_STM32C071XX 0x493
#define DEVID_STM32WB1XX 0x494
#define DEVID_STM32WB5XX 0x495
#define DEVID_STM32WB3XX 0x496
diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c
index a1e1d34..df58f6c 100644
--- a/src/flash/nor/stmqspi.c
+++ b/src/flash/nor/stmqspi.c
@@ -1807,7 +1807,7 @@ err:
/* Read SFDP parameter block */
static int read_sfdp_block(struct flash_bank *bank, uint32_t addr,
- uint32_t words, uint32_t *buffer)
+ unsigned int words, uint32_t *buffer)
{
struct target *target = bank->target;
struct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;
@@ -1848,7 +1848,7 @@ static int read_sfdp_block(struct flash_bank *bank, uint32_t addr,
}
}
- LOG_DEBUG("%s: addr=0x%08" PRIx32 " words=0x%08" PRIx32 " dummy=%u",
+ LOG_DEBUG("%s: addr=0x%08" PRIx32 " words=0x%08x dummy=%u",
__func__, addr, words, *dummy);
/* Abort any previous operation */
diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c
index c39eb3a..eff7df5 100644
--- a/src/flash/nor/str9xpec.c
+++ b/src/flash/nor/str9xpec.c
@@ -68,7 +68,7 @@ static int str9xpec_erase_area(struct flash_bank *bank, unsigned int first,
static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
static int str9xpec_write_options(struct flash_bank *bank);
-static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
+static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, enum tap_state end_state)
{
if (!tap)
return ERROR_TARGET_INVALID;
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 15edd1a..a19b1a6 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -36,7 +36,7 @@ COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index,
if (*bank)
return ERROR_OK;
- unsigned bank_num;
+ unsigned int bank_num;
COMMAND_PARSE_NUMBER(uint, name, bank_num);
if (do_probe) {
@@ -48,7 +48,7 @@ COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index,
}
}
-COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
+COMMAND_HELPER(flash_command_get_bank, unsigned int name_index,
struct flash_bank **bank)
{
return CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional,
@@ -518,7 +518,7 @@ COMMAND_HANDLER(handle_flash_fill_command)
uint64_t pattern;
uint32_t count;
struct target *target = get_current_target(CMD_CTX);
- unsigned i;
+ unsigned int i;
uint32_t wordsize;
int retval;
@@ -1317,7 +1317,7 @@ COMMAND_HANDLER(handle_flash_banks_command)
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned n = 0;
+ unsigned int n = 0;
for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {
command_print(CMD, "#%d : %s (%s) at " TARGET_ADDR_FMT ", size 0x%8.8" PRIx32 ", "
"buswidth %u, chipwidth %u", p->bank_number,
diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c
index e01d2df..00ee77b 100644
--- a/src/flash/nor/tms470.c
+++ b/src/flash/nor/tms470.c
@@ -16,7 +16,7 @@
* ---------------------------------------------------------------------- */
struct tms470_flash_bank {
- unsigned ordinal;
+ unsigned int ordinal;
/* device identification register */
uint32_t device_ident_reg;
@@ -239,8 +239,8 @@ static int tms470_read_part_info(struct flash_bank *bank)
break;
default:
- LOG_WARNING("Could not identify part 0x%02x as a member of the TMS470 family.",
- (unsigned)part_number);
+ LOG_WARNING("Could not identify part 0x%02" PRIx32 " as a member of the TMS470 family.",
+ part_number);
return ERROR_FLASH_OPERATION_FAILED;
}
@@ -391,7 +391,7 @@ static int tms470_try_flash_keys(struct target *target, const uint32_t *key_set)
/* only perform the key match when 3VSTAT is clear */
target_read_u32(target, 0xFFE8BC0C, &fmmstat);
if (!(fmmstat & 0x08)) {
- unsigned i;
+ unsigned int i;
uint32_t fmbptr, fmbac2, orig_fmregopt;
target_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07);
@@ -455,7 +455,7 @@ static int tms470_unlock_flash(struct flash_bank *bank)
{
struct target *target = bank->target;
const uint32_t *p_key_sets[5];
- unsigned i, key_set_count;
+ unsigned int i, key_set_count;
if (keys_set) {
key_set_count = 5;
diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c
index 1d67b09..4011fa4 100644
--- a/src/flash/nor/xcf.c
+++ b/src/flash/nor/xcf.c
@@ -143,28 +143,27 @@ static int isc_enter(struct flash_bank *bank)
struct xcf_status status = read_status(bank);
- if (true == status.isc_mode)
+ if (status.isc_mode)
return ERROR_OK;
- else {
- struct scan_field scan;
- scan.check_mask = NULL;
- scan.check_value = NULL;
- scan.num_bits = 16;
- scan.out_value = cmd_isc_enable;
- scan.in_value = NULL;
+ struct scan_field scan;
- jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
- jtag_execute_queue();
+ scan.check_mask = NULL;
+ scan.check_value = NULL;
+ scan.num_bits = 16;
+ scan.out_value = cmd_isc_enable;
+ scan.in_value = NULL;
- status = read_status(bank);
- if (!status.isc_mode) {
- LOG_ERROR("*** XCF: FAILED to enter ISC mode");
- return ERROR_FLASH_OPERATION_FAILED;
- }
+ jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
+ jtag_execute_queue();
- return ERROR_OK;
+ status = read_status(bank);
+ if (!status.isc_mode) {
+ LOG_ERROR("*** XCF: FAILED to enter ISC mode");
+ return ERROR_FLASH_OPERATION_FAILED;
}
+
+ return ERROR_OK;
}
static int isc_leave(struct flash_bank *bank)
@@ -174,27 +173,26 @@ static int isc_leave(struct flash_bank *bank)
if (!status.isc_mode)
return ERROR_OK;
- else {
- struct scan_field scan;
-
- scan.check_mask = NULL;
- scan.check_value = NULL;
- scan.num_bits = 16;
- scan.out_value = cmd_isc_disable;
- scan.in_value = NULL;
-
- jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
- jtag_execute_queue();
- alive_sleep(1); /* device needs 50 uS to leave ISC mode */
-
- status = read_status(bank);
- if (status.isc_mode) {
- LOG_ERROR("*** XCF: FAILED to leave ISC mode");
- return ERROR_FLASH_OPERATION_FAILED;
- }
- return ERROR_OK;
+ struct scan_field scan;
+
+ scan.check_mask = NULL;
+ scan.check_value = NULL;
+ scan.num_bits = 16;
+ scan.out_value = cmd_isc_disable;
+ scan.in_value = NULL;
+
+ jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
+ jtag_execute_queue();
+ alive_sleep(1); /* device needs 50 uS to leave ISC mode */
+
+ status = read_status(bank);
+ if (status.isc_mode) {
+ LOG_ERROR("*** XCF: FAILED to leave ISC mode");
+ return ERROR_FLASH_OPERATION_FAILED;
}
+
+ return ERROR_OK;
}
static int sector_state(uint8_t wrpt, int sector)
diff --git a/src/flash/nor/xmc1xxx.c b/src/flash/nor/xmc1xxx.c
index 6e30fc1..4aa97a9 100644
--- a/src/flash/nor/xmc1xxx.c
+++ b/src/flash/nor/xmc1xxx.c
@@ -84,7 +84,7 @@ static int xmc1xxx_erase(struct flash_bank *bank, unsigned int first,
struct working_area *workarea;
struct reg_param reg_params[3];
struct armv7m_algorithm armv7m_algo;
- unsigned i;
+ unsigned int i;
int retval;
const uint8_t erase_code[] = {
#include "../../../contrib/loaders/flash/xmc1xxx/erase.inc"
@@ -159,7 +159,7 @@ static int xmc1xxx_erase_check(struct flash_bank *bank)
struct reg_param reg_params[3];
struct armv7m_algorithm armv7m_algo;
uint16_t val;
- unsigned i;
+ unsigned int i;
int retval;
const uint8_t erase_check_code[] = {
#include "../../../contrib/loaders/flash/xmc1xxx/erase_check.inc"
@@ -245,7 +245,7 @@ static int xmc1xxx_write(struct flash_bank *bank, const uint8_t *buffer,
struct reg_param reg_params[4];
struct armv7m_algorithm armv7m_algo;
uint32_t block_count = DIV_ROUND_UP(byte_count, NVM_BLOCK_SIZE);
- unsigned i;
+ unsigned int i;
int retval;
const uint8_t write_code[] = {
#include "../../../contrib/loaders/flash/xmc1xxx/write.inc"
diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl
index 654f201..0dd84ef 100644
--- a/src/flash/startup.tcl
+++ b/src/flash/startup.tcl
@@ -5,7 +5,7 @@
#
# program utility proc
# usage: program filename
-# optional args: verify, reset, exit and address
+# optional args: preverify, verify, reset, exit and address
#
lappend _telnet_autocomplete_skip program_error
@@ -101,8 +101,8 @@ proc program {filename args} {
return
}
-add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional"
-add_usage_text program "<filename> \[address\] \[pre-verify\] \[verify\] \[reset\] \[exit\]"
+add_help_text program "write an image to flash, address is only required for binary images. preverify, verify, reset, exit are optional"
+add_usage_text program "<filename> \[address\] \[preverify\] \[verify\] \[reset\] \[exit\]"
# stm32[f0x|f3x] uses the same flash driver as the stm32f1x
proc stm32f0x args { eval stm32f1x $args }