4 * Copyright (c) 2016 Andreas Färber
14 #include <helper/binarybuffer.h>
15 #include <target/algorithm.h>
16 #include <target/armv7m.h>
18 #define FLASH_BASE 0x10000000
19 #define PAU_BASE 0x40000000
20 #define SCU_BASE 0x40010000
21 #define NVM_BASE 0x40050000
23 #define FLASH_CS0 (FLASH_BASE + 0xf00)
25 #define PAU_FLSIZE (PAU_BASE + 0x404)
27 #define SCU_IDCHIP (SCU_BASE + 0x004)
29 #define NVMSTATUS (NVM_BASE + 0x00)
30 #define NVMPROG (NVM_BASE + 0x04)
31 #define NVMCONF (NVM_BASE + 0x08)
33 #define NVMSTATUS_BUSY (1 << 0)
34 #define NVMSTATUS_VERR_MASK (0x3 << 2)
36 #define NVMPROG_ACTION_OPTYPE_IDLE_VERIFY (0 << 0)
37 #define NVMPROG_ACTION_OPTYPE_WRITE (1 << 0)
38 #define NVMPROG_ACTION_OPTYPE_PAGE_ERASE (2 << 0)
40 #define NVMPROG_ACTION_ONE_SHOT_ONCE (1 << 4)
41 #define NVMPROG_ACTION_ONE_SHOT_CONTINUOUS (2 << 4)
43 #define NVMPROG_ACTION_VERIFY_EACH (1 << 6)
44 #define NVMPROG_ACTION_VERIFY_NO (2 << 6)
45 #define NVMPROG_ACTION_VERIFY_ARRAY (3 << 6)
47 #define NVMPROG_ACTION_IDLE 0x00
48 #define NVMPROG_ACTION_MASK 0xff
50 #define NVM_WORD_SIZE 4
51 #define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE)
52 #define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE)
54 struct xmc1xxx_flash_bank
{
58 static int xmc1xxx_nvm_set_idle(struct target
*target
)
60 return target_write_u16(target
, NVMPROG
, NVMPROG_ACTION_IDLE
);
63 static int xmc1xxx_nvm_check_idle(struct target
*target
)
68 retval
= target_read_u16(target
, NVMPROG
, &val
);
69 if (retval
!= ERROR_OK
)
71 if ((val
& NVMPROG_ACTION_MASK
) != NVMPROG_ACTION_IDLE
) {
72 LOG_WARNING("NVMPROG.ACTION");
73 retval
= xmc1xxx_nvm_set_idle(target
);
79 static int xmc1xxx_erase(struct flash_bank
*bank
, unsigned int first
,
82 struct target
*target
= bank
->target
;
83 struct working_area
*workarea
;
84 struct reg_param reg_params
[3];
85 struct armv7m_algorithm armv7m_algo
;
88 const uint8_t erase_code
[] = {
89 #include "../../../contrib/loaders/flash/xmc1xxx/erase.inc"
92 LOG_DEBUG("Infineon XMC1000 erase sectors %u to %u", first
, last
);
94 if (bank
->target
->state
!= TARGET_HALTED
) {
95 LOG_WARNING("Cannot communicate... target not halted.");
96 return ERROR_TARGET_NOT_HALTED
;
99 retval
= xmc1xxx_nvm_check_idle(target
);
100 if (retval
!= ERROR_OK
)
103 retval
= target_alloc_working_area(target
, sizeof(erase_code
),
105 if (retval
!= ERROR_OK
) {
106 LOG_ERROR("No working area available.");
107 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
110 retval
= target_write_buffer(target
, workarea
->address
,
111 sizeof(erase_code
), erase_code
);
112 if (retval
!= ERROR_OK
)
115 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
116 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
118 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
119 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
120 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
122 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
123 buf_set_u32(reg_params
[1].value
, 0, 32, bank
->base
+
124 bank
->sectors
[first
].offset
);
125 buf_set_u32(reg_params
[2].value
, 0, 32, bank
->base
+
126 bank
->sectors
[last
].offset
+ bank
->sectors
[last
].size
);
128 retval
= target_run_algorithm(target
,
130 ARRAY_SIZE(reg_params
), reg_params
,
131 workarea
->address
, 0,
133 if (retval
!= ERROR_OK
) {
134 LOG_ERROR("Error executing flash sector erase "
135 "programming algorithm");
136 retval
= xmc1xxx_nvm_set_idle(target
);
137 if (retval
!= ERROR_OK
)
138 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
139 retval
= ERROR_FLASH_OPERATION_FAILED
;
143 for (unsigned int sector
= first
; sector
<= last
; sector
++)
144 bank
->sectors
[sector
].is_erased
= 1;
147 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
148 destroy_reg_param(®_params
[i
]);
151 target_free_working_area(target
, workarea
);
157 static int xmc1xxx_erase_check(struct flash_bank
*bank
)
159 struct target
*target
= bank
->target
;
160 struct working_area
*workarea
;
161 struct reg_param reg_params
[3];
162 struct armv7m_algorithm armv7m_algo
;
166 const uint8_t erase_check_code
[] = {
167 #include "../../../contrib/loaders/flash/xmc1xxx/erase_check.inc"
170 if (bank
->target
->state
!= TARGET_HALTED
) {
171 LOG_WARNING("Cannot communicate... target not halted.");
172 return ERROR_TARGET_NOT_HALTED
;
175 retval
= target_alloc_working_area(target
, sizeof(erase_check_code
),
177 if (retval
!= ERROR_OK
) {
178 LOG_ERROR("No working area available.");
179 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
182 retval
= target_write_buffer(target
, workarea
->address
,
183 sizeof(erase_check_code
), erase_check_code
);
184 if (retval
!= ERROR_OK
)
187 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
188 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
190 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
191 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
192 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
194 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
196 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
197 uint32_t start
= bank
->base
+ bank
->sectors
[sector
].offset
;
198 buf_set_u32(reg_params
[1].value
, 0, 32, start
);
199 buf_set_u32(reg_params
[2].value
, 0, 32, start
+ bank
->sectors
[sector
].size
);
201 retval
= xmc1xxx_nvm_check_idle(target
);
202 if (retval
!= ERROR_OK
)
205 LOG_DEBUG("Erase-checking 0x%08" PRIx32
, start
);
206 retval
= target_run_algorithm(target
,
208 ARRAY_SIZE(reg_params
), reg_params
,
209 workarea
->address
, 0,
211 if (retval
!= ERROR_OK
) {
212 LOG_ERROR("Error executing flash sector erase check "
213 "programming algorithm");
214 retval
= xmc1xxx_nvm_set_idle(target
);
215 if (retval
!= ERROR_OK
)
216 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
217 retval
= ERROR_FLASH_OPERATION_FAILED
;
221 retval
= target_read_u16(target
, NVMSTATUS
, &val
);
222 if (retval
!= ERROR_OK
) {
223 LOG_ERROR("Couldn't read NVMSTATUS");
226 bank
->sectors
[sector
].is_erased
= (val
& NVMSTATUS_VERR_MASK
) ? 0 : 1;
232 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
233 destroy_reg_param(®_params
[i
]);
236 target_free_working_area(target
, workarea
);
242 static int xmc1xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
243 uint32_t offset
, uint32_t byte_count
)
245 struct target
*target
= bank
->target
;
246 struct working_area
*code_workarea
, *data_workarea
;
247 struct reg_param reg_params
[4];
248 struct armv7m_algorithm armv7m_algo
;
249 uint32_t block_count
= DIV_ROUND_UP(byte_count
, NVM_BLOCK_SIZE
);
252 const uint8_t write_code
[] = {
253 #include "../../../contrib/loaders/flash/xmc1xxx/write.inc"
256 LOG_DEBUG("Infineon XMC1000 write at 0x%08" PRIx32
" (%" PRIu32
" bytes)",
259 if (offset
& (NVM_BLOCK_SIZE
- 1)) {
260 LOG_ERROR("offset 0x%" PRIx32
" breaks required block alignment",
262 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
264 if (byte_count
& (NVM_BLOCK_SIZE
- 1)) {
265 LOG_WARNING("length %" PRIu32
" is not block aligned, rounding up",
269 if (target
->state
!= TARGET_HALTED
) {
270 LOG_WARNING("Cannot communicate... target not halted.");
271 return ERROR_TARGET_NOT_HALTED
;
274 retval
= target_alloc_working_area(target
, sizeof(write_code
),
276 if (retval
!= ERROR_OK
) {
277 LOG_ERROR("No working area available for write code.");
278 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
281 retval
= target_write_buffer(target
, code_workarea
->address
,
282 sizeof(write_code
), write_code
);
283 if (retval
!= ERROR_OK
)
286 retval
= target_alloc_working_area(target
, MAX(NVM_BLOCK_SIZE
,
287 MIN(block_count
* NVM_BLOCK_SIZE
, target_get_working_area_avail(target
))),
289 if (retval
!= ERROR_OK
) {
290 LOG_ERROR("No working area available for write data.");
291 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
295 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
296 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
298 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
299 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
300 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
301 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
303 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
305 while (byte_count
> 0) {
306 uint32_t blocks
= MIN(block_count
, data_workarea
->size
/ NVM_BLOCK_SIZE
);
307 uint32_t addr
= bank
->base
+ offset
;
309 LOG_DEBUG("copying %" PRIu32
" bytes to SRAM " TARGET_ADDR_FMT
,
310 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
),
311 data_workarea
->address
);
313 retval
= target_write_buffer(target
, data_workarea
->address
,
314 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
), buffer
);
315 if (retval
!= ERROR_OK
) {
316 LOG_ERROR("Error writing data buffer");
317 retval
= ERROR_FLASH_OPERATION_FAILED
;
320 if (byte_count
< blocks
* NVM_BLOCK_SIZE
) {
321 retval
= target_write_memory(target
,
322 data_workarea
->address
+ byte_count
, 1,
323 blocks
* NVM_BLOCK_SIZE
- byte_count
,
324 &bank
->default_padded_value
);
325 if (retval
!= ERROR_OK
) {
326 LOG_ERROR("Error writing data padding");
327 retval
= ERROR_FLASH_OPERATION_FAILED
;
332 LOG_DEBUG("writing 0x%08" PRIx32
"-0x%08" PRIx32
" (%" PRIu32
"x)",
333 addr
, addr
+ blocks
* NVM_BLOCK_SIZE
- 1, blocks
);
335 retval
= xmc1xxx_nvm_check_idle(target
);
336 if (retval
!= ERROR_OK
)
339 buf_set_u32(reg_params
[1].value
, 0, 32, addr
);
340 buf_set_u32(reg_params
[2].value
, 0, 32, data_workarea
->address
);
341 buf_set_u32(reg_params
[3].value
, 0, 32, blocks
);
343 retval
= target_run_algorithm(target
,
345 ARRAY_SIZE(reg_params
), reg_params
,
346 code_workarea
->address
, 0,
347 5 * 60 * 1000, &armv7m_algo
);
348 if (retval
!= ERROR_OK
) {
349 LOG_ERROR("Error executing flash write "
350 "programming algorithm");
351 retval
= xmc1xxx_nvm_set_idle(target
);
352 if (retval
!= ERROR_OK
)
353 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
354 retval
= ERROR_FLASH_OPERATION_FAILED
;
358 block_count
-= blocks
;
359 offset
+= blocks
* NVM_BLOCK_SIZE
;
360 buffer
+= blocks
* NVM_BLOCK_SIZE
;
361 byte_count
-= MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
);
368 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
369 destroy_reg_param(®_params
[i
]);
371 target_free_working_area(target
, data_workarea
);
374 target_free_working_area(target
, code_workarea
);
380 static int xmc1xxx_protect_check(struct flash_bank
*bank
)
383 unsigned int num_protected
;
386 if (bank
->target
->state
!= TARGET_HALTED
) {
387 LOG_WARNING("Cannot communicate... target not halted.");
388 return ERROR_TARGET_NOT_HALTED
;
391 retval
= target_read_u32(bank
->target
, NVMCONF
, &nvmconf
);
392 if (retval
!= ERROR_OK
) {
393 LOG_ERROR("Cannot read NVMCONF register.");
396 LOG_DEBUG("NVMCONF = %08" PRIx32
, nvmconf
);
398 num_protected
= (nvmconf
>> 4) & 0xff;
400 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
401 bank
->sectors
[i
].is_protected
= (i
< num_protected
) ? 1 : 0;
406 static int xmc1xxx_get_info_command(struct flash_bank
*bank
, struct command_invocation
*cmd
)
411 if (bank
->target
->state
!= TARGET_HALTED
) {
412 LOG_WARNING("Cannot communicate... target not halted.");
413 return ERROR_TARGET_NOT_HALTED
;
416 /* Obtain the 8-word Chip Identification Number */
417 for (i
= 0; i
< 7; i
++) {
418 retval
= target_read_u32(bank
->target
, FLASH_CS0
+ i
* 4, &chipid
[i
]);
419 if (retval
!= ERROR_OK
) {
420 LOG_ERROR("Cannot read CS0 register %i.", i
);
423 LOG_DEBUG("ID[%d] = %08" PRIX32
, i
, chipid
[i
]);
425 retval
= target_read_u32(bank
->target
, SCU_BASE
+ 0x000, &chipid
[7]);
426 if (retval
!= ERROR_OK
) {
427 LOG_ERROR("Cannot read DBGROMID register.");
430 LOG_DEBUG("ID[7] = %08" PRIX32
, chipid
[7]);
432 command_print_sameline(cmd
,
433 "XMC%" PRIx32
"00 %" PRIX32
" flash %" PRIu32
"KB ROM %" PRIu32
"KB SRAM %" PRIu32
"KB",
434 (chipid
[0] >> 12) & 0xff,
435 0xAA + (chipid
[7] >> 28) - 1,
436 (((chipid
[6] >> 12) & 0x3f) - 1) * 4,
437 (((chipid
[4] >> 8) & 0x3f) * 256) / 1024,
438 (((chipid
[5] >> 8) & 0x1f) * 256 * 4) / 1024);
443 static int xmc1xxx_probe(struct flash_bank
*bank
)
445 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
446 uint32_t flash_addr
= bank
->base
;
447 uint32_t idchip
, flsize
;
450 if (xmc_bank
->probed
)
453 if (bank
->target
->state
!= TARGET_HALTED
) {
454 LOG_WARNING("Cannot communicate... target not halted.");
455 return ERROR_TARGET_NOT_HALTED
;
458 retval
= target_read_u32(bank
->target
, SCU_IDCHIP
, &idchip
);
459 if (retval
!= ERROR_OK
) {
460 LOG_ERROR("Cannot read IDCHIP register.");
464 if ((idchip
& 0xffff0000) != 0x10000) {
465 LOG_ERROR("IDCHIP register does not match XMC1xxx.");
469 LOG_DEBUG("IDCHIP = %08" PRIx32
, idchip
);
471 retval
= target_read_u32(bank
->target
, PAU_FLSIZE
, &flsize
);
472 if (retval
!= ERROR_OK
) {
473 LOG_ERROR("Cannot read FLSIZE register.");
477 bank
->num_sectors
= 1 + ((flsize
>> 12) & 0x3f) - 1;
478 bank
->size
= bank
->num_sectors
* 4 * 1024;
479 bank
->sectors
= calloc(bank
->num_sectors
,
480 sizeof(struct flash_sector
));
481 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
483 bank
->sectors
[i
].size
= 0x200;
484 bank
->sectors
[i
].offset
= 0xE00;
485 flash_addr
+= 0x1000;
487 bank
->sectors
[i
].size
= 4 * 1024;
488 bank
->sectors
[i
].offset
= flash_addr
- bank
->base
;
489 flash_addr
+= bank
->sectors
[i
].size
;
491 bank
->sectors
[i
].is_erased
= -1;
492 bank
->sectors
[i
].is_protected
= -1;
495 xmc_bank
->probed
= true;
500 static int xmc1xxx_auto_probe(struct flash_bank
*bank
)
502 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
504 if (xmc_bank
->probed
)
507 return xmc1xxx_probe(bank
);
510 FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command
)
512 struct xmc1xxx_flash_bank
*xmc_bank
;
514 xmc_bank
= malloc(sizeof(struct xmc1xxx_flash_bank
));
516 return ERROR_FLASH_OPERATION_FAILED
;
518 xmc_bank
->probed
= false;
520 bank
->driver_priv
= xmc_bank
;
525 static const struct command_registration xmc1xxx_exec_command_handlers
[] = {
526 COMMAND_REGISTRATION_DONE
529 static const struct command_registration xmc1xxx_command_handlers
[] = {
533 .help
= "xmc1xxx flash command group",
535 .chain
= xmc1xxx_exec_command_handlers
,
537 COMMAND_REGISTRATION_DONE
540 const struct flash_driver xmc1xxx_flash
= {
542 .commands
= xmc1xxx_command_handlers
,
543 .flash_bank_command
= xmc1xxx_flash_bank_command
,
544 .info
= xmc1xxx_get_info_command
,
545 .probe
= xmc1xxx_probe
,
546 .auto_probe
= xmc1xxx_auto_probe
,
547 .protect_check
= xmc1xxx_protect_check
,
548 .read
= default_flash_read
,
549 .erase
= xmc1xxx_erase
,
550 .erase_check
= xmc1xxx_erase_check
,
551 .write
= xmc1xxx_write
,
552 .free_driver_priv
= default_flash_free_driver_priv
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)