75 #define PSOC4_SFLASH_MACRO0 0x0FFFF000
77 #define PSOC4_CPUSS_SYSREQ_LEGACY 0x40000004
78 #define PSOC4_CPUSS_SYSARG_LEGACY 0x40000008
79 #define PSOC4_SPCIF_GEOMETRY_LEGACY 0x400E0000
81 #define PSOC4_CPUSS_SYSREQ_NEW 0x40100004
82 #define PSOC4_CPUSS_SYSARG_NEW 0x40100008
83 #define PSOC4_SPCIF_GEOMETRY_NEW 0x40110000
85 #define PSOC4_TEST_MODE 0x40030014
87 #define PSOC4_ROMTABLE_PID0 0xF0000FE0
91 #define PSOC4_SFLASH_MACRO_SIZE 0x800
92 #define PSOC4_ROWS_PER_MACRO 512
94 #define PSOC4_SROM_KEY1 0xb6
95 #define PSOC4_SROM_KEY2 0xd3
96 #define PSOC4_SROM_SYSREQ_BIT (1<<31)
97 #define PSOC4_SROM_HMASTER_BIT (1<<30)
98 #define PSOC4_SROM_PRIVILEGED_BIT (1<<28)
99 #define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000
100 #define PSOC4_SROM_STATUS_FAILED 0xf0000000
101 #define PSOC4_SROM_STATUS_MASK 0xf0000000
104 #define PSOC4_SROM_ERR_IMO_NOT_IMPLEM 0xf0000013
106 #define PSOC4_CMD_GET_SILICON_ID 0
107 #define PSOC4_CMD_LOAD_LATCH 4
108 #define PSOC4_CMD_WRITE_ROW 5
109 #define PSOC4_CMD_PROGRAM_ROW 6
110 #define PSOC4_CMD_ERASE_ALL 0xa
111 #define PSOC4_CMD_CHECKSUM 0xb
112 #define PSOC4_CMD_WRITE_PROTECTION 0xd
113 #define PSOC4_CMD_SET_IMO48 0x15
114 #define PSOC4_CMD_WRITE_SFLASH_ROW 0x18
116 #define PSOC4_CHIP_PROT_VIRGIN 0x0
117 #define PSOC4_CHIP_PROT_OPEN 0x1
118 #define PSOC4_CHIP_PROT_PROTECTED 0x2
119 #define PSOC4_CHIP_PROT_KILL 0x4
121 #define PSOC4_ROMTABLE_DESIGNER_CHECK 0xb4
123 #define PSOC4_FAMILY_FLAG_LEGACY 1
133 { 0x9A,
"PSoC4000", .flags = 0 },
134 { 0x9E,
"PSoC/PRoC BLE (119E)", .flags = 0 },
135 { 0xA0,
"PSoC4200L", .flags = 0 },
136 { 0xA1,
"PSoC4100M/4200M", .flags = 0 },
137 { 0xA3,
"PSoC/PRoC BLE (11A3)", .flags = 0 },
138 { 0xA9,
"PSoC4000S", .flags = 0 },
139 { 0xAA,
"PSoC/PRoC BLE (11AA)", .flags = 0 },
140 { 0xAB,
"PSoC4100S", .flags = 0 },
141 { 0xAC,
"PSoC Analog Coprocessor", .flags = 0 },
142 { 0,
"Unknown", .flags = 0 }
163 while (p->
id && p->
id != family_id)
173 return "protection VIRGIN";
175 return "protection open";
179 return "protection KILL";
198 bank->driver_priv = psoc4_info;
199 bank->default_padded_value =
bank->erased_value = 0x00;
216 uint32_t *sysreq_params, uint32_t sysreq_params_size,
217 uint32_t *sysarg_out)
234 static uint8_t psoc4_sysreq_wait_code[] = {
240 const int code_words = (
sizeof(psoc4_sysreq_wait_code) + 3) / 4;
242 const int stack_size = 256;
251 &sysreq_wait_algorithm) !=
ERROR_OK) {
252 LOG_DEBUG(
"no working area for sysreq code");
258 sysreq_wait_algorithm->
address,
259 sizeof(psoc4_sysreq_wait_code),
260 psoc4_sysreq_wait_code);
267 if (sysreq_params_size) {
268 LOG_DEBUG(
"SYSREQ %02" PRIx8
" %04" PRIx16
" %08" PRIx32
" size %" PRIu32,
269 cmd, cmd_param, param1, sysreq_params_size);
273 LOG_WARNING(
"no working area for sysreq parameters");
284 sysreq_params_size, (uint8_t *)sysreq_params);
295 LOG_DEBUG(
"SYSREQ %02" PRIx8
" %04" PRIx16
" %08" PRIx32,
296 cmd, cmd_param, param1);
309 sysreq_wait_algorithm->
address + sysreq_wait_algorithm->
size);
314 LOG_ERROR(
"unable to get armv7m target");
328 sysreq_wait_algorithm->
address, 0, 1000, &armv7m_info);
330 LOG_ERROR(
"sysreq wait code execution failed");
334 uint32_t sysarg_out_tmp;
340 *sysarg_out = sysarg_out_tmp;
343 LOG_ERROR(
"sysreq error 0x%" PRIx32, sysarg_out_tmp);
350 if (sysreq_params_size)
366 uint32_t part0, part1;
373 LOG_ERROR(
"sysreq error 0x%" PRIx32, part0);
387 *silicon_id = ((part0 & 0x0000ffff) << 16)
388 | ((part0 & 0x00ff0000) >> 8)
389 | (part1 & 0x000000ff);
411 for (i = 0; i < 3; i++) {
413 if (tmp & 0xffffff00) {
414 LOG_ERROR(
"Unexpected data in ROMTABLE");
420 uint16_t family = pid[0] | ((pid[1] & 0xf) << 8);
421 uint32_t designer = ((pid[1] & 0xf0) >> 4) | ((pid[2] & 0xf) << 4);
424 LOG_ERROR(
"ROMTABLE designer is not Cypress");
458 uint32_t sysreq_status;
469 LOG_INFO(
"PSOC4_CMD_SET_IMO48 is not implemented on this device.");
471 LOG_ERROR(
"sysreq error 0x%" PRIx32, sysreq_status);
497 bank->sectors[s].is_protected = bf[i/8] & (1 << (i%8)) ? 1 : 0;
514 ¶m,
sizeof(param),
NULL);
523 LOG_INFO(
"Autoerase enabled, erase command ignored");
527 if ((first == 0) && (last == (
bank->num_sectors - 1)))
530 LOG_ERROR(
"Only mass erase available! Consider using 'psoc4 flash_autoerase 0 on'");
549 uint32_t *sysrq_buffer =
NULL;
550 const int param_sz = 8;
553 unsigned int num_bits =
bank->num_sectors;
558 int prot_sz = num_bits / 8;
560 sysrq_buffer = malloc(param_sz + prot_sz);
566 for (i = first; i <= last && i <
bank->num_sectors; i++)
567 bank->sectors[i].is_protected = set;
569 for (
unsigned int m = 0, sect = 0; m < psoc4_info->
num_macros; m++) {
570 uint8_t *p = (uint8_t *)(sysrq_buffer + 2);
571 memset(p, 0, prot_sz);
572 for (i = 0; i < num_bits && sect <
bank->num_sectors; i++, sect++) {
573 if (
bank->sectors[sect].is_protected)
574 p[i/8] |= 1 << (i%8);
583 sysrq_buffer, param_sz + prot_sz,
590 chip_prot | (m << 8),
NULL, 0,
NULL);
620 LOG_INFO(
"Flash auto-erase enabled, non mass erase commands will be ignored.");
623 LOG_INFO(
"Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
635 uint32_t *sysrq_buffer =
NULL;
636 const int param_sz = 8;
642 sysrq_buffer = malloc(param_sz + psoc4_info->
row_size);
648 uint8_t *row_buffer = (uint8_t *)sysrq_buffer + param_sz;
652 memset(row_buffer,
bank->default_padded_value, row_offset);
655 uint32_t chunk_size = psoc4_info->
row_size - row_offset;
656 if (chunk_size >
count) {
658 memset(row_buffer + chunk_size,
bank->default_padded_value, psoc4_info->
row_size - chunk_size);
660 memcpy(row_buffer + row_offset,
buffer, chunk_size);
661 LOG_DEBUG(
"offset / row: 0x%08" PRIx32
" / %" PRIu32
", size %" PRIu32
"",
662 offset, row_offset, chunk_size);
672 sysrq_buffer, param_sz + psoc4_info->
row_size,
678 uint32_t sysrq_param;
681 &sysrq_param,
sizeof(sysrq_param),
703 for (i = 3; i >= 1; i--) {
704 uint32_t
addr = flash_size >> i;
722 psoc4_info->
probed =
false;
730 if (family->
id == 0) {
731 LOG_ERROR(
"Cannot identify PSoC 4 family.");
749 uint32_t spcif_geometry;
754 uint32_t flash_size_in_kb = spcif_geometry & 0x3fff;
760 uint32_t row_size = (spcif_geometry >> 22) & 3;
761 uint32_t num_macros = (spcif_geometry >> 20) & 3;
764 flash_size_in_kb = flash_size_in_kb * 256 / 1024;
767 flash_size_in_kb = (flash_size_in_kb + 1) * 256 / 1024;
768 row_size = 64 * (row_size + 1);
772 LOG_DEBUG(
"SPCIF geometry: %" PRIu32
" KiB flash, row %" PRIu32
" bytes.",
773 flash_size_in_kb, row_size);
778 LOG_INFO(
"ignoring flash probed value, using configured bank size");
782 char macros_txt[22] =
"";
784 snprintf(macros_txt,
sizeof(macros_txt),
" in %" PRIu32
" macros", num_macros);
786 LOG_INFO(
"flash size = %" PRIu32
" KiB%s", flash_size_in_kb, macros_txt);
789 uint32_t num_rows = flash_size_in_kb * 1024 / row_size;
793 LOG_WARNING(
"Number of macros does not correspond with flash size!");
798 flash_size_in_kb = flash_size_in_kb >> wounding;
799 num_rows = num_rows >> wounding;
800 LOG_INFO(
"WOUNDING detected: accessible flash size %" PRIu32
" kbytes", flash_size_in_kb);
809 bank->base = 0x00000000;
810 bank->size = num_rows * row_size;
811 bank->num_sectors = num_rows;
816 LOG_DEBUG(
"flash bank set %" PRIu32
" rows", num_rows);
817 psoc4_info->
probed =
true;
840 uint32_t size_in_kb =
bank->size / 1024;
844 " (halt target to see details)", family->
name, size_in_kb);
858 "/0x%02" PRIx16
", silicon id 0x%08" PRIx32,
859 psoc4_info->
family_id, family_id, silicon_id);
862 family->
name, silicon_id);
893 .
name =
"mass_erase",
894 .handler = psoc4_handle_mass_erase_command,
897 .help =
"Erase entire flash device.",
900 .name =
"flash_autoerase",
901 .handler = psoc4_handle_flash_autoerase_command,
903 .usage =
"bank_id on|off",
904 .help =
"Set autoerase mode for flash bank.",
913 .help =
"PSoC 4 flash command group",
923 .flash_bank_command = psoc4_flash_bank_command,
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
static struct armv7m_common * target_to_armv7m(struct target *target)
#define ARMV7M_COMMON_MAGIC
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define COMMAND_PARSE_ON_OFF(in, out)
parses an on/off command argument
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static const struct psoc4_chip_family psoc4_families[]
#define PSOC4_SPCIF_GEOMETRY_LEGACY
#define PSOC4_CMD_WRITE_ROW
#define PSOC4_ROWS_PER_MACRO
#define PSOC4_SROM_ERR_IMO_NOT_IMPLEM
static const struct psoc4_chip_family * psoc4_family_by_id(uint16_t family_id)
#define PSOC4_CMD_SET_IMO48
static int psoc4_probe(struct flash_bank *bank)
static int psoc4_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
static int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd, uint16_t cmd_param, uint32_t *sysreq_params, uint32_t sysreq_params_size, uint32_t *sysarg_out)
#define PSOC4_CHIP_PROT_PROTECTED
static int get_psoc4_info(struct flash_bank *bank, struct command_invocation *cmd)
#define PSOC4_CMD_WRITE_PROTECTION
static int psoc4_get_silicon_id(struct flash_bank *bank, uint32_t *silicon_id, uint16_t *family_id, uint8_t *protection)
#define PSOC4_SPCIF_GEOMETRY_NEW
#define PSOC4_SROM_HMASTER_BIT
static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
static int psoc4_mass_erase(struct flash_bank *bank)
static int psoc4_test_flash_wounding(struct target *target, uint32_t flash_size)
static int psoc4_get_family(struct target *target, uint16_t *family_id)
#define PSOC4_CPUSS_SYSREQ_NEW
#define PSOC4_SFLASH_MACRO0
#define PSOC4_CHIP_PROT_OPEN
#define PSOC4_CPUSS_SYSREQ_LEGACY
#define PSOC4_CMD_ERASE_ALL
#define PSOC4_ROMTABLE_PID0
static const struct command_registration psoc4_exec_command_handlers[]
#define PSOC4_FAMILY_FLAG_LEGACY
#define PSOC4_CPUSS_SYSARG_LEGACY
#define PSOC4_CMD_LOAD_LATCH
static int psoc4_protect_check(struct flash_bank *bank)
static const struct command_registration psoc4_command_handlers[]
static int psoc4_flash_prepare(struct flash_bank *bank)
#define PSOC4_SROM_STATUS_SUCCEEDED
FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command)
COMMAND_HANDLER(psoc4_handle_flash_autoerase_command)
#define PSOC4_CPUSS_SYSARG_NEW
#define PSOC4_SFLASH_MACRO_SIZE
#define PSOC4_CHIP_PROT_VIRGIN
static const char * psoc4_decode_chip_protection(uint8_t protection)
const struct flash_driver psoc4_flash
#define PSOC4_ROMTABLE_DESIGNER_CHECK
#define PSOC4_CMD_PROGRAM_ROW
#define PSOC4_CMD_GET_SILICON_ID
#define PSOC4_SROM_SYSREQ_BIT
#define PSOC4_SROM_STATUS_MASK
static int psoc4_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static int psoc4_auto_probe(struct flash_bank *bank)
#define PSOC4_CHIP_PROT_KILL
target_addr_t addr
Start address to search for the control block.
unsigned int common_magic
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Provides details of a flash bank, available either on-chip or through a major interface.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
uint32_t cpuss_sysarg_addr
uint32_t cpuss_sysreq_addr
uint32_t spcif_geometry_addr
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.