4 * Copyright (c) 2016 Andreas Färber
14 #include <helper/align.h>
15 #include <helper/binarybuffer.h>
16 #include <target/algorithm.h>
17 #include <target/armv7m.h>
19 #define FLASH_BASE 0x10000000
20 #define PAU_BASE 0x40000000
21 #define SCU_BASE 0x40010000
22 #define NVM_BASE 0x40050000
24 #define FLASH_CS0 (FLASH_BASE + 0xf00)
26 #define PAU_FLSIZE (PAU_BASE + 0x404)
28 #define SCU_IDCHIP (SCU_BASE + 0x004)
30 #define NVMSTATUS (NVM_BASE + 0x00)
31 #define NVMPROG (NVM_BASE + 0x04)
32 #define NVMCONF (NVM_BASE + 0x08)
34 #define NVMSTATUS_BUSY (1 << 0)
35 #define NVMSTATUS_VERR_MASK (0x3 << 2)
37 #define NVMPROG_ACTION_OPTYPE_IDLE_VERIFY (0 << 0)
38 #define NVMPROG_ACTION_OPTYPE_WRITE (1 << 0)
39 #define NVMPROG_ACTION_OPTYPE_PAGE_ERASE (2 << 0)
41 #define NVMPROG_ACTION_ONE_SHOT_ONCE (1 << 4)
42 #define NVMPROG_ACTION_ONE_SHOT_CONTINUOUS (2 << 4)
44 #define NVMPROG_ACTION_VERIFY_EACH (1 << 6)
45 #define NVMPROG_ACTION_VERIFY_NO (2 << 6)
46 #define NVMPROG_ACTION_VERIFY_ARRAY (3 << 6)
48 #define NVMPROG_ACTION_IDLE 0x00
49 #define NVMPROG_ACTION_MASK 0xff
51 #define NVM_WORD_SIZE 4
52 #define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE)
53 #define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE)
55 struct xmc1xxx_flash_bank
{
59 static int xmc1xxx_nvm_set_idle(struct target
*target
)
61 return target_write_u16(target
, NVMPROG
, NVMPROG_ACTION_IDLE
);
64 static int xmc1xxx_nvm_check_idle(struct target
*target
)
69 retval
= target_read_u16(target
, NVMPROG
, &val
);
70 if (retval
!= ERROR_OK
)
72 if ((val
& NVMPROG_ACTION_MASK
) != NVMPROG_ACTION_IDLE
) {
73 LOG_WARNING("NVMPROG.ACTION");
74 retval
= xmc1xxx_nvm_set_idle(target
);
80 static int xmc1xxx_erase(struct flash_bank
*bank
, unsigned int first
,
83 struct target
*target
= bank
->target
;
84 struct working_area
*workarea
;
85 struct reg_param reg_params
[3];
86 struct armv7m_algorithm armv7m_algo
;
89 const uint8_t erase_code
[] = {
90 #include "../../../contrib/loaders/flash/xmc1xxx/erase.inc"
93 LOG_DEBUG("Infineon XMC1000 erase sectors %u to %u", first
, last
);
95 if (bank
->target
->state
!= TARGET_HALTED
) {
96 LOG_WARNING("Cannot communicate... target not halted.");
97 return ERROR_TARGET_NOT_HALTED
;
100 retval
= xmc1xxx_nvm_check_idle(target
);
101 if (retval
!= ERROR_OK
)
104 retval
= target_alloc_working_area(target
, sizeof(erase_code
),
106 if (retval
!= ERROR_OK
) {
107 LOG_ERROR("No working area available.");
108 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
111 retval
= target_write_buffer(target
, workarea
->address
,
112 sizeof(erase_code
), erase_code
);
113 if (retval
!= ERROR_OK
)
116 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
117 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
119 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
120 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
121 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
123 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
124 buf_set_u32(reg_params
[1].value
, 0, 32, bank
->base
+
125 bank
->sectors
[first
].offset
);
126 buf_set_u32(reg_params
[2].value
, 0, 32, bank
->base
+
127 bank
->sectors
[last
].offset
+ bank
->sectors
[last
].size
);
129 retval
= target_run_algorithm(target
,
131 ARRAY_SIZE(reg_params
), reg_params
,
132 workarea
->address
, 0,
134 if (retval
!= ERROR_OK
) {
135 LOG_ERROR("Error executing flash sector erase "
136 "programming algorithm");
137 retval
= xmc1xxx_nvm_set_idle(target
);
138 if (retval
!= ERROR_OK
)
139 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
140 retval
= ERROR_FLASH_OPERATION_FAILED
;
145 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
146 destroy_reg_param(®_params
[i
]);
149 target_free_working_area(target
, workarea
);
155 static int xmc1xxx_erase_check(struct flash_bank
*bank
)
157 struct target
*target
= bank
->target
;
158 struct working_area
*workarea
;
159 struct reg_param reg_params
[3];
160 struct armv7m_algorithm armv7m_algo
;
164 const uint8_t erase_check_code
[] = {
165 #include "../../../contrib/loaders/flash/xmc1xxx/erase_check.inc"
168 if (bank
->target
->state
!= TARGET_HALTED
) {
169 LOG_WARNING("Cannot communicate... target not halted.");
170 return ERROR_TARGET_NOT_HALTED
;
173 retval
= target_alloc_working_area(target
, sizeof(erase_check_code
),
175 if (retval
!= ERROR_OK
) {
176 LOG_ERROR("No working area available.");
177 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
180 retval
= target_write_buffer(target
, workarea
->address
,
181 sizeof(erase_check_code
), erase_check_code
);
182 if (retval
!= ERROR_OK
)
185 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
186 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
188 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
189 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
190 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
192 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
194 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
195 uint32_t start
= bank
->base
+ bank
->sectors
[sector
].offset
;
196 buf_set_u32(reg_params
[1].value
, 0, 32, start
);
197 buf_set_u32(reg_params
[2].value
, 0, 32, start
+ bank
->sectors
[sector
].size
);
199 retval
= xmc1xxx_nvm_check_idle(target
);
200 if (retval
!= ERROR_OK
)
203 LOG_DEBUG("Erase-checking 0x%08" PRIx32
, start
);
204 retval
= target_run_algorithm(target
,
206 ARRAY_SIZE(reg_params
), reg_params
,
207 workarea
->address
, 0,
209 if (retval
!= ERROR_OK
) {
210 LOG_ERROR("Error executing flash sector erase check "
211 "programming algorithm");
212 retval
= xmc1xxx_nvm_set_idle(target
);
213 if (retval
!= ERROR_OK
)
214 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
215 retval
= ERROR_FLASH_OPERATION_FAILED
;
219 retval
= target_read_u16(target
, NVMSTATUS
, &val
);
220 if (retval
!= ERROR_OK
) {
221 LOG_ERROR("Couldn't read NVMSTATUS");
224 bank
->sectors
[sector
].is_erased
= (val
& NVMSTATUS_VERR_MASK
) ? 0 : 1;
230 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
231 destroy_reg_param(®_params
[i
]);
234 target_free_working_area(target
, workarea
);
240 static int xmc1xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
241 uint32_t offset
, uint32_t byte_count
)
243 struct target
*target
= bank
->target
;
244 struct working_area
*code_workarea
, *data_workarea
;
245 struct reg_param reg_params
[4];
246 struct armv7m_algorithm armv7m_algo
;
247 uint32_t block_count
= DIV_ROUND_UP(byte_count
, NVM_BLOCK_SIZE
);
250 const uint8_t write_code
[] = {
251 #include "../../../contrib/loaders/flash/xmc1xxx/write.inc"
254 LOG_DEBUG("Infineon XMC1000 write at 0x%08" PRIx32
" (%" PRIu32
" bytes)",
257 if (!IS_ALIGNED(offset
, NVM_BLOCK_SIZE
)) {
258 LOG_ERROR("offset 0x%" PRIx32
" breaks required block alignment",
260 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
262 if (!IS_ALIGNED(byte_count
, NVM_BLOCK_SIZE
)) {
263 LOG_WARNING("length %" PRIu32
" is not block aligned, rounding up",
267 if (target
->state
!= TARGET_HALTED
) {
268 LOG_WARNING("Cannot communicate... target not halted.");
269 return ERROR_TARGET_NOT_HALTED
;
272 retval
= target_alloc_working_area(target
, sizeof(write_code
),
274 if (retval
!= ERROR_OK
) {
275 LOG_ERROR("No working area available for write code.");
276 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
279 retval
= target_write_buffer(target
, code_workarea
->address
,
280 sizeof(write_code
), write_code
);
281 if (retval
!= ERROR_OK
)
284 retval
= target_alloc_working_area(target
, MAX(NVM_BLOCK_SIZE
,
285 MIN(block_count
* NVM_BLOCK_SIZE
, target_get_working_area_avail(target
))),
287 if (retval
!= ERROR_OK
) {
288 LOG_ERROR("No working area available for write data.");
289 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
293 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
294 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
296 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
297 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
298 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
299 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
301 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
303 while (byte_count
> 0) {
304 uint32_t blocks
= MIN(block_count
, data_workarea
->size
/ NVM_BLOCK_SIZE
);
305 uint32_t addr
= bank
->base
+ offset
;
307 LOG_DEBUG("copying %" PRIu32
" bytes to SRAM " TARGET_ADDR_FMT
,
308 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
),
309 data_workarea
->address
);
311 retval
= target_write_buffer(target
, data_workarea
->address
,
312 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
), buffer
);
313 if (retval
!= ERROR_OK
) {
314 LOG_ERROR("Error writing data buffer");
315 retval
= ERROR_FLASH_OPERATION_FAILED
;
318 if (byte_count
< blocks
* NVM_BLOCK_SIZE
) {
319 retval
= target_write_memory(target
,
320 data_workarea
->address
+ byte_count
, 1,
321 blocks
* NVM_BLOCK_SIZE
- byte_count
,
322 &bank
->default_padded_value
);
323 if (retval
!= ERROR_OK
) {
324 LOG_ERROR("Error writing data padding");
325 retval
= ERROR_FLASH_OPERATION_FAILED
;
330 LOG_DEBUG("writing 0x%08" PRIx32
"-0x%08" PRIx32
" (%" PRIu32
"x)",
331 addr
, addr
+ blocks
* NVM_BLOCK_SIZE
- 1, blocks
);
333 retval
= xmc1xxx_nvm_check_idle(target
);
334 if (retval
!= ERROR_OK
)
337 buf_set_u32(reg_params
[1].value
, 0, 32, addr
);
338 buf_set_u32(reg_params
[2].value
, 0, 32, data_workarea
->address
);
339 buf_set_u32(reg_params
[3].value
, 0, 32, blocks
);
341 retval
= target_run_algorithm(target
,
343 ARRAY_SIZE(reg_params
), reg_params
,
344 code_workarea
->address
, 0,
345 5 * 60 * 1000, &armv7m_algo
);
346 if (retval
!= ERROR_OK
) {
347 LOG_ERROR("Error executing flash write "
348 "programming algorithm");
349 retval
= xmc1xxx_nvm_set_idle(target
);
350 if (retval
!= ERROR_OK
)
351 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
352 retval
= ERROR_FLASH_OPERATION_FAILED
;
356 block_count
-= blocks
;
357 offset
+= blocks
* NVM_BLOCK_SIZE
;
358 buffer
+= blocks
* NVM_BLOCK_SIZE
;
359 byte_count
-= MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
);
366 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
367 destroy_reg_param(®_params
[i
]);
369 target_free_working_area(target
, data_workarea
);
372 target_free_working_area(target
, code_workarea
);
378 static int xmc1xxx_protect_check(struct flash_bank
*bank
)
381 unsigned int num_protected
;
384 if (bank
->target
->state
!= TARGET_HALTED
) {
385 LOG_WARNING("Cannot communicate... target not halted.");
386 return ERROR_TARGET_NOT_HALTED
;
389 retval
= target_read_u32(bank
->target
, NVMCONF
, &nvmconf
);
390 if (retval
!= ERROR_OK
) {
391 LOG_ERROR("Cannot read NVMCONF register.");
394 LOG_DEBUG("NVMCONF = %08" PRIx32
, nvmconf
);
396 num_protected
= (nvmconf
>> 4) & 0xff;
398 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
399 bank
->sectors
[i
].is_protected
= (i
< num_protected
) ? 1 : 0;
404 static int xmc1xxx_get_info_command(struct flash_bank
*bank
, struct command_invocation
*cmd
)
409 if (bank
->target
->state
!= TARGET_HALTED
) {
410 LOG_WARNING("Cannot communicate... target not halted.");
411 return ERROR_TARGET_NOT_HALTED
;
414 /* Obtain the 8-word Chip Identification Number */
415 for (i
= 0; i
< 7; i
++) {
416 retval
= target_read_u32(bank
->target
, FLASH_CS0
+ i
* 4, &chipid
[i
]);
417 if (retval
!= ERROR_OK
) {
418 LOG_ERROR("Cannot read CS0 register %i.", i
);
421 LOG_DEBUG("ID[%d] = %08" PRIX32
, i
, chipid
[i
]);
423 retval
= target_read_u32(bank
->target
, SCU_BASE
+ 0x000, &chipid
[7]);
424 if (retval
!= ERROR_OK
) {
425 LOG_ERROR("Cannot read DBGROMID register.");
428 LOG_DEBUG("ID[7] = %08" PRIX32
, chipid
[7]);
430 command_print_sameline(cmd
,
431 "XMC%" PRIx32
"00 %" PRIX32
" flash %" PRIu32
"KB ROM %" PRIu32
"KB SRAM %" PRIu32
"KB",
432 (chipid
[0] >> 12) & 0xff,
433 0xAA + (chipid
[7] >> 28) - 1,
434 (((chipid
[6] >> 12) & 0x3f) - 1) * 4,
435 (((chipid
[4] >> 8) & 0x3f) * 256) / 1024,
436 (((chipid
[5] >> 8) & 0x1f) * 256 * 4) / 1024);
441 static int xmc1xxx_probe(struct flash_bank
*bank
)
443 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
444 uint32_t flash_addr
= bank
->base
;
445 uint32_t idchip
, flsize
;
448 if (xmc_bank
->probed
)
451 if (bank
->target
->state
!= TARGET_HALTED
) {
452 LOG_WARNING("Cannot communicate... target not halted.");
453 return ERROR_TARGET_NOT_HALTED
;
456 retval
= target_read_u32(bank
->target
, SCU_IDCHIP
, &idchip
);
457 if (retval
!= ERROR_OK
) {
458 LOG_ERROR("Cannot read IDCHIP register.");
462 if ((idchip
& 0xffff0000) != 0x10000) {
463 LOG_ERROR("IDCHIP register does not match XMC1xxx.");
467 LOG_DEBUG("IDCHIP = %08" PRIx32
, idchip
);
469 retval
= target_read_u32(bank
->target
, PAU_FLSIZE
, &flsize
);
470 if (retval
!= ERROR_OK
) {
471 LOG_ERROR("Cannot read FLSIZE register.");
475 bank
->num_sectors
= 1 + ((flsize
>> 12) & 0x3f) - 1;
476 bank
->size
= bank
->num_sectors
* 4 * 1024;
477 bank
->sectors
= calloc(bank
->num_sectors
,
478 sizeof(struct flash_sector
));
479 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
481 bank
->sectors
[i
].size
= 0x200;
482 bank
->sectors
[i
].offset
= 0xE00;
483 flash_addr
+= 0x1000;
485 bank
->sectors
[i
].size
= 4 * 1024;
486 bank
->sectors
[i
].offset
= flash_addr
- bank
->base
;
487 flash_addr
+= bank
->sectors
[i
].size
;
489 bank
->sectors
[i
].is_erased
= -1;
490 bank
->sectors
[i
].is_protected
= -1;
493 xmc_bank
->probed
= true;
498 static int xmc1xxx_auto_probe(struct flash_bank
*bank
)
500 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
502 if (xmc_bank
->probed
)
505 return xmc1xxx_probe(bank
);
508 FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command
)
510 struct xmc1xxx_flash_bank
*xmc_bank
;
512 xmc_bank
= malloc(sizeof(struct xmc1xxx_flash_bank
));
514 return ERROR_FLASH_OPERATION_FAILED
;
516 xmc_bank
->probed
= false;
518 bank
->driver_priv
= xmc_bank
;
523 static const struct command_registration xmc1xxx_exec_command_handlers
[] = {
524 COMMAND_REGISTRATION_DONE
527 static const struct command_registration xmc1xxx_command_handlers
[] = {
531 .help
= "xmc1xxx flash command group",
533 .chain
= xmc1xxx_exec_command_handlers
,
535 COMMAND_REGISTRATION_DONE
538 const struct flash_driver xmc1xxx_flash
= {
540 .commands
= xmc1xxx_command_handlers
,
541 .flash_bank_command
= xmc1xxx_flash_bank_command
,
542 .info
= xmc1xxx_get_info_command
,
543 .probe
= xmc1xxx_probe
,
544 .auto_probe
= xmc1xxx_auto_probe
,
545 .protect_check
= xmc1xxx_protect_check
,
546 .read
= default_flash_read
,
547 .erase
= xmc1xxx_erase
,
548 .erase_check
= xmc1xxx_erase_check
,
549 .write
= xmc1xxx_write
,
550 .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)