17 #define FLASH_ERASE_TIMEOUT 10000
18 #define FLASH_WRITE_TIMEOUT 5
19 #define MASS_ERASE_TIMEOUT 30000
22 #include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
26 #include "../../../contrib/loaders/flash/stm32/stm32h7rx.inc"
78 #define FLASH_LOCK BIT(0)
79 #define FLASH_PG BIT(1)
80 #define FLASH_SER BIT(2)
81 #define FLASH_BER BIT(3)
82 #define FLASH_PSIZE_8 (0 << 4)
83 #define FLASH_PSIZE_16 (1 << 4)
84 #define FLASH_PSIZE_32 (2 << 4)
85 #define FLASH_PSIZE_64 (3 << 4)
86 #define FLASH_FW BIT(6)
87 #define FLASH_START BIT(7)
90 #define FLASH_CRCRDERRF BIT(28)
91 #define FLASH_CRCENDF BIT(27)
92 #define FLASH_DBECCERRF BIT(26)
93 #define FLASH_SNECCERRF BIT(25)
94 #define FLASH_RDSERRF BIT(24)
95 #define FLASH_INCERRF BIT(21)
96 #define FLASH_OBLERRF BIT(20)
97 #define FLASH_STRBERRF BIT(19)
98 #define FLASH_PGSERRF BIT(18)
99 #define FLASH_WRPERRF BIT(17)
100 #define FLASH_EOPF BIT(16)
103 #define FLASH_BSY BIT(0)
104 #define FLASH_QW BIT(2)
105 #define FLASH_WRPERR BIT(17)
106 #define FLASH_PGSERR BIT(18)
107 #define FLASH_STRBERR BIT(19)
108 #define FLASH_INCERR BIT(21)
109 #define FLASH_OPERR BIT(22)
110 #define FLASH_RDPERR BIT(23)
111 #define FLASH_RDSERR BIT(24)
112 #define FLASH_SNECCERR BIT(25)
113 #define FLASH_DBECCERR BIT(26)
115 #define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | FLASH_INCERR | FLASH_OPERR | \
116 FLASH_RDPERR | FLASH_RDSERR | FLASH_SNECCERR | FLASH_DBECCERR)
118 #define FLASH_ERROR_H7RS (FLASH_CRCRDERRF | FLASH_CRCENDF | FLASH_DBECCERRF | FLASH_SNECCERRF | FLASH_RDSERRF | \
119 FLASH_INCERRF | FLASH_OBLERRF | FLASH_STRBERRF | FLASH_PGSERRF | FLASH_WRPERRF | FLASH_EOPF)
122 #define OPT_LOCK BIT(0)
123 #define OPT_START BIT(1)
126 #define OPT_BSY BIT(0)
127 #define OPT_RDP_POS 8
128 #define OPT_RDP_MASK (0xff << OPT_RDP_POS)
129 #define OPT_OPTCHANGEERR BIT(30)
132 #define OPT_CLR_OPTCHANGEERR BIT(30)
135 #define KEY1 0x45670123
136 #define KEY2 0xCDEF89AB
139 #define OPTKEY1 0x08192A3B
140 #define OPTKEY2 0x4C5D6E7F
142 #define DBGMCU_IDCODE_REGISTER 0x5C001000
143 #define FLASH_BANK0_ADDRESS 0x08000000
144 #define FLASH_BANK1_ADDRESS 0x08100000
145 #define FLASH_REG_BASE_B0 0x52002000
146 #define FLASH_REG_BASE_B1 0x52002100
149 #define DEVID_STM32H74_H75XX 0x450
150 #define DEVID_STM32H7A_H7BXX 0x480
151 #define DEVID_STM32H72_H73XX 0x483
152 #define DEVID_STM32H7R_H7SXX 0x485
199 { 0x1000,
"A" }, { 0x1001,
"Z" }, { 0x1003,
"Y" }, { 0x2001,
"X" }, { 0x2003,
"V" },
207 { 0x1000,
"A" }, { 0x1001,
"Z" },
211 { 0x1000,
"A" }, { 0x2000,
"B" },
216 return cmd | (snb << 8);
227 return cmd | (tmp >> 2) | (snb << 6);
238 .device_str =
"STM32H74x/75x",
241 .max_flash_size_kb = 2048,
242 .max_bank_size_kb = 1024,
243 .has_dual_bank =
true,
244 .fsize_addr = 0x1FF1E880,
257 .device_str =
"STM32H7Ax/7Bx",
260 .max_flash_size_kb = 2048,
261 .max_bank_size_kb = 1024,
262 .has_dual_bank =
true,
263 .fsize_addr = 0x08FFF80C,
265 .wps_mask = 0xFFFFFFFF,
276 .device_str =
"STM32H72x/73x",
279 .max_flash_size_kb = 1024,
280 .max_bank_size_kb = 1024,
281 .has_dual_bank =
false,
282 .fsize_addr = 0x1FF1E880,
295 .device_str =
"STM32H7Rx/7Sx",
298 .max_flash_size_kb = 64,
299 .max_bank_size_kb = 64,
300 .has_dual_bank =
false,
301 .fsize_addr = 0x08FFF80C,
322 bank->driver_priv = stm32h7_info;
324 stm32h7_info->
probed =
false;
342 LOG_ERROR(
"error while reading from address 0x%" PRIx32, reg_addr);
360 LOG_ERROR(
"error while writing to address 0x%" PRIx32, reg_addr);
398 LOG_ERROR(
"wait_flash_op_queue, time out expired, status: 0x%" PRIx32,
status);
405 LOG_ERROR(
"wait_flash_op_queue, write protection error");
447 LOG_ERROR(
"flash not unlocked STM32_FLASH_CRx: 0x%" PRIx32,
ctrl);
478 LOG_ERROR(
"options not unlocked STM32_FLASH_OPTCR: 0x%" PRIx32,
ctrl);
502 goto flash_options_lock;
507 goto flash_options_lock;
512 goto flash_options_lock;
517 goto flash_options_lock;
525 LOG_ERROR(
"stm32h7_options_program: failed to read FLASH_OPTSR_CUR");
526 goto flash_options_lock;
532 LOG_ERROR(
"waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32,
status);
534 goto flash_options_lock;
541 LOG_ERROR(
"error changing option bytes (OPTCHANGEERR=1)");
548 LOG_ERROR(
"error during the lock of flash options");
550 return (retval ==
ERROR_OK) ? retval2 : retval;
561 data = (data & ~
mask) | (value &
mask);
573 LOG_DEBUG(
"unable to read WPSN_CUR register");
577 for (
unsigned int i = 0; i <
bank->num_prot_blocks; i++)
578 bank->prot_blocks[i].is_protected =
protection & (1 << i) ? 0 : 1;
589 assert(first < bank->num_sectors);
590 assert(last < bank->num_sectors);
609 for (
unsigned int i = first; i <= last; i++) {
626 LOG_ERROR(
"erase time-out or operation error sector %u", i);
634 LOG_ERROR(
"error during the lock of flash");
636 return (retval ==
ERROR_OK) ? retval2 : retval;
654 LOG_DEBUG(
"unable to read WPSN_CUR register");
658 for (
unsigned int i = first; i <= last; i++) {
694 LOG_WARNING(
"no working area available, can't do block memory writes");
711 if (data_size <= 256) {
716 LOG_WARNING(
"no large enough working area available, can't do block memory writes");
751 LOG_ERROR(
"error executing stm32h7 flash write algorithm");
753 uint32_t flash_sr =
buf_get_u32(reg_params[0].value, 0, 32);
756 LOG_ERROR(
"flash memory write protected");
759 LOG_ERROR(
"flash write failed, status = 0x%08" PRIx32, flash_sr);
804 if (blocks_remaining) {
810 LOG_WARNING(
"couldn't use block writes, falling back to single memory accesses");
815 blocks_remaining = 0;
830 while (blocks_remaining > 0) {
852 LOG_ERROR(
"error during the lock of flash");
854 return (retval ==
ERROR_OK) ? retval2 : retval;
870 uint16_t flash_size_in_kb;
873 stm32h7_info->
probed =
false;
887 device_id = stm32h7_info->
idcode & 0xfff;
899 LOG_WARNING(
"Cannot identify target as a STM32H7xx family.");
911 LOG_WARNING(
"Flash register base not defined for bank %u",
bank->bank_number);
928 LOG_INFO(
"assuming %" PRIu16
"k flash", flash_size_in_kb);
930 LOG_INFO(
"flash size probed value %" PRIu16
"k", flash_size_in_kb);
946 if (flash_size_in_kb == 128)
947 has_dual_bank =
false;
950 flash_size_in_kb /= 2;
961 LOG_INFO(
"STM32H7 flash has dual banks");
962 if (
bank->base != bank1_base &&
bank->base != bank2_base) {
963 LOG_ERROR(
"STM32H7 flash bank base address config is incorrect. "
965 bank->base, bank1_base, bank2_base);
969 LOG_INFO(
"STM32H7 flash has a single bank");
970 if (
bank->base == bank2_base) {
971 LOG_ERROR(
"this device has a single bank only");
973 }
else if (
bank->base != bank1_base) {
974 LOG_ERROR(
"STM32H7 flash bank base address config is incorrect. "
976 bank->base, bank1_base);
982 bank->bank_number, flash_size_in_kb,
bank->base);
987 LOG_INFO(
"ignoring flash probed value, using configured bank size");
989 }
else if (flash_size_in_kb == 0xffff) {
995 assert(flash_size_in_kb != 0xffff);
996 bank->size = flash_size_in_kb * 1024;
1002 assert(
bank->num_sectors > 0);
1004 free(
bank->sectors);
1009 if (!
bank->sectors) {
1010 LOG_ERROR(
"failed to allocate bank sectors");
1016 assert(
bank->num_sectors % wpsn == 0);
1018 bank->num_prot_blocks =
bank->num_sectors / wpsn;
1019 assert(
bank->num_prot_blocks > 0);
1021 free(
bank->prot_blocks);
1024 bank->num_prot_blocks);
1026 if (!
bank->prot_blocks) {
1027 LOG_ERROR(
"failed to allocate bank prot_block");
1031 stm32h7_info->
probed =
true;
1039 if (stm32h7_info->
probed)
1051 if (!stm32h7_info->
probed) {
1060 const char *rev_str =
NULL;
1061 uint16_t rev_id = stm32h7_info->
idcode >> 16;
1063 for (
unsigned int i = 0; i <
info->num_revs; i++)
1064 if (rev_id ==
info->revs[i].rev)
1065 rev_str =
info->revs[i].str;
1072 "%s - Rev: unknown (0x%04" PRIx16
")",
1085 uint32_t optsr, cur_rdp;
1096 LOG_DEBUG(
"unable to read FLASH_OPTSR_PRG register");
1102 if (new_rdp == cur_rdp) {
1103 LOG_INFO(
"the requested RDP value is already programmed");
1115 LOG_WARNING(
"locking the entire flash device, irreversible");
1168 int retval, retval2;
1199 LOG_ERROR(
"error during the lock of flash");
1201 return (retval ==
ERROR_OK) ? retval2 : retval;
1233 uint32_t reg_offset, value;
1256 uint32_t reg_offset, value,
mask = 0xffffffff;
1269 .handler = stm32h7_handle_lock_command,
1272 .help =
"Lock entire flash device.",
1276 .handler = stm32h7_handle_unlock_command,
1279 .help =
"Unlock entire protected flash device.",
1282 .name =
"mass_erase",
1283 .handler = stm32h7_handle_mass_erase_command,
1286 .help =
"Erase entire flash device.",
1289 .name =
"option_read",
1290 .handler = stm32h7_handle_option_read_command,
1292 .usage =
"bank_id reg_offset",
1293 .help =
"Read and display device option bytes.",
1296 .name =
"option_write",
1297 .handler = stm32h7_handle_option_write_command,
1299 .usage =
"bank_id reg_offset value [mask]",
1300 .help =
"Write device option bit fields with provided value.",
1309 .help =
"stm32h7x flash command group",
1319 .flash_bank_command = stm32h7_flash_bank_command,
void init_reg_param(struct reg_param *param, const char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
#define ARMV7M_COMMON_MAGIC
Support functions to access arbitrary bits in a byte array.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
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 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_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static enum cortex_m_impl_part cortex_m_get_impl_part(struct target *target)
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t buffer_size
Size of dw_spi_program::buffer.
uint32_t address
Starting address. Sector aligned.
#define ERROR_FLASH_OPERATION_FAILED
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.
void alive_sleep(uint64_t ms)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
struct rtt_control ctrl
Control block.
#define MASS_ERASE_TIMEOUT
static int stm32h7_protect_check(struct flash_bank *bank)
static const struct stm32h7_part_info stm32h7_parts[]
#define FLASH_ERASE_TIMEOUT
#define DEVID_STM32H74_H75XX
#define OPT_CLR_OPTCHANGEERR
static const struct stm32h7_rev stm32h74_h75xx_revs[]
#define DEVID_STM32H72_H73XX
#define DBGMCU_IDCODE_REGISTER
static const struct stm32h7_rev stm32h72_h73xx_revs[]
static int stm32h7_wait_flash_op_queue(struct flash_bank *bank, int timeout)
static int stm32h7_probe(struct flash_bank *bank)
#define FLASH_BANK0_ADDRESS
static const struct command_registration stm32h7_command_handlers[]
@ STM32_FLASH_OPTCR_INDEX
@ STM32_FLASH_OPTSR_CUR_INDEX
@ STM32_FLASH_OPTSR_PRG_INDEX
@ STM32_FLASH_OPTCCR_INDEX
@ STM32_FLASH_WPSN_PRG_INDEX
@ STM32_FLASH_OPTKEYR_INDEX
@ STM32_FLASH_OPTSR_INDEX
@ STM32_FLASH_ICR_CCR_INDEX
@ STM32_FLASH_WPSN_CUR_INDEX
@ STM32_FLASH_REG_INDEX_NUM
static int stm32h7_get_info(struct flash_bank *bank, struct command_invocation *cmd)
static int stm32h7_modify_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask)
static int stm32h7_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t *status)
static int stm32h7_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
#define FLASH_REG_BASE_B0
static const uint8_t stm32h7_flash_write_code[]
static uint32_t stm32h7a_h7b_h7r_h7sxx_compute_flash_cr(uint32_t cmd, int snb)
static int stm32h7_lock_option_reg(struct flash_bank *bank)
static int stm32h7_unlock_option_reg(struct flash_bank *bank)
static int stm32h7_read_flash_reg_by_index(struct flash_bank *bank, enum stm32h7_flash_reg_index reg_index, uint32_t *value)
static int stm32h7_set_rdp(struct flash_bank *bank, enum stm32h7_opt_rdp new_rdp)
static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM]
#define DEVID_STM32H7R_H7SXX
static int stm32h7_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
static const uint32_t stm32h7rs_flash_regs[STM32_FLASH_REG_INDEX_NUM]
static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
FLASH_BANK_COMMAND_HANDLER(stm32h7_flash_bank_command)
#define DEVID_STM32H7A_H7BXX
static const struct stm32h7_rev stm32h7a_h7bxx_revs[]
static const uint8_t stm32h7rs_flash_write_code[]
static int stm32h7_write_flash_reg_by_index(struct flash_bank *bank, enum stm32h7_flash_reg_index reg_index, uint32_t value)
static int stm32h7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
static int stm32h7_read_id_code(struct flash_bank *bank, uint32_t *id)
static const struct command_registration stm32h7_exec_command_handlers[]
static int stm32h7_unlock_reg(struct flash_bank *bank)
static int stm32h7_mass_erase(struct flash_bank *bank)
static int stm32h7_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
static const struct stm32h7_rev stm32h7r_h7sxx_revs[]
const struct flash_driver stm32h7x_flash
COMMAND_HANDLER(stm32h7_handle_lock_command)
static uint32_t stm32h7_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)
static int stm32h7_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
static int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t *status)
static int stm32h7_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
#define FLASH_BANK1_ADDRESS
#define FLASH_WRITE_TIMEOUT
#define FLASH_REG_BASE_B1
static int stm32h7_lock_reg(struct flash_bank *bank)
static int stm32h7_auto_probe(struct flash_bank *bank)
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...
const struct stm32h7_part_info * part_info
const uint32_t * flash_regs
const uint8_t * write_code
int(* get_flash_error_status)(struct flash_bank *bank, uint32_t *status)
const struct stm32h7_rev * revs
unsigned int page_size_kb
uint32_t(* compute_flash_cr)(uint32_t cmd, int snb)
uint16_t max_bank_size_kb
uint16_t max_flash_size_kb
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
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_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Streams data to a circular buffer on target intended for consumption by code running asynchronously o...
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
#define ERROR_TARGET_NOT_HALTED
static bool target_was_examined(const struct target *target)
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TARGET_NOT_EXAMINED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ERROR_TARGET_FAILURE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
static struct ublast_lowlevel_priv info