27 #define MFLASH_SECTOR_SIZE (256u * 1024u)
28 #define WFLASH_SECTOR_SIZE (32u * 1024u)
30 #define MEM_BASE_MFLASH 0x10000000u
31 #define MEM_BASE_WFLASH 0x14000000u
32 #define MEM_WFLASH_SIZE 32768u
33 #define MEM_BASE_SFLASH 0x16000000u
34 #define RAM_STACK_WA_SIZE 2048u
35 #define PSOC6_SPCIF_GEOMETRY 0x4025F00Cu
37 #define PROTECTION_UNKNOWN 0x00u
38 #define PROTECTION_VIRGIN 0x01u
39 #define PROTECTION_NORMAL 0x02u
40 #define PROTECTION_SECURE 0x03u
41 #define PROTECTION_DEAD 0x04u
43 #define MEM_BASE_IPC 0x40230000u
44 #define IPC_STRUCT_SIZE 0x20u
45 #define MEM_IPC(n) (MEM_BASE_IPC + (n) * IPC_STRUCT_SIZE)
46 #define MEM_IPC_ACQUIRE(n) (MEM_IPC(n) + 0x00u)
47 #define MEM_IPC_NOTIFY(n) (MEM_IPC(n) + 0x08u)
48 #define MEM_IPC_DATA(n) (MEM_IPC(n) + 0x0Cu)
49 #define MEM_IPC_LOCK_STATUS(n) (MEM_IPC(n) + 0x10u)
51 #define MEM_BASE_IPC_INTR 0x40231000u
52 #define IPC_INTR_STRUCT_SIZE 0x20u
53 #define MEM_IPC_INTR(n) (MEM_BASE_IPC_INTR + (n) * IPC_INTR_STRUCT_SIZE)
54 #define MEM_IPC_INTR_MASK(n) (MEM_IPC_INTR(n) + 0x08u)
55 #define IPC_ACQUIRE_SUCCESS_MSK 0x80000000u
56 #define IPC_LOCK_ACQUIRED_MSK 0x80000000u
59 #define IPC_INTR_ID 0u
60 #define IPC_TIMEOUT_MS 1000
62 #define SROMAPI_SIID_REQ 0x00000001u
63 #define SROMAPI_SIID_REQ_FAMILY_REVISION (SROMAPI_SIID_REQ | 0x000u)
64 #define SROMAPI_SIID_REQ_SIID_PROTECTION (SROMAPI_SIID_REQ | 0x100u)
65 #define SROMAPI_WRITEROW_REQ 0x05000100u
66 #define SROMAPI_PROGRAMROW_REQ 0x06000100u
67 #define SROMAPI_ERASESECTOR_REQ 0x14000100u
68 #define SROMAPI_ERASEALL_REQ 0x0A000100u
69 #define SROMAPI_ERASEROW_REQ 0x1C000100u
71 #define SROMAPI_STATUS_MSK 0xF0000000u
72 #define SROMAPI_STAT_SUCCESS 0xA0000000u
73 #define SROMAPI_DATA_LOCATION_MSK 0x00000001u
74 #define SROMAPI_CALL_TIMEOUT_MS 1500
101 #define SFLASH_NUM_REGIONS ARRAY_SIZE(safe_sflash_regions)
159 goto destroy_rp_free_wa;
164 goto destroy_rp_free_wa;
238 LOG_ERROR(
"Unable to read IPC Lock Status register");
244 if (lock_expected == is_locked)
249 LOG_WARNING(
"SROM API calls via CM4 target are supported on single-core PSoC6 devices only. "
250 "Please perform all Flash-related operations via CM0+ target on dual-core devices.");
253 LOG_ERROR(
"Timeout polling IPC Lock Status");
270 bool is_acquired =
false;
281 LOG_ERROR(
"Unable to write to IPC Acquire register");
288 LOG_ERROR(
"Unable to read IPC Acquire register");
301 LOG_ERROR(
"Timeout acquiring IPC structure");
316 uint32_t req_and_params,
357 LOG_ERROR(
"Error reading SROM API Status location");
363 LOG_ERROR(
"SROM API execution failed. Status: 0x%08" PRIX32, *data_out);
380 uint32_t family_rev, siid_prot;
396 *si_id = (siid_prot & 0x0000FFFF) << 16;
397 *si_id |= (family_rev & 0x00FF0000) >> 8;
398 *si_id |= (family_rev & 0x000000FF) >> 0;
400 *protection = (siid_prot & 0x000F0000) >> 0x10;
435 for (
unsigned int i = 0; i <
bank->num_sectors; i++)
436 bank->sectors[i].is_protected = is_protected;
453 LOG_WARNING(
"Life Cycle transition for PSoC6 is not supported");
497 "PSoC6 Silicon ID: 0x%08" PRIX32
"\n"
499 "Main Flash size: %" PRIu32
" kB\n"
500 "Work Flash size: 32 kB\n",
561 uint32_t row_sz_lg2 = (geom & 0xF0) >> 4;
562 uint32_t
row_sz = (0x01 << row_sz_lg2);
563 uint32_t row_cnt = 1 + ((geom & 0x00FFFF00) >> 8);
564 uint32_t bank_cnt = 1 + ((geom & 0xFF000000) >> 24);
567 uint32_t flash_sz_bytes = bank_cnt * row_cnt *
row_sz;
572 size_t bank_size = 0;
575 bank_size = flash_sz_bytes;
587 if (bank_size == 0) {
588 LOG_ERROR(
"Invalid Flash Bank base address in config file");
592 unsigned int num_sectors = bank_size /
row_sz;
593 bank->size = bank_size;
595 bank->erased_value = 0;
596 bank->default_padded_value = 0;
598 bank->num_sectors = num_sectors;
600 for (
unsigned int i = 0; i < num_sectors; i++) {
603 bank->sectors[i].is_erased = -1;
604 bank->sectors[i].is_protected = -1;
710 LOG_INFO(
"Erase operation on Supervisory Flash is not required, skipping");
725 while (last >= first) {
727 if ((first % rows_in_sector) == 0 &&
728 (last - first + 1) >= rows_in_sector) {
733 first += rows_in_sector;
826 uint8_t page_buf[psoc6_info->
row_sz];
834 uint32_t aligned_addr =
bank->base +
offset - row_offset;
837 memset(page_buf, 0,
sizeof(page_buf));
838 memcpy(&page_buf[row_offset],
buffer, row_bytes);
842 LOG_ERROR(
"Failed to program Flash at address 0x%08" PRIX32, aligned_addr);
905 const uint32_t vt_offset_reg = is_cm0 ? 0x402102B0 : 0x402102C0;
911 vt_base &= 0xFFFFFF00;
912 if ((vt_base == 0) || (vt_base == 0xFFFFFF00))
921 if ((reset_addr == 0) || (reset_addr == 0xFFFFFF00))
937 LOG_INFO(
"psoc6.cm0: bkpt @0x%08" PRIX32
", issuing SYSRESETREQ", reset_addr);
941 LOG_INFO(
"psoc6.cm4: bkpt @0x%08" PRIX32
", issuing VECTRESET", reset_addr);
987 bank->driver_priv = psoc6_info;
994 .
name =
"mass_erase",
995 .handler = psoc6_handle_mass_erase_command,
998 .help =
"Erases entire Main Flash",
1001 .name =
"reset_halt",
1002 .handler = psoc6_handle_reset_halt,
1005 .help =
"Tries to simulate broken Vector Catch",
1014 .help =
"PSoC 6 flash command group",
1024 .flash_bank_command = psoc6_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)
int dap_dp_init(struct adiv5_dap *dap)
Initialize a DAP.
int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Synchronous write of a word to memory or a system register.
This defines formats and data structures used to talk to ADIv5 entities.
static struct armv7m_common * target_to_armv7m(struct target *target)
#define ARMV7M_COMMON_MAGIC
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void breakpoint_remove(struct target *target, target_addr_t address)
int breakpoint_add(struct target *target, target_addr_t address, uint32_t length, enum breakpoint_type type)
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#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 CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define AIRCR_SYSRESETREQ
static const int sector_size
#define ERROR_FLASH_BANK_INVALID
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.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
#define SROMAPI_STAT_SUCCESS
FLASH_BANK_COMMAND_HANDLER(psoc6_flash_bank_command)
static const struct row_region safe_sflash_regions[]
#define SROMAPI_PROGRAMROW_REQ
static int psoc6_probe(struct flash_bank *bank)
Probes the device and populates related data structures with target flash geometry data.
static struct armv7m_algorithm g_armv7m_info
static int handle_reset_halt(struct target *target)
Simulates broken Vector Catch Function will try to determine entry point of user application.
#define PROTECTION_SECURE
static bool is_wflash_bank(struct flash_bank *bank)
Checks if given flash bank belongs to Work Flash.
#define SFLASH_NUM_REGIONS
#define PSOC6_SPCIF_GEOMETRY
static int sromalgo_prepare(struct target *target)
Starts pseudo flash algorithm and leaves it running.
static struct working_area * g_stack_area
#define SROMAPI_ERASEROW_REQ
#define SROMAPI_SIID_REQ_SIID_PROTECTION
#define IPC_ACQUIRE_SUCCESS_MSK
#define SROMAPI_WRITEROW_REQ
#define MEM_IPC_LOCK_STATUS(n)
static int psoc6_erase_sector(struct flash_bank *bank, struct working_area *wa, uint32_t addr)
Erases single sector (256k) on target device.
#define MEM_IPC_INTR_MASK(n)
const struct flash_driver psoc6_flash
static void sromalgo_release(struct target *target)
Stops running flash algorithm and releases associated resources.
static int psoc6_auto_probe(struct flash_bank *bank)
Probes target device only if it hasn't been probed yet.
#define SROMAPI_STATUS_MSK
static int call_sromapi(struct target *target, uint32_t req_and_params, uint32_t working_area, uint32_t *data_out)
Invokes SROM API functions which are responsible for Flash operations.
#define PROTECTION_VIRGIN
#define WFLASH_SECTOR_SIZE
static bool timeout_expired(struct timeout *to)
Returns true if given struct timeout structure has expired.
#define IPC_LOCK_ACQUIRED_MSK
#define MEM_IPC_NOTIFY(n)
static int psoc6_program(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Performs Program operation.
#define MEM_IPC_ACQUIRE(n)
static void timeout_init(struct timeout *to, long timeout_ms)
Initializes struct timeout structure with given timeout value.
static int psoc6_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Performs Erase operation.
static int psoc6_erase_row(struct flash_bank *bank, struct working_area *wa, uint32_t addr)
Erases single row (512b) on target device.
COMMAND_HANDLER(psoc6_handle_mass_erase_command)
Performs Mass Erase operation.
static bool is_sflash_bank(struct flash_bank *bank)
Checks if given flash bank belongs to Supervisory Flash.
#define SROMAPI_DATA_LOCATION_MSK
#define MFLASH_SECTOR_SIZE
static int psoc6_protect_check(struct flash_bank *bank)
Translates Protection status to openocd-friendly boolean value.
static int get_silicon_id(struct target *target, uint32_t *si_id, uint8_t *protection)
Retrieves SiliconID and Protection status of the target device.
#define PROTECTION_UNKNOWN
#define PROTECTION_NORMAL
static int psoc6_program_row(struct flash_bank *bank, uint32_t addr, const uint8_t *buffer, bool is_sflash)
Programs single Flash Row.
static int psoc6_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Dummy function, Life Cycle transition is not currently supported.
#define RAM_STACK_WA_SIZE
#define SROMAPI_SIID_REQ_FAMILY_REVISION
#define SROMAPI_ERASESECTOR_REQ
static int psoc6_get_info(struct flash_bank *bank, struct command_invocation *cmd)
psoc6_get_info Displays human-readable information about acquired device
static const char * protection_to_str(uint8_t protection)
Translates Protection status to string.
static bool is_mflash_bank(struct flash_bank *bank)
Checks if given flash bank belongs to Main Flash.
static const struct command_registration psoc6_command_handlers[]
static const struct command_registration psoc6_exec_command_handlers[]
static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_expected)
Waits for expected IPC lock status.
static int ipc_acquire(struct target *target, char ipc_id)
Acquires IPC structure.
struct adiv5_dap * dap
DAP this AP belongs to.
unsigned int common_magic
struct adiv5_ap * debug_ap
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...
Describes the geometry and status of a single flash sector within a flash bank.
bool running_alg
true if the target is currently running a downloaded "algorithm" instead of arbitrary user code.
int target_halt(struct target *target)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t exit_point, int timeout_ms, void *arch_info)
Waits for an algorithm started with target_start_algorithm() to complete.
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)
struct target * get_current_target(struct command_context *cmd_ctx)
int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, void *arch_info)
Executes a target-specific native code algorithm and leaves it running.
int target_wait_state(struct target *target, enum target_state state, int ms)
#define ERROR_TARGET_TIMEOUT
#define ERROR_TARGET_FAILURE