1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2011 by Andreas Fritiofson *
9 * andreas.fritiofson@gmail.com *
11 * Copyright (C) 2013 by Paul Fertser *
12 * fercerpav@gmail.com *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
26 ***************************************************************************/
33 #include <helper/binarybuffer.h>
34 #include <target/algorithm.h>
35 #include <target/armv7m.h>
37 #define MD_RST_CLK 0x40020000
38 #define MD_PER_CLOCK (MD_RST_CLK + 0x1C)
39 #define MD_PER_CLOCK_EEPROM (1 << 3)
40 #define MD_PER_CLOCK_RST_CLK (1 << 4)
42 #define FLASH_REG_BASE 0x40018000
43 #define FLASH_CMD (FLASH_REG_BASE + 0x00)
44 #define FLASH_ADR (FLASH_REG_BASE + 0x04)
45 #define FLASH_DI (FLASH_REG_BASE + 0x08)
46 #define FLASH_DO (FLASH_REG_BASE + 0x0C)
47 #define FLASH_KEY (FLASH_REG_BASE + 0x10)
49 #define FLASH_NVSTR (1 << 13)
50 #define FLASH_PROG (1 << 12)
51 #define FLASH_MAS1 (1 << 11)
52 #define FLASH_ERASE (1 << 10)
53 #define FLASH_IFREN (1 << 9)
54 #define FLASH_SE (1 << 8)
55 #define FLASH_YE (1 << 7)
56 #define FLASH_XE (1 << 6)
57 #define FLASH_RD (1 << 2)
58 #define FLASH_WR (1 << 1)
59 #define FLASH_CON (1 << 0)
60 #define FLASH_DELAY_MASK (7 << 3)
62 #define KEY 0x8AAA5551
64 struct mdr_flash_bank
{
66 unsigned int mem_type
;
67 unsigned int page_count
;
68 unsigned int sec_count
;
71 /* flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count> */
72 FLASH_BANK_COMMAND_HANDLER(mdr_flash_bank_command
)
74 struct mdr_flash_bank
*mdr_info
;
77 return ERROR_COMMAND_SYNTAX_ERROR
;
79 mdr_info
= malloc(sizeof(struct mdr_flash_bank
));
81 bank
->driver_priv
= mdr_info
;
82 mdr_info
->probed
= false;
83 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[6], mdr_info
->mem_type
);
84 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[7], mdr_info
->page_count
);
85 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[8], mdr_info
->sec_count
);
89 static int mdr_mass_erase(struct flash_bank
*bank
)
91 struct target
*target
= bank
->target
;
92 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
97 retval
= target_read_u32(target
, FLASH_CMD
, &flash_cmd
);
98 if (retval
!= ERROR_OK
)
101 for (i
= 0; i
< mdr_info
->sec_count
; i
++) {
102 retval
= target_write_u32(target
, FLASH_ADR
, i
<< 2);
103 if (retval
!= ERROR_OK
)
106 flash_cmd
|= FLASH_XE
| FLASH_MAS1
| FLASH_ERASE
;
107 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
108 if (retval
!= ERROR_OK
)
110 flash_cmd
|= FLASH_NVSTR
;
111 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
112 if (retval
!= ERROR_OK
)
114 flash_cmd
&= ~FLASH_ERASE
;
115 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
116 if (retval
!= ERROR_OK
)
118 flash_cmd
&= ~(FLASH_XE
| FLASH_MAS1
| FLASH_NVSTR
);
119 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
120 if (retval
!= ERROR_OK
)
127 static int mdr_erase(struct flash_bank
*bank
, unsigned int first
,
130 struct target
*target
= bank
->target
;
131 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
134 uint32_t flash_cmd
, cur_per_clock
;
136 if (bank
->target
->state
!= TARGET_HALTED
) {
137 LOG_ERROR("Target not halted");
138 return ERROR_TARGET_NOT_HALTED
;
141 retval
= target_read_u32(target
, MD_PER_CLOCK
, &cur_per_clock
);
142 if (retval
!= ERROR_OK
)
145 if (!(cur_per_clock
& 0x10)) {
146 LOG_ERROR("Target needs reset before flash operations");
147 return ERROR_FLASH_OPERATION_FAILED
;
150 retval
= target_write_u32(target
, MD_PER_CLOCK
, cur_per_clock
| MD_PER_CLOCK_EEPROM
);
151 if (retval
!= ERROR_OK
)
154 retval
= target_write_u32(target
, FLASH_KEY
, KEY
);
155 if (retval
!= ERROR_OK
)
158 retval
= target_read_u32(target
, FLASH_CMD
, &flash_cmd
);
159 if (retval
!= ERROR_OK
)
160 goto reset_pg_and_lock
;
162 /* Switch on register access */
163 flash_cmd
= (flash_cmd
& FLASH_DELAY_MASK
) | FLASH_CON
;
164 if (mdr_info
->mem_type
)
165 flash_cmd
|= FLASH_IFREN
;
166 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
167 if (retval
!= ERROR_OK
)
168 goto reset_pg_and_lock
;
170 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)) &&
171 !mdr_info
->mem_type
) {
172 retval
= mdr_mass_erase(bank
);
173 goto reset_pg_and_lock
;
176 unsigned int page_size
= bank
->size
/ mdr_info
->page_count
;
177 for (unsigned int i
= first
; i
<= last
; i
++) {
178 for (j
= 0; j
< mdr_info
->sec_count
; j
++) {
179 retval
= target_write_u32(target
, FLASH_ADR
, (i
* page_size
) | (j
<< 2));
180 if (retval
!= ERROR_OK
)
181 goto reset_pg_and_lock
;
183 flash_cmd
|= FLASH_XE
| FLASH_ERASE
;
184 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
185 if (retval
!= ERROR_OK
)
186 goto reset_pg_and_lock
;
187 flash_cmd
|= FLASH_NVSTR
;
188 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
189 if (retval
!= ERROR_OK
)
190 goto reset_pg_and_lock
;
191 flash_cmd
&= ~FLASH_ERASE
;
192 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
193 if (retval
!= ERROR_OK
)
194 goto reset_pg_and_lock
;
195 flash_cmd
&= ~(FLASH_XE
| FLASH_NVSTR
);
196 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
197 if (retval
!= ERROR_OK
)
198 goto reset_pg_and_lock
;
203 flash_cmd
&= FLASH_DELAY_MASK
;
204 retval2
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
205 if (retval
== ERROR_OK
)
208 retval2
= target_write_u32(target
, FLASH_KEY
, 0);
209 if (retval
== ERROR_OK
)
215 static int mdr_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
216 uint32_t offset
, uint32_t count
)
218 struct target
*target
= bank
->target
;
219 uint32_t buffer_size
= 16384;
220 struct working_area
*write_algorithm
;
221 struct working_area
*source
;
222 uint32_t address
= bank
->base
+ offset
;
223 struct reg_param reg_params
[5];
224 struct armv7m_algorithm armv7m_info
;
225 int retval
= ERROR_OK
;
227 /* see contrib/loaders/flash/mdr32fx.S for src */
228 static const uint8_t mdr32fx_flash_write_code
[] = {
229 0x07, 0x68, 0x16, 0x68, 0x00, 0x2e, 0x2e, 0xd0, 0x55, 0x68, 0xb5, 0x42,
230 0xf9, 0xd0, 0x2e, 0x68, 0x44, 0x60, 0x86, 0x60, 0x17, 0x4e, 0x37, 0x43,
231 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0, 0x25, 0xf8, 0x15, 0x4e, 0x37, 0x43,
232 0x07, 0x60, 0x0d, 0x26, 0x00, 0xf0, 0x1f, 0xf8, 0x80, 0x26, 0x37, 0x43,
233 0x07, 0x60, 0x3d, 0x26, 0x00, 0xf0, 0x19, 0xf8, 0x80, 0x26, 0xb7, 0x43,
234 0x07, 0x60, 0x0f, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0,
235 0x10, 0xf8, 0x0d, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x04, 0x35, 0x04, 0x34,
236 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46, 0x08, 0x35, 0x55, 0x60, 0x01, 0x39,
237 0x00, 0x29, 0x00, 0xd0, 0xcd, 0xe7, 0x30, 0x46, 0x00, 0xbe, 0x01, 0x3e,
238 0x00, 0x2e, 0xfc, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00,
239 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00
242 /* flash write code */
243 if (target_alloc_working_area(target
, sizeof(mdr32fx_flash_write_code
),
244 &write_algorithm
) != ERROR_OK
) {
245 LOG_WARNING("no working area available, can't do block memory writes");
246 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
249 retval
= target_write_buffer(target
, write_algorithm
->address
,
250 sizeof(mdr32fx_flash_write_code
), mdr32fx_flash_write_code
);
251 if (retval
!= ERROR_OK
)
255 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
257 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
258 if (buffer_size
<= 256) {
259 /* we already allocated the writing code, but failed to get a
260 * buffer, free the algorithm */
261 target_free_working_area(target
, write_algorithm
);
263 LOG_WARNING("no large enough working area available, can't do block memory writes");
264 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
268 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
269 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (32bit) */
270 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
271 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
272 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
274 buf_set_u32(reg_params
[0].value
, 0, 32, FLASH_REG_BASE
);
275 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
276 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
277 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
278 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
280 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
281 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
283 retval
= target_run_flash_async_algorithm(target
, buffer
, count
, 4,
286 source
->address
, source
->size
,
287 write_algorithm
->address
, 0,
290 if (retval
== ERROR_FLASH_OPERATION_FAILED
)
291 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
292 buf_get_u32(reg_params
[4].value
, 0, 32));
294 target_free_working_area(target
, source
);
295 target_free_working_area(target
, write_algorithm
);
297 destroy_reg_param(®_params
[0]);
298 destroy_reg_param(®_params
[1]);
299 destroy_reg_param(®_params
[2]);
300 destroy_reg_param(®_params
[3]);
301 destroy_reg_param(®_params
[4]);
306 static int mdr_write(struct flash_bank
*bank
, const uint8_t *buffer
,
307 uint32_t offset
, uint32_t count
)
309 struct target
*target
= bank
->target
;
310 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
311 uint8_t *new_buffer
= NULL
;
313 if (bank
->target
->state
!= TARGET_HALTED
) {
314 LOG_ERROR("Target not halted");
315 return ERROR_TARGET_NOT_HALTED
;
319 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte alignment", offset
);
320 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
323 /* If there's an odd number of bytes, the data has to be padded. Duplicate
324 * the buffer and use the normal code path with a single block write since
325 * it's probably cheaper than to special case the last odd write using
326 * discrete accesses. */
329 new_buffer
= malloc(count
+ rem
);
331 LOG_ERROR("odd number of bytes to write and no memory for padding buffer");
334 LOG_INFO("odd number of bytes to write, padding with 0xff");
335 buffer
= memcpy(new_buffer
, buffer
, count
);
337 new_buffer
[count
++] = 0xff;
340 uint32_t flash_cmd
, cur_per_clock
;
343 retval
= target_read_u32(target
, MD_PER_CLOCK
, &cur_per_clock
);
344 if (retval
!= ERROR_OK
)
347 if (!(cur_per_clock
& MD_PER_CLOCK_RST_CLK
)) {
348 /* Something's very wrong if the RST_CLK module is not clocked */
349 LOG_ERROR("Target needs reset before flash operations");
350 retval
= ERROR_FLASH_OPERATION_FAILED
;
354 retval
= target_write_u32(target
, MD_PER_CLOCK
, cur_per_clock
| MD_PER_CLOCK_EEPROM
);
355 if (retval
!= ERROR_OK
)
358 retval
= target_write_u32(target
, FLASH_KEY
, KEY
);
359 if (retval
!= ERROR_OK
)
362 retval
= target_read_u32(target
, FLASH_CMD
, &flash_cmd
);
363 if (retval
!= ERROR_OK
)
364 goto reset_pg_and_lock
;
366 /* Switch on register access */
367 flash_cmd
= (flash_cmd
& FLASH_DELAY_MASK
) | FLASH_CON
;
368 if (mdr_info
->mem_type
)
369 flash_cmd
|= FLASH_IFREN
;
370 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
371 if (retval
!= ERROR_OK
)
372 goto reset_pg_and_lock
;
374 /* try using block write */
375 retval
= mdr_write_block(bank
, buffer
, offset
, count
/4);
377 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
378 /* if block write failed (no sufficient working area),
379 * we use normal (slow) single halfword accesses */
380 LOG_WARNING("Can't use block writes, falling back to single memory accesses");
382 unsigned int page_size
= bank
->size
/ mdr_info
->page_count
;
383 unsigned int page_mask
= page_size
- 1;
386 unsigned int cur_page
= offset
& ~page_mask
;
387 unsigned int bytes_to_write
= cur_page
+ page_size
- offset
;
388 if (count
< bytes_to_write
)
389 bytes_to_write
= count
;
391 /*LOG_INFO("Selecting next page: %08x", cur_page);*/
393 for (i
= 0; i
< mdr_info
->sec_count
; i
++) {
394 retval
= target_write_u32(target
, FLASH_ADR
, offset
+ i
*4);
395 if (retval
!= ERROR_OK
)
396 goto reset_pg_and_lock
;
397 /*LOG_INFO("Selecting page/sector: %08x", offset + i*4);*/
399 flash_cmd
|= FLASH_XE
| FLASH_PROG
;
400 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
401 if (retval
!= ERROR_OK
)
402 goto reset_pg_and_lock
;
404 flash_cmd
|= FLASH_NVSTR
;
405 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
406 if (retval
!= ERROR_OK
)
407 goto reset_pg_and_lock
;
410 (((offset
+ j
+ i
*4) & ~page_mask
) == cur_page
) &&
412 j
+= mdr_info
->sec_count
*4) {
414 memcpy(&value
, buffer
+ j
+ i
*4, sizeof(uint32_t));
415 retval
= target_write_u32(target
, FLASH_DI
, value
);
416 if (retval
!= ERROR_OK
)
417 goto reset_pg_and_lock
;
418 /*LOG_INFO("Writing to addr %08x", offset + j + i*4);*/
419 retval
= target_write_u32(target
, FLASH_ADR
, offset
+ j
+ i
*4);
420 if (retval
!= ERROR_OK
)
421 goto reset_pg_and_lock
;
423 flash_cmd
|= FLASH_YE
;
424 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
425 if (retval
!= ERROR_OK
)
426 goto reset_pg_and_lock
;
427 flash_cmd
&= ~FLASH_YE
;
428 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
429 if (retval
!= ERROR_OK
)
430 goto reset_pg_and_lock
;
432 flash_cmd
&= ~FLASH_NVSTR
;
433 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
434 if (retval
!= ERROR_OK
)
435 goto reset_pg_and_lock
;
437 flash_cmd
&= ~(FLASH_XE
| FLASH_PROG
);
438 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
439 if (retval
!= ERROR_OK
)
440 goto reset_pg_and_lock
;
443 buffer
+= bytes_to_write
;
444 offset
+= bytes_to_write
;
445 count
-= bytes_to_write
;
450 flash_cmd
&= FLASH_DELAY_MASK
;
451 retval2
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
452 if (retval
== ERROR_OK
)
455 retval2
= target_write_u32(target
, FLASH_KEY
, 0);
456 if (retval
== ERROR_OK
)
462 /* read some bytes bytes to flush buffer in flash accelerator.
463 * See errata for 1986VE1T and 1986VE3. Error 0007 */
464 if ((retval
== ERROR_OK
) && (!mdr_info
->mem_type
)) {
466 target_checksum_memory(bank
->target
, bank
->base
, 64, &tmp
);
472 static int mdr_read(struct flash_bank
*bank
, uint8_t *buffer
,
473 uint32_t offset
, uint32_t count
)
475 struct target
*target
= bank
->target
;
476 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
479 if (!mdr_info
->mem_type
)
480 return default_flash_read(bank
, buffer
, offset
, count
);
482 if (bank
->target
->state
!= TARGET_HALTED
) {
483 LOG_ERROR("Target not halted");
484 return ERROR_TARGET_NOT_HALTED
;
488 LOG_ERROR("offset 0x%" PRIx32
" breaks required 4-byte alignment", offset
);
489 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
493 LOG_ERROR("count 0x%" PRIx32
" breaks required 4-byte alignment", count
);
494 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
497 uint32_t flash_cmd
, cur_per_clock
;
499 retval
= target_read_u32(target
, MD_PER_CLOCK
, &cur_per_clock
);
500 if (retval
!= ERROR_OK
)
503 if (!(cur_per_clock
& MD_PER_CLOCK_RST_CLK
)) {
504 /* Something's very wrong if the RST_CLK module is not clocked */
505 LOG_ERROR("Target needs reset before flash operations");
506 retval
= ERROR_FLASH_OPERATION_FAILED
;
510 retval
= target_write_u32(target
, MD_PER_CLOCK
, cur_per_clock
| MD_PER_CLOCK_EEPROM
);
511 if (retval
!= ERROR_OK
)
514 retval
= target_write_u32(target
, FLASH_KEY
, KEY
);
515 if (retval
!= ERROR_OK
)
518 retval
= target_read_u32(target
, FLASH_CMD
, &flash_cmd
);
519 if (retval
!= ERROR_OK
)
522 /* Switch on register access */
523 flash_cmd
= (flash_cmd
& FLASH_DELAY_MASK
) | FLASH_CON
| FLASH_IFREN
;
524 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
525 if (retval
!= ERROR_OK
)
526 goto reset_pg_and_lock
;
528 for (uint32_t i
= 0; i
< count
; i
+= 4) {
529 retval
= target_write_u32(target
, FLASH_ADR
, offset
+ i
);
530 if (retval
!= ERROR_OK
)
531 goto reset_pg_and_lock
;
533 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
|
534 FLASH_XE
| FLASH_YE
| FLASH_SE
);
535 if (retval
!= ERROR_OK
)
536 goto reset_pg_and_lock
;
539 retval
= target_read_u32(target
, FLASH_DO
, &buf
);
540 if (retval
!= ERROR_OK
)
541 goto reset_pg_and_lock
;
543 buf_set_u32(buffer
, i
* 8, 32, buf
);
545 retval
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
546 if (retval
!= ERROR_OK
)
547 goto reset_pg_and_lock
;
552 flash_cmd
&= FLASH_DELAY_MASK
;
553 retval2
= target_write_u32(target
, FLASH_CMD
, flash_cmd
);
554 if (retval
== ERROR_OK
)
558 retval2
= target_write_u32(target
, FLASH_KEY
, 0);
559 if (retval
== ERROR_OK
)
566 static int mdr_probe(struct flash_bank
*bank
)
568 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
569 unsigned int page_count
, page_size
, i
;
571 page_count
= mdr_info
->page_count
;
572 page_size
= bank
->size
/ page_count
;
576 bank
->num_sectors
= page_count
;
577 bank
->sectors
= malloc(sizeof(struct flash_sector
) * page_count
);
579 for (i
= 0; i
< page_count
; i
++) {
580 bank
->sectors
[i
].offset
= i
* page_size
;
581 bank
->sectors
[i
].size
= page_size
;
582 bank
->sectors
[i
].is_erased
= -1;
583 bank
->sectors
[i
].is_protected
= 0;
586 mdr_info
->probed
= true;
591 static int mdr_auto_probe(struct flash_bank
*bank
)
593 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
594 if (mdr_info
->probed
)
596 return mdr_probe(bank
);
599 static int get_mdr_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
601 struct mdr_flash_bank
*mdr_info
= bank
->driver_priv
;
602 command_print_sameline(cmd
, "MDR32Fx - %s",
603 mdr_info
->mem_type
? "info memory" : "main memory");
608 const struct flash_driver mdr_flash
= {
610 .usage
= "flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count>\n"
611 "<type>: 0 for main memory, 1 for info memory",
612 .flash_bank_command
= mdr_flash_bank_command
,
617 .auto_probe
= mdr_auto_probe
,
618 .erase_check
= default_flash_blank_check
,
619 .info
= get_mdr_info
,
620 .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)