ipdbg: fix double free of virtual-ir data
[openocd.git] / src / flash / nor / rsl10.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2022 by Toms Stūrmanis *
5 * toms.sturmanis@gmail.com *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <stdint.h>
13
14 #include <helper/binarybuffer.h>
15 #include <helper/bits.h>
16
17 #include <target/algorithm.h>
18 #include <target/arm_adi_v5.h>
19 #include <target/armv7m.h>
20 #include <target/cortex_m.h>
21
22 #include "imp.h"
23
24 #define RSL10_FLASH_ADDRESS_MAIN 0x00100000
25 #define RSL10_FLASH_ADDRESS_NVR1 0x00080000
26 #define RSL10_FLASH_ADDRESS_NVR2 0x00080800
27 #define RSL10_FLASH_ADDRESS_NVR3 0x00081000
28 #define RSL10_FLASH_ADDRESS_NVR4 0x00081800
29 #define RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING 0x00081040
30
31 #define RSL10_REG_ID 0x1FFFFFFC
32
33 #define RSL10_FLASH_REG_MAIN_WRITE_UNLOCK 0x40000504
34 #define RSL10_FLASH_REG_MAIN_CTRL 0x40000508
35 #define RSL10_FLASH_REG_IF_STATUS 0x40000538
36 #define RSL10_FLASH_REG_NVR_WRITE_UNLOCK 0x40000548
37 #define RSL10_FLASH_REG_NVR_CTRL 0x4000054C
38
39 #define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1 0x400000F0
40 #define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY2 0x400000F4
41 #define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY3 0x400000F8
42 #define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY4 0x400000FC
43
44 #define RSL10_NVR3_USER_KEY_OFFSET 0x40
45
46 #define RSL10_ID 0x09010106
47 #define RSL10_FLASH_KEY_MAIN 0xDBC8264E
48 #define RSL10_FLASH_KEY_NVR 0x71B371F5
49 #define RSL10_KEY_DEBUG_LOCK 0x4C6F634B
50
51 #define RSL10_FLASH_REG_MAIN_CTRL_LOW_W_ENABLE BIT(0)
52 #define RSL10_FLASH_REG_MAIN_CTRL_MIDDLE_W_ENABLE BIT(1)
53 #define RSL10_FLASH_REG_MAIN_CTRL_HIGH_W_ENABLE BIT(2)
54
55 #define RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE BIT(1)
56 #define RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE BIT(2)
57 #define RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE BIT(3)
58
59 #define RSL10_FLASH_REG_STATUS_LOW_W_UNLOCKED BIT(0)
60 #define RSL10_FLASH_REG_STATUS_MIDDLE_W_UNLOCKED BIT(1)
61 #define RSL10_FLASH_REG_STATUS_HIGH_W_UNLOCKED BIT(2)
62 #define RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED BIT(4)
63 #define RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED BIT(5)
64 #define RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED BIT(6)
65
66 #define RSL10_ROM_CMD_WRITE_WORD_PAIR 0x3C
67 #define RSL10_ROM_CMD_WRITE_BUFFER 0x40
68 #define RSL10_ROM_CMD_ERASE_SECTOR 0x44
69 #define RSL10_ROM_CMD_ERASE_ALL 0x48
70
71 #define FLASH_SECTOR_SIZE 0x2000
72
73 #define RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE FLASH_SECTOR_SIZE
74
75 #define ALGO_STACK_POINTER_ADDR 0x20002000
76
77 /* Used to launch flash related functions from ROM
78 * Params :
79 * r0-r2 = arguments
80 * r3 = target address in rom
81 */
82 static const uint8_t rsl10_rom_launcher_code[] = {
83 #include "../../../contrib/loaders/flash/rsl10/rom_launcher.inc"
84 };
85
86 enum rsl10_flash_status {
87 RSL10_FLASH_ERR_NONE = 0x0,
88 RSL10_FLASH_ERR_GENERAL_FAILURE = 0x1,
89 RSL10_FLASH_ERR_WRITE_NOT_ENABLED = 0x2,
90 RSL10_FLASH_ERR_BAD_ADDRESS = 0x3,
91 RSL10_FLASH_ERR_ERASE_FAILED = 0x4,
92 RSL10_FLASH_ERR_BAD_LENGTH = 0x5,
93 RSL10_FLASH_ERR_INACCESSIBLE = 0x6,
94 RSL10_FLASH_ERR_COPIER_BUSY = 0x7,
95 RSL10_FLASH_ERR_PROG_FAILED = 0x8,
96 RSL10_FLASH_MAX_ERR_CODES /* must be the last one */
97 };
98
99 static const char *const rsl10_error_list[] = {
100 [RSL10_FLASH_ERR_GENERAL_FAILURE] = "general failure",
101 [RSL10_FLASH_ERR_WRITE_NOT_ENABLED] = "write not enabled, protected",
102 [RSL10_FLASH_ERR_BAD_ADDRESS] = "bad address",
103 [RSL10_FLASH_ERR_ERASE_FAILED] = "erase failed",
104 [RSL10_FLASH_ERR_BAD_LENGTH] = "bad length",
105 [RSL10_FLASH_ERR_INACCESSIBLE] = "inaccessible: not powered up, or isolated",
106 [RSL10_FLASH_ERR_COPIER_BUSY] = "copier busy",
107 [RSL10_FLASH_ERR_PROG_FAILED] = "prog failed",
108 };
109
110 const char *rsl10_error(enum rsl10_flash_status x)
111 {
112 if (x >= RSL10_FLASH_MAX_ERR_CODES || !rsl10_error_list[x])
113 return "unknown";
114 return rsl10_error_list[x];
115 }
116
117 const struct flash_driver rsl10_flash;
118
119 struct rsl10_info {
120 unsigned int refcount;
121
122 struct rsl10_bank {
123 struct rsl10_info *chip;
124 bool probed;
125 } bank[5];
126 struct target *target;
127
128 unsigned int flash_size_kb;
129 };
130
131 static bool rsl10_bank_is_probed(const struct flash_bank *bank)
132 {
133 struct rsl10_bank *nbank = bank->driver_priv;
134 assert(nbank);
135 return nbank->probed;
136 }
137
138 static int rsl10_probe(struct flash_bank *bank);
139
140 static int rsl10_get_probed_chip_if_halted(struct flash_bank *bank, struct rsl10_info **chip)
141 {
142 if (bank->target->state != TARGET_HALTED) {
143 LOG_ERROR("Target not halted");
144 return ERROR_TARGET_NOT_HALTED;
145 }
146
147 struct rsl10_bank *nbank = bank->driver_priv;
148 *chip = nbank->chip;
149
150 if (rsl10_bank_is_probed(bank))
151 return ERROR_OK;
152
153 return rsl10_probe(bank);
154 }
155
156 static int rsl10_protect_check(struct flash_bank *bank)
157 {
158 struct rsl10_bank *nbank = bank->driver_priv;
159 struct rsl10_info *chip = nbank->chip;
160
161 assert(chip);
162
163 uint32_t status;
164
165 int retval = target_read_u32(bank->target, RSL10_FLASH_REG_IF_STATUS, &status);
166 if (retval != ERROR_OK)
167 return retval;
168
169 if (bank->base == RSL10_FLASH_ADDRESS_MAIN) {
170 for (unsigned int i = 0; i < bank->num_prot_blocks; i++)
171 bank->prot_blocks[i].is_protected = (status & (1 << i)) ? 0 : 1;
172
173 } else {
174 uint32_t test_bit = 0;
175 switch (bank->base) {
176 case RSL10_FLASH_ADDRESS_NVR1:
177 test_bit = RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED;
178 break;
179 case RSL10_FLASH_ADDRESS_NVR2:
180 test_bit = RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED;
181 break;
182 case RSL10_FLASH_ADDRESS_NVR3:
183 test_bit = RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED;
184 break;
185 default:
186 break;
187 }
188
189 bank->sectors[0].is_protected = (status & test_bit) ? 0 : 1;
190 }
191 return ERROR_OK;
192 }
193
194 static int rsl10_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
195 {
196
197 struct rsl10_info *chip;
198 int retval = rsl10_get_probed_chip_if_halted(bank, &chip);
199 if (retval != ERROR_OK)
200 return retval;
201
202 if (bank->base == RSL10_FLASH_ADDRESS_MAIN) {
203 uint32_t status;
204 retval = target_read_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, &status);
205 if (retval != ERROR_OK)
206 return retval;
207
208 for (unsigned int i = first; i <= last; i++) {
209 if (set)
210 status &= ~(1 << i);
211 else
212 status |= (1 << i);
213 }
214
215 retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, status);
216 if (retval != ERROR_OK)
217 return retval;
218
219 retval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_WRITE_UNLOCK, RSL10_FLASH_KEY_MAIN);
220 if (retval != ERROR_OK)
221 return retval;
222 } else {
223 uint32_t bit = 0;
224 switch (bank->base) {
225 case RSL10_FLASH_ADDRESS_NVR1:
226 bit = RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE;
227 break;
228 case RSL10_FLASH_ADDRESS_NVR2:
229 bit = RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE;
230 break;
231 case RSL10_FLASH_ADDRESS_NVR3:
232 bit = RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE;
233 break;
234 default:
235 break;
236 }
237
238 uint32_t status;
239 retval = target_read_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, &status);
240 if (retval != ERROR_OK)
241 return retval;
242
243 if (set)
244 status &= ~bit;
245 else
246 status |= bit;
247
248 retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, status);
249 if (retval != ERROR_OK)
250 return retval;
251
252 retval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_WRITE_UNLOCK, RSL10_FLASH_KEY_NVR);
253 if (retval != ERROR_OK)
254 return retval;
255 }
256
257 return ERROR_OK;
258 }
259
260 static int rsl10_check_device(struct flash_bank *bank)
261 {
262 uint32_t configid;
263 int retval = target_read_u32(bank->target, RSL10_REG_ID, &configid);
264 if (retval != ERROR_OK)
265 return retval;
266
267 if (configid != RSL10_ID) {
268 LOG_ERROR("This is not supported (RSL10) device, use other flash driver!!!");
269 return ERROR_TARGET_INVALID;
270 }
271 return ERROR_OK;
272 }
273
274 static int rsl10_probe(struct flash_bank *bank)
275 {
276 struct rsl10_bank *nbank = bank->driver_priv;
277 struct rsl10_info *chip = nbank->chip;
278
279 int retval = rsl10_check_device(bank);
280 if (retval != ERROR_OK)
281 return retval;
282
283 unsigned int bank_id;
284 unsigned int num_prot_blocks = 0;
285 switch (bank->base) {
286 case RSL10_FLASH_ADDRESS_MAIN:
287 bank_id = 0;
288 num_prot_blocks = 3;
289 break;
290 case RSL10_FLASH_ADDRESS_NVR1:
291 bank_id = 1;
292 break;
293 case RSL10_FLASH_ADDRESS_NVR2:
294 bank_id = 2;
295 break;
296 case RSL10_FLASH_ADDRESS_NVR3:
297 bank_id = 3;
298 break;
299 default:
300 return ERROR_FAIL;
301 }
302
303 uint32_t flash_page_size = 2048;
304
305 bank->write_start_alignment = 8;
306 bank->write_end_alignment = 8;
307
308 bank->num_sectors = bank->size / flash_page_size;
309 chip->flash_size_kb = bank->size / 1024;
310
311 free(bank->sectors);
312 bank->sectors = NULL;
313
314 bank->sectors = alloc_block_array(0, flash_page_size, bank->num_sectors);
315 if (!bank->sectors)
316 return ERROR_FAIL;
317
318 free(bank->prot_blocks);
319 bank->prot_blocks = NULL;
320
321 if (num_prot_blocks > 0) {
322 bank->num_prot_blocks = num_prot_blocks;
323 bank->prot_blocks = alloc_block_array(0, bank->num_sectors / 3 * flash_page_size, bank->num_prot_blocks);
324 if (!bank->prot_blocks)
325 return ERROR_FAIL;
326 }
327
328 chip->bank[bank_id].probed = true;
329 return ERROR_OK;
330 }
331
332 static int rsl10_auto_probe(struct flash_bank *bank)
333 {
334 if (rsl10_bank_is_probed(bank))
335 return ERROR_OK;
336
337 return rsl10_probe(bank);
338 }
339
340 static int rsl10_ll_flash_erase(struct rsl10_info *chip, uint32_t address)
341 {
342 struct target *target = chip->target;
343 struct working_area *write_algorithm;
344
345 LOG_DEBUG("erasing buffer flash address=0x%" PRIx32, address);
346
347 int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
348 if (retval != ERROR_OK) {
349 LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
350 return ERROR_FAIL;
351 }
352
353 retval =
354 target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
355 if (retval != ERROR_OK)
356 goto free_algorithm;
357
358 struct reg_param reg_params[3];
359 struct armv7m_algorithm armv7m_info;
360 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
361 armv7m_info.core_mode = ARM_MODE_THREAD;
362
363 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* address */
364 init_reg_param(&reg_params[1], "r3", 32, PARAM_OUT); /* cmd */
365 init_reg_param(&reg_params[2], "sp", 32, PARAM_OUT); /* stack pointer */
366
367 buf_set_u32(reg_params[0].value, 0, 32, address);
368 uint32_t cmd;
369 retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_SECTOR, &cmd);
370 if (retval != ERROR_OK)
371 goto free_reg_params;
372 buf_set_u32(reg_params[1].value, 0, 32, cmd);
373 buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);
374
375 retval = target_run_algorithm(
376 target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
377 write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
378 );
379 if (retval != ERROR_OK)
380 goto free_reg_params;
381
382 int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
383 if (algo_ret != RSL10_FLASH_ERR_NONE) {
384 LOG_ERROR("RSL10 ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
385 retval = ERROR_FLASH_SECTOR_NOT_ERASED;
386 }
387
388 free_reg_params:
389 for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
390 destroy_reg_param(&reg_params[i]);
391
392 free_algorithm:
393 target_free_working_area(target, write_algorithm);
394 return retval;
395 }
396
397 static int rsl10_ll_flash_write(struct rsl10_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes)
398 {
399 struct target *target = chip->target;
400 struct working_area *write_algorithm;
401
402 if (bytes == 8) {
403 uint32_t data;
404 data = buf_get_u32(buffer, 0, 32);
405 LOG_DEBUG("Writing 0x%" PRIx32 " to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, data, address, bytes);
406 } else
407 LOG_DEBUG("Writing buffer to flash address=0x%" PRIx32 " bytes=0x%" PRIx32, address, bytes);
408
409 /* allocate working area with flash programming code */
410 int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
411 if (retval != ERROR_OK) {
412 LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
413 return ERROR_FAIL;
414 }
415
416 retval =
417 target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
418 if (retval != ERROR_OK)
419 goto free_algorithm;
420
421 /* memory buffer, rounded down, to be multiple of 8 */
422 uint32_t buffer_avail = target_get_working_area_avail(target) & ~7;
423 uint32_t buffer_size = MIN(RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE, buffer_avail);
424 struct working_area *source;
425 retval = target_alloc_working_area(target, buffer_size, &source);
426 if (retval != ERROR_OK) {
427 LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
428 goto free_algorithm;
429 }
430
431 struct reg_param reg_params[5];
432 struct armv7m_algorithm armv7m_info;
433 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
434 armv7m_info.core_mode = ARM_MODE_THREAD;
435
436 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* start addr, return value */
437 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* length */
438 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* data */
439 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* cmd */
440 init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT); /* stack pointer */
441 buf_set_u32(reg_params[4].value, 0, 32, ALGO_STACK_POINTER_ADDR);
442
443 uint32_t cmd = 0;
444 uint32_t sent_bytes = 0;
445 uint32_t write_address = 0;
446 uint32_t bytes_to_send = 0;
447 uint32_t remaining_bytes = 0;
448
449 retval = target_read_u32(target, RSL10_ROM_CMD_WRITE_BUFFER, &cmd);
450 if (retval != ERROR_OK)
451 goto free_everything;
452
453 while (sent_bytes < bytes) {
454 remaining_bytes = bytes - sent_bytes;
455 bytes_to_send = remaining_bytes >= buffer_size ? buffer_size : remaining_bytes;
456
457 retval = target_write_buffer(target, source->address, bytes_to_send, buffer + sent_bytes);
458 if (retval != ERROR_OK)
459 goto free_everything;
460
461 write_address = address + sent_bytes;
462
463 LOG_DEBUG(
464 "write_address: 0x%" PRIx32 ", words: 0x%" PRIx32 ", source: 0x%" PRIx64 ", cmd: 0x%" PRIx32, write_address,
465 bytes_to_send / 4, source->address, cmd
466 );
467 buf_set_u32(reg_params[0].value, 0, 32, write_address);
468 buf_set_u32(reg_params[1].value, 0, 32, bytes_to_send / 4);
469 buf_set_u32(reg_params[2].value, 0, 32, source->address);
470 buf_set_u32(reg_params[3].value, 0, 32, cmd);
471
472 retval = target_run_algorithm(
473 target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
474 write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
475 );
476 if (retval != ERROR_OK)
477 goto free_everything;
478
479 int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
480 if (algo_ret != RSL10_FLASH_ERR_NONE) {
481 LOG_ERROR("RSL10 WRITE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
482 retval = ERROR_FLASH_OPERATION_FAILED;
483 goto free_everything;
484 }
485
486 sent_bytes += bytes_to_send;
487 }
488
489 free_everything:
490 target_free_working_area(target, source);
491
492 for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
493 destroy_reg_param(&reg_params[i]);
494
495 free_algorithm:
496 target_free_working_area(target, write_algorithm);
497
498 return retval;
499 }
500
501 static int rsl10_mass_erase(struct target *target)
502 {
503 struct working_area *write_algorithm;
504
505 int retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);
506 if (retval != ERROR_OK) {
507 LOG_ERROR("Current working area 0x%x is too small! Increase working area size!", target->working_area_size);
508 return ERROR_FAIL;
509 }
510
511 retval =
512 target_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);
513 if (retval != ERROR_OK)
514 goto free_algorithm;
515
516 struct reg_param reg_params[3];
517 struct armv7m_algorithm armv7m_info;
518 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
519 armv7m_info.core_mode = ARM_MODE_THREAD;
520
521 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* return value */
522 init_reg_param(&reg_params[1], "r3", 32, PARAM_OUT); /* cmd */
523 init_reg_param(&reg_params[2], "sp", 32, PARAM_OUT); /* stack pointer */
524
525 uint32_t cmd;
526 retval = target_read_u32(target, RSL10_ROM_CMD_ERASE_ALL, &cmd);
527 if (retval != ERROR_OK)
528 goto free_reg_params;
529 buf_set_u32(reg_params[1].value, 0, 32, cmd);
530 buf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);
531
532 retval = target_run_algorithm(
533 target, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,
534 write_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info
535 );
536 if (retval != ERROR_OK)
537 goto free_reg_params;
538
539 int algo_ret = buf_get_u32(reg_params[0].value, 0, 32);
540 if (algo_ret != RSL10_FLASH_ERR_NONE) {
541 LOG_ERROR("RSL10 MASS ERASE ERROR: '%s' (%d)", rsl10_error(algo_ret), algo_ret);
542 retval = ERROR_FLASH_OPERATION_FAILED;
543 }
544
545 free_reg_params:
546 for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)
547 destroy_reg_param(&reg_params[i]);
548
549 free_algorithm:
550 target_free_working_area(target, write_algorithm);
551 return retval;
552 }
553
554 static int rsl10_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
555 {
556 struct rsl10_info *chip;
557
558 int retval = rsl10_get_probed_chip_if_halted(bank, &chip);
559 if (retval != ERROR_OK)
560 return retval;
561
562 return rsl10_ll_flash_write(chip, bank->base + offset, buffer, count);
563 }
564
565 static int rsl10_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
566 {
567 LOG_INFO("erase bank: %x, %x", first, last);
568 int retval;
569 struct rsl10_info *chip;
570
571 retval = rsl10_get_probed_chip_if_halted(bank, &chip);
572 if (retval != ERROR_OK)
573 return retval;
574
575 for (unsigned int i = first; i <= last; i++) {
576 retval = rsl10_ll_flash_erase(chip, bank->base + i * 0x800);
577 if (retval != ERROR_OK)
578 return retval;
579 }
580
581 return ERROR_OK;
582 }
583
584 static void rsl10_free_driver_priv(struct flash_bank *bank)
585 {
586 struct rsl10_bank *nbank = bank->driver_priv;
587 struct rsl10_info *chip = nbank->chip;
588 if (!chip)
589 return;
590
591 chip->refcount--;
592 if (chip->refcount == 0) {
593 free(chip);
594 bank->driver_priv = NULL;
595 }
596 }
597
598 static struct rsl10_info *rsl10_get_chip(struct target *target)
599 {
600 struct flash_bank *bank_iter;
601
602 /* iterate over rsl10 banks of same target */
603 for (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {
604 if (bank_iter->driver != &rsl10_flash)
605 continue;
606
607 if (bank_iter->target != target)
608 continue;
609
610 struct rsl10_bank *nbank = bank_iter->driver_priv;
611 if (!nbank)
612 continue;
613
614 if (nbank->chip)
615 return nbank->chip;
616 }
617 return NULL;
618 }
619
620 FLASH_BANK_COMMAND_HANDLER(rsl10_flash_bank_command)
621 {
622 struct rsl10_info *chip = NULL;
623 struct rsl10_bank *nbank = NULL;
624 LOG_INFO("Creating flash @ " TARGET_ADDR_FMT, bank->base);
625
626 switch (bank->base) {
627 case RSL10_FLASH_ADDRESS_MAIN:
628 case RSL10_FLASH_ADDRESS_NVR1:
629 case RSL10_FLASH_ADDRESS_NVR2:
630 case RSL10_FLASH_ADDRESS_NVR3:
631 case RSL10_FLASH_ADDRESS_NVR4:
632 break;
633 default:
634 LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
635 return ERROR_FAIL;
636 }
637
638 chip = rsl10_get_chip(bank->target);
639 if (!chip) {
640 chip = calloc(1, sizeof(*chip));
641 if (!chip)
642 return ERROR_FAIL;
643
644 chip->target = bank->target;
645 }
646
647 switch (bank->base) {
648 case RSL10_FLASH_ADDRESS_MAIN:
649 nbank = &chip->bank[0];
650 break;
651 case RSL10_FLASH_ADDRESS_NVR1:
652 nbank = &chip->bank[1];
653 break;
654 case RSL10_FLASH_ADDRESS_NVR2:
655 nbank = &chip->bank[2];
656 break;
657 case RSL10_FLASH_ADDRESS_NVR3:
658 nbank = &chip->bank[3];
659 break;
660 case RSL10_FLASH_ADDRESS_NVR4:
661 nbank = &chip->bank[4];
662 break;
663 }
664 assert(nbank);
665
666 chip->refcount++;
667 nbank->chip = chip;
668 nbank->probed = false;
669 bank->driver_priv = nbank;
670
671 return ERROR_OK;
672 }
673
674 COMMAND_HANDLER(rsl10_lock_command)
675 {
676 struct target *target = get_current_target(CMD_CTX);
677
678 if (CMD_ARGC != 4)
679 return ERROR_COMMAND_SYNTAX_ERROR;
680
681 struct flash_bank *bank;
682 int retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);
683 if (retval != ERROR_OK)
684 return retval;
685
686 LOG_INFO("Keys used: %s %s %s %s", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2], CMD_ARGV[3]);
687
688 uint32_t user_key[4];
689 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);
690 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);
691 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);
692 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);
693
694 uint8_t write_buffer[6 * 4];
695 target_buffer_set_u32(target, write_buffer, RSL10_KEY_DEBUG_LOCK);
696 target_buffer_set_u32_array(target, &write_buffer[4], 4, user_key);
697 /* pad the end to 64-bit word boundary */
698 memset(&write_buffer[5 * 4], bank->default_padded_value, 4);
699
700 retval = rsl10_erase(bank, 0, 0);
701 if (retval != ERROR_OK)
702 return retval;
703
704 retval = rsl10_write(bank, write_buffer, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer));
705 if (retval != ERROR_OK) {
706 /* erase sector, if write fails, otherwise it can lock debug with wrong keys */
707 return rsl10_erase(bank, 0, 0);
708 }
709
710 command_print(
711 CMD, "****** WARNING ******\n"
712 "rsl10 device has been successfully prepared to lock.\n"
713 "Debug port is locked after restart.\n"
714 "Unlock with 'rsl10_unlock key0 key1 key2 key3'\n"
715 "****** ....... ******\n"
716 );
717
718 return rsl10_protect(bank, true, 0, 0);
719 }
720
721 COMMAND_HANDLER(rsl10_unlock_command)
722 {
723 if (CMD_ARGC != 4)
724 return ERROR_COMMAND_SYNTAX_ERROR;
725
726 struct target *target = get_current_target(CMD_CTX);
727 struct cortex_m_common *cortex_m = target_to_cm(target);
728
729 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
730 struct adiv5_ap *ap = dap_get_ap(dap, 0);
731
732 uint32_t user_key[4];
733 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);
734 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);
735 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);
736 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);
737
738 uint8_t write_buffer1[4 * 4];
739 target_buffer_set_u32_array(target, write_buffer1, 4, user_key);
740 int retval = mem_ap_write_buf(ap, write_buffer1, 4, 4, RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1);
741 if (retval != ERROR_OK) {
742 dap_put_ap(ap);
743 return retval;
744 }
745
746 dap_put_ap(ap);
747
748 uint32_t key;
749 retval = mem_ap_read_atomic_u32(ap, RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING, &key);
750 if (retval != ERROR_OK)
751 return retval;
752 LOG_INFO("mem read: 0x%08" PRIx32, key);
753
754 if (key == RSL10_KEY_DEBUG_LOCK) {
755 retval = command_run_line(CMD_CTX, "reset init");
756 if (retval != ERROR_OK)
757 return retval;
758
759 struct flash_bank *bank;
760 retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);
761 if (retval != ERROR_OK)
762 return retval;
763
764 retval = rsl10_protect(bank, false, 0, 0);
765 if (retval != ERROR_OK)
766 return retval;
767
768 uint8_t write_buffer2[4 * 2];
769 target_buffer_set_u32(target, write_buffer2, 0x1);
770 /* pad the end to 64-bit word boundary */
771 memset(&write_buffer2[4], bank->default_padded_value, 4);
772
773 /* let it fail, because sector is not erased, maybe just erase all? */
774 (void)rsl10_write(bank, write_buffer2, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer2));
775 command_print(CMD, "Debug port is unlocked!");
776 }
777
778 return ERROR_OK;
779 }
780
781 COMMAND_HANDLER(rsl10_mass_erase_command)
782 {
783 if (CMD_ARGC)
784 return ERROR_COMMAND_SYNTAX_ERROR;
785
786 struct target *target = get_current_target(CMD_CTX);
787
788 int retval = rsl10_mass_erase(target);
789 if (retval != ERROR_OK)
790 return retval;
791
792 command_print(CMD, "Mass erase was succesfull!");
793 return ERROR_OK;
794 }
795
796 static const struct command_registration rsl10_exec_command_handlers[] = {
797 {
798 .name = "lock",
799 .handler = rsl10_lock_command,
800 .mode = COMMAND_EXEC,
801 .help = "Lock rsl10 debug, with passed keys",
802 .usage = "key1 key2 key3 key4",
803 },
804 {
805 .name = "unlock",
806 .handler = rsl10_unlock_command,
807 .mode = COMMAND_EXEC,
808 .help = "Unlock rsl10 debug, with passed keys",
809 .usage = "key1 key2 key3 key4",
810 },
811 {
812 .name = "mass_erase",
813 .handler = rsl10_mass_erase_command,
814 .mode = COMMAND_EXEC,
815 .help = "Mass erase all unprotected flash areas",
816 .usage = "",
817 },
818 COMMAND_REGISTRATION_DONE};
819
820 static const struct command_registration rsl10_command_handlers[] = {
821 {
822 .name = "rsl10",
823 .mode = COMMAND_ANY,
824 .help = "rsl10 flash command group",
825 .usage = "",
826 .chain = rsl10_exec_command_handlers,
827 },
828 COMMAND_REGISTRATION_DONE};
829
830 const struct flash_driver rsl10_flash = {
831 .name = "rsl10",
832 .commands = rsl10_command_handlers,
833 .flash_bank_command = rsl10_flash_bank_command,
834 .erase = rsl10_erase,
835 .protect = rsl10_protect,
836 .write = rsl10_write,
837 .read = default_flash_read,
838 .probe = rsl10_probe,
839 .auto_probe = rsl10_auto_probe,
840 .erase_check = default_flash_blank_check,
841 .protect_check = rsl10_protect_check,
842 .free_driver_priv = rsl10_free_driver_priv,
843 };

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)