1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * 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 const struct flash_driver xmc1xxx_flash
= {
525 .flash_bank_command
= xmc1xxx_flash_bank_command
,
526 .info
= xmc1xxx_get_info_command
,
527 .probe
= xmc1xxx_probe
,
528 .auto_probe
= xmc1xxx_auto_probe
,
529 .protect_check
= xmc1xxx_protect_check
,
530 .read
= default_flash_read
,
531 .erase
= xmc1xxx_erase
,
532 .erase_check
= xmc1xxx_erase_check
,
533 .write
= xmc1xxx_write
,
534 .free_driver_priv
= default_flash_free_driver_priv
,