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
;
144 for (unsigned int sector
= first
; sector
<= last
; sector
++)
145 bank
->sectors
[sector
].is_erased
= 1;
148 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
149 destroy_reg_param(®_params
[i
]);
152 target_free_working_area(target
, workarea
);
158 static int xmc1xxx_erase_check(struct flash_bank
*bank
)
160 struct target
*target
= bank
->target
;
161 struct working_area
*workarea
;
162 struct reg_param reg_params
[3];
163 struct armv7m_algorithm armv7m_algo
;
167 const uint8_t erase_check_code
[] = {
168 #include "../../../contrib/loaders/flash/xmc1xxx/erase_check.inc"
171 if (bank
->target
->state
!= TARGET_HALTED
) {
172 LOG_WARNING("Cannot communicate... target not halted.");
173 return ERROR_TARGET_NOT_HALTED
;
176 retval
= target_alloc_working_area(target
, sizeof(erase_check_code
),
178 if (retval
!= ERROR_OK
) {
179 LOG_ERROR("No working area available.");
180 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
183 retval
= target_write_buffer(target
, workarea
->address
,
184 sizeof(erase_check_code
), erase_check_code
);
185 if (retval
!= ERROR_OK
)
188 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
189 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
191 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
192 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
193 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
195 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
197 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
198 uint32_t start
= bank
->base
+ bank
->sectors
[sector
].offset
;
199 buf_set_u32(reg_params
[1].value
, 0, 32, start
);
200 buf_set_u32(reg_params
[2].value
, 0, 32, start
+ bank
->sectors
[sector
].size
);
202 retval
= xmc1xxx_nvm_check_idle(target
);
203 if (retval
!= ERROR_OK
)
206 LOG_DEBUG("Erase-checking 0x%08" PRIx32
, start
);
207 retval
= target_run_algorithm(target
,
209 ARRAY_SIZE(reg_params
), reg_params
,
210 workarea
->address
, 0,
212 if (retval
!= ERROR_OK
) {
213 LOG_ERROR("Error executing flash sector erase check "
214 "programming algorithm");
215 retval
= xmc1xxx_nvm_set_idle(target
);
216 if (retval
!= ERROR_OK
)
217 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
218 retval
= ERROR_FLASH_OPERATION_FAILED
;
222 retval
= target_read_u16(target
, NVMSTATUS
, &val
);
223 if (retval
!= ERROR_OK
) {
224 LOG_ERROR("Couldn't read NVMSTATUS");
227 bank
->sectors
[sector
].is_erased
= (val
& NVMSTATUS_VERR_MASK
) ? 0 : 1;
233 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
234 destroy_reg_param(®_params
[i
]);
237 target_free_working_area(target
, workarea
);
243 static int xmc1xxx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
244 uint32_t offset
, uint32_t byte_count
)
246 struct target
*target
= bank
->target
;
247 struct working_area
*code_workarea
, *data_workarea
;
248 struct reg_param reg_params
[4];
249 struct armv7m_algorithm armv7m_algo
;
250 uint32_t block_count
= DIV_ROUND_UP(byte_count
, NVM_BLOCK_SIZE
);
253 const uint8_t write_code
[] = {
254 #include "../../../contrib/loaders/flash/xmc1xxx/write.inc"
257 LOG_DEBUG("Infineon XMC1000 write at 0x%08" PRIx32
" (%" PRIu32
" bytes)",
260 if (!IS_ALIGNED(offset
, NVM_BLOCK_SIZE
)) {
261 LOG_ERROR("offset 0x%" PRIx32
" breaks required block alignment",
263 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
265 if (!IS_ALIGNED(byte_count
, NVM_BLOCK_SIZE
)) {
266 LOG_WARNING("length %" PRIu32
" is not block aligned, rounding up",
270 if (target
->state
!= TARGET_HALTED
) {
271 LOG_WARNING("Cannot communicate... target not halted.");
272 return ERROR_TARGET_NOT_HALTED
;
275 retval
= target_alloc_working_area(target
, sizeof(write_code
),
277 if (retval
!= ERROR_OK
) {
278 LOG_ERROR("No working area available for write code.");
279 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
282 retval
= target_write_buffer(target
, code_workarea
->address
,
283 sizeof(write_code
), write_code
);
284 if (retval
!= ERROR_OK
)
287 retval
= target_alloc_working_area(target
, MAX(NVM_BLOCK_SIZE
,
288 MIN(block_count
* NVM_BLOCK_SIZE
, target_get_working_area_avail(target
))),
290 if (retval
!= ERROR_OK
) {
291 LOG_ERROR("No working area available for write data.");
292 retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
296 armv7m_algo
.common_magic
= ARMV7M_COMMON_MAGIC
;
297 armv7m_algo
.core_mode
= ARM_MODE_THREAD
;
299 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
300 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
301 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
302 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
304 buf_set_u32(reg_params
[0].value
, 0, 32, NVM_BASE
);
306 while (byte_count
> 0) {
307 uint32_t blocks
= MIN(block_count
, data_workarea
->size
/ NVM_BLOCK_SIZE
);
308 uint32_t addr
= bank
->base
+ offset
;
310 LOG_DEBUG("copying %" PRIu32
" bytes to SRAM " TARGET_ADDR_FMT
,
311 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
),
312 data_workarea
->address
);
314 retval
= target_write_buffer(target
, data_workarea
->address
,
315 MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
), buffer
);
316 if (retval
!= ERROR_OK
) {
317 LOG_ERROR("Error writing data buffer");
318 retval
= ERROR_FLASH_OPERATION_FAILED
;
321 if (byte_count
< blocks
* NVM_BLOCK_SIZE
) {
322 retval
= target_write_memory(target
,
323 data_workarea
->address
+ byte_count
, 1,
324 blocks
* NVM_BLOCK_SIZE
- byte_count
,
325 &bank
->default_padded_value
);
326 if (retval
!= ERROR_OK
) {
327 LOG_ERROR("Error writing data padding");
328 retval
= ERROR_FLASH_OPERATION_FAILED
;
333 LOG_DEBUG("writing 0x%08" PRIx32
"-0x%08" PRIx32
" (%" PRIu32
"x)",
334 addr
, addr
+ blocks
* NVM_BLOCK_SIZE
- 1, blocks
);
336 retval
= xmc1xxx_nvm_check_idle(target
);
337 if (retval
!= ERROR_OK
)
340 buf_set_u32(reg_params
[1].value
, 0, 32, addr
);
341 buf_set_u32(reg_params
[2].value
, 0, 32, data_workarea
->address
);
342 buf_set_u32(reg_params
[3].value
, 0, 32, blocks
);
344 retval
= target_run_algorithm(target
,
346 ARRAY_SIZE(reg_params
), reg_params
,
347 code_workarea
->address
, 0,
348 5 * 60 * 1000, &armv7m_algo
);
349 if (retval
!= ERROR_OK
) {
350 LOG_ERROR("Error executing flash write "
351 "programming algorithm");
352 retval
= xmc1xxx_nvm_set_idle(target
);
353 if (retval
!= ERROR_OK
)
354 LOG_WARNING("Couldn't restore NVMPROG.ACTION");
355 retval
= ERROR_FLASH_OPERATION_FAILED
;
359 block_count
-= blocks
;
360 offset
+= blocks
* NVM_BLOCK_SIZE
;
361 buffer
+= blocks
* NVM_BLOCK_SIZE
;
362 byte_count
-= MIN(blocks
* NVM_BLOCK_SIZE
, byte_count
);
369 for (i
= 0; i
< ARRAY_SIZE(reg_params
); i
++)
370 destroy_reg_param(®_params
[i
]);
372 target_free_working_area(target
, data_workarea
);
375 target_free_working_area(target
, code_workarea
);
381 static int xmc1xxx_protect_check(struct flash_bank
*bank
)
384 unsigned int num_protected
;
387 if (bank
->target
->state
!= TARGET_HALTED
) {
388 LOG_WARNING("Cannot communicate... target not halted.");
389 return ERROR_TARGET_NOT_HALTED
;
392 retval
= target_read_u32(bank
->target
, NVMCONF
, &nvmconf
);
393 if (retval
!= ERROR_OK
) {
394 LOG_ERROR("Cannot read NVMCONF register.");
397 LOG_DEBUG("NVMCONF = %08" PRIx32
, nvmconf
);
399 num_protected
= (nvmconf
>> 4) & 0xff;
401 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
402 bank
->sectors
[i
].is_protected
= (i
< num_protected
) ? 1 : 0;
407 static int xmc1xxx_get_info_command(struct flash_bank
*bank
, struct command_invocation
*cmd
)
412 if (bank
->target
->state
!= TARGET_HALTED
) {
413 LOG_WARNING("Cannot communicate... target not halted.");
414 return ERROR_TARGET_NOT_HALTED
;
417 /* Obtain the 8-word Chip Identification Number */
418 for (i
= 0; i
< 7; i
++) {
419 retval
= target_read_u32(bank
->target
, FLASH_CS0
+ i
* 4, &chipid
[i
]);
420 if (retval
!= ERROR_OK
) {
421 LOG_ERROR("Cannot read CS0 register %i.", i
);
424 LOG_DEBUG("ID[%d] = %08" PRIX32
, i
, chipid
[i
]);
426 retval
= target_read_u32(bank
->target
, SCU_BASE
+ 0x000, &chipid
[7]);
427 if (retval
!= ERROR_OK
) {
428 LOG_ERROR("Cannot read DBGROMID register.");
431 LOG_DEBUG("ID[7] = %08" PRIX32
, chipid
[7]);
433 command_print_sameline(cmd
,
434 "XMC%" PRIx32
"00 %" PRIX32
" flash %" PRIu32
"KB ROM %" PRIu32
"KB SRAM %" PRIu32
"KB",
435 (chipid
[0] >> 12) & 0xff,
436 0xAA + (chipid
[7] >> 28) - 1,
437 (((chipid
[6] >> 12) & 0x3f) - 1) * 4,
438 (((chipid
[4] >> 8) & 0x3f) * 256) / 1024,
439 (((chipid
[5] >> 8) & 0x1f) * 256 * 4) / 1024);
444 static int xmc1xxx_probe(struct flash_bank
*bank
)
446 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
447 uint32_t flash_addr
= bank
->base
;
448 uint32_t idchip
, flsize
;
451 if (xmc_bank
->probed
)
454 if (bank
->target
->state
!= TARGET_HALTED
) {
455 LOG_WARNING("Cannot communicate... target not halted.");
456 return ERROR_TARGET_NOT_HALTED
;
459 retval
= target_read_u32(bank
->target
, SCU_IDCHIP
, &idchip
);
460 if (retval
!= ERROR_OK
) {
461 LOG_ERROR("Cannot read IDCHIP register.");
465 if ((idchip
& 0xffff0000) != 0x10000) {
466 LOG_ERROR("IDCHIP register does not match XMC1xxx.");
470 LOG_DEBUG("IDCHIP = %08" PRIx32
, idchip
);
472 retval
= target_read_u32(bank
->target
, PAU_FLSIZE
, &flsize
);
473 if (retval
!= ERROR_OK
) {
474 LOG_ERROR("Cannot read FLSIZE register.");
478 bank
->num_sectors
= 1 + ((flsize
>> 12) & 0x3f) - 1;
479 bank
->size
= bank
->num_sectors
* 4 * 1024;
480 bank
->sectors
= calloc(bank
->num_sectors
,
481 sizeof(struct flash_sector
));
482 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
484 bank
->sectors
[i
].size
= 0x200;
485 bank
->sectors
[i
].offset
= 0xE00;
486 flash_addr
+= 0x1000;
488 bank
->sectors
[i
].size
= 4 * 1024;
489 bank
->sectors
[i
].offset
= flash_addr
- bank
->base
;
490 flash_addr
+= bank
->sectors
[i
].size
;
492 bank
->sectors
[i
].is_erased
= -1;
493 bank
->sectors
[i
].is_protected
= -1;
496 xmc_bank
->probed
= true;
501 static int xmc1xxx_auto_probe(struct flash_bank
*bank
)
503 struct xmc1xxx_flash_bank
*xmc_bank
= bank
->driver_priv
;
505 if (xmc_bank
->probed
)
508 return xmc1xxx_probe(bank
);
511 FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command
)
513 struct xmc1xxx_flash_bank
*xmc_bank
;
515 xmc_bank
= malloc(sizeof(struct xmc1xxx_flash_bank
));
517 return ERROR_FLASH_OPERATION_FAILED
;
519 xmc_bank
->probed
= false;
521 bank
->driver_priv
= xmc_bank
;
526 static const struct command_registration xmc1xxx_exec_command_handlers
[] = {
527 COMMAND_REGISTRATION_DONE
530 static const struct command_registration xmc1xxx_command_handlers
[] = {
534 .help
= "xmc1xxx flash command group",
536 .chain
= xmc1xxx_exec_command_handlers
,
538 COMMAND_REGISTRATION_DONE
541 const struct flash_driver xmc1xxx_flash
= {
543 .commands
= xmc1xxx_command_handlers
,
544 .flash_bank_command
= xmc1xxx_flash_bank_command
,
545 .info
= xmc1xxx_get_info_command
,
546 .probe
= xmc1xxx_probe
,
547 .auto_probe
= xmc1xxx_auto_probe
,
548 .protect_check
= xmc1xxx_protect_check
,
549 .read
= default_flash_read
,
550 .erase
= xmc1xxx_erase
,
551 .erase_check
= xmc1xxx_erase_check
,
552 .write
= xmc1xxx_write
,
553 .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)