1 /***************************************************************************
2 * Copyright (C) 2007-2008 by unsik Kim <donari75@gmail.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
25 #include "time_support.h"
30 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
);
31 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
32 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
);
33 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
35 static command_t
*mflash_cmd
;
37 static mflash_bank_t
*mflash_bank
;
39 static mflash_gpio_drv_t pxa270_gpio
= {
41 .set_gpio_to_output
= pxa270_set_gpio_to_output
,
42 .set_gpio_output_val
= pxa270_set_gpio_output_val
45 static mflash_gpio_drv_t s3c2440_gpio
= {
47 .set_gpio_to_output
= s3c2440_set_gpio_to_output
,
48 .set_gpio_output_val
= s3c2440_set_gpio_output_val
51 static mflash_gpio_drv_t
*mflash_gpio
[] =
58 #define PXA270_GAFR0_L 0x40E00054
59 #define PXA270_GAFR3_U 0x40E00070
60 #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
61 #define PXA270_GPDR0 0x40E0000C
62 #define PXA270_GPDR3 0x40E0010C
63 #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
64 #define PXA270_GPSR0 0x40E00018
65 #define PXA270_GPCR0 0x40E00024
67 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
)
69 u32 addr
, value
, mask
;
70 target_t
*target
= mflash_bank
->target
;
73 /* remove alternate function. */
74 mask
= 0x3u
<< (gpio
.num
& 0xF)*2;
76 addr
= PXA270_GAFR0_L
+ (gpio
.num
>> 4) * 4;
78 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
82 if (addr
== PXA270_GAFR3_U
)
83 value
&= ~PXA270_GAFR3_U_RESERVED_BITS
;
85 if ((ret
= target_write_u32(target
, addr
, value
)) != ERROR_OK
)
88 /* set direction to output */
89 mask
= 0x1u
<< (gpio
.num
& 0x1F);
91 addr
= PXA270_GPDR0
+ (gpio
.num
>> 5) * 4;
93 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
97 if (addr
== PXA270_GPDR3
)
98 value
&= ~PXA270_GPDR3_RESERVED_BITS
;
100 ret
= target_write_u32(target
, addr
, value
);
104 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
106 u32 addr
, value
, mask
;
107 target_t
*target
= mflash_bank
->target
;
110 mask
= 0x1u
<< (gpio
.num
& 0x1F);
113 addr
= PXA270_GPSR0
+ (gpio
.num
>> 5) * 4;
115 addr
= PXA270_GPCR0
+ (gpio
.num
>> 5) * 4;
118 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
123 ret
= target_write_u32(target
, addr
, value
);
128 #define S3C2440_GPACON 0x56000000
129 #define S3C2440_GPADAT 0x56000004
130 #define S3C2440_GPJCON 0x560000d0
131 #define S3C2440_GPJDAT 0x560000d4
133 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
)
135 u32 data
, mask
, gpio_con
;
136 target_t
*target
= mflash_bank
->target
;
139 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
140 gpio_con
= S3C2440_GPACON
+ (gpio
.port
[0] - 'a') * 0x10;
141 } else if (gpio
.port
[0] == 'j') {
142 gpio_con
= S3C2440_GPJCON
;
144 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
145 return ERROR_INVALID_ARGUMENTS
;
148 ret
= target_read_u32(target
, gpio_con
, &data
);
150 if (ret
== ERROR_OK
) {
151 if (gpio
.port
[0] == 'a') {
152 mask
= 1 << gpio
.num
;
155 mask
= 3 << gpio
.num
* 2;
157 data
|= (1 << gpio
.num
* 2);
160 ret
= target_write_u32(target
, gpio_con
, data
);
165 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
167 u32 data
, mask
, gpio_dat
;
168 target_t
*target
= mflash_bank
->target
;
171 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
172 gpio_dat
= S3C2440_GPADAT
+ (gpio
.port
[0] - 'a') * 0x10;
173 } else if (gpio
.port
[0] == 'j') {
174 gpio_dat
= S3C2440_GPJDAT
;
176 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
177 return ERROR_INVALID_ARGUMENTS
;
180 ret
= target_read_u32(target
, gpio_dat
, &data
);
182 if (ret
== ERROR_OK
) {
183 mask
= 1 << gpio
.num
;
189 ret
= target_write_u32(target
, gpio_dat
, data
);
194 static int mg_hdrst(u8 level
)
196 return mflash_bank
->gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, level
);
199 static int mg_init_gpio (void)
201 mflash_gpio_drv_t
*gpio_drv
= mflash_bank
->gpio_drv
;
203 gpio_drv
->set_gpio_to_output(mflash_bank
->rst_pin
);
204 gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, 1);
209 static int mg_dsk_wait(mg_io_type_wait wait
, u32 time
)
212 target_t
*target
= mflash_bank
->target
;
213 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
217 duration_start_measure(&duration
);
221 target_read_u8(target
, mg_task_reg
+ MG_REG_STATUS
, &status
);
223 if (status
& mg_io_rbit_status_busy
)
225 if (wait
== mg_io_wait_bsy
)
230 case mg_io_wait_not_bsy
:
232 case mg_io_wait_rdy_noerr
:
233 if (status
& mg_io_rbit_status_ready
)
236 case mg_io_wait_drq_noerr
:
237 if (status
& mg_io_rbit_status_data_req
)
244 /* Now we check the error condition! */
245 if (status
& mg_io_rbit_status_error
)
247 target_read_u8(target
, mg_task_reg
+ MG_REG_ERROR
, &error
);
249 if (error
& mg_io_rbit_err_bad_sect_num
) {
250 LOG_ERROR("sector not found");
253 else if (error
& (mg_io_rbit_err_bad_block
| mg_io_rbit_err_uncorrectable
)) {
254 LOG_ERROR("bad block");
257 LOG_ERROR("disk operation fail");
265 if (status
& mg_io_rbit_status_ready
)
269 if (status
& mg_io_rbit_status_data_req
)
277 duration_stop_measure(&duration
, NULL
);
279 t
=duration
.duration
.tv_usec
/1000;
280 t
+=duration
.duration
.tv_sec
*1000;
286 LOG_ERROR("timeout occured");
290 static int mg_dsk_srst(u8 on
)
292 target_t
*target
= mflash_bank
->target
;
293 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
297 if ((ret
= target_read_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, &value
)) != ERROR_OK
)
301 value
|= (mg_io_rbit_devc_srst
);
303 value
&= ~mg_io_rbit_devc_srst
;
306 ret
= target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, value
);
310 static int mg_dsk_io_cmd(u32 sect_num
, u32 cnt
, u8 cmd
)
312 target_t
*target
= mflash_bank
->target
;
313 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
316 if (mg_dsk_wait(mg_io_wait_rdy_noerr
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
319 value
= mg_io_rval_dev_drv_master
| mg_io_rval_dev_lba_mode
|((sect_num
>> 24) & 0xf);
321 target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_HEAD
, value
);
322 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_CNT
, (u8
)cnt
);
323 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_NUM
, (u8
)sect_num
);
324 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_LOW
, (u8
)(sect_num
>> 8));
325 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_HIGH
, (u8
)(sect_num
>> 16));
327 target_write_u8(target
, mg_task_reg
+ MG_REG_COMMAND
, cmd
);
332 static int mg_dsk_drv_info(void)
334 target_t
*target
= mflash_bank
->target
;
335 u32 mg_buff
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
337 if ( mg_dsk_io_cmd(0, 1, mg_io_cmd_identify
) != ERROR_OK
)
340 if ( mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
343 LOG_INFO("read drive info.");
345 if (! mflash_bank
->drv_info
)
346 mflash_bank
->drv_info
= malloc(sizeof(mg_drv_info_t
));
348 target
->type
->read_memory(target
, mg_buff
, 2, sizeof(mg_io_type_drv_info
) >> 1,
349 (u8
*)&mflash_bank
->drv_info
->drv_id
);
351 mflash_bank
->drv_info
->tot_sects
= (u32
)(mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_hi
<< 16)
352 + mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_lo
;
354 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
359 static int mg_mflash_probe(void)
363 LOG_INFO("reset mflash");
367 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
372 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
377 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
382 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
385 if (mg_dsk_drv_info() != ERROR_OK
)
391 static int mg_probe_cmd(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
395 ret
= mg_mflash_probe();
397 if (ret
== ERROR_OK
) {
398 command_print(cmd_ctx
, "mflash (total %u sectors) found at 0x%8.8x",
399 mflash_bank
->drv_info
->tot_sects
, mflash_bank
->base
);
405 static int mg_mflash_do_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
409 target_t
*target
= mflash_bank
->target
;
413 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_read
) != ERROR_OK
)
416 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
418 duration_start_measure(&duration
);
420 for (i
= 0; i
< sect_cnt
; i
++) {
421 mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
423 target
->type
->read_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
424 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
426 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
428 LOG_DEBUG("%u (0x%8.8x) sector read", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
430 duration_stop_measure(&duration
, NULL
);
432 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
433 LOG_INFO("read %u'th sectors", sect_num
+ i
);
434 duration_start_measure(&duration
);
438 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
443 static int mg_mflash_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
445 u32 quotient
, residue
, i
;
448 quotient
= sect_cnt
>> 8;
449 residue
= sect_cnt
% 256;
451 for (i
= 0; i
< quotient
; i
++) {
452 LOG_DEBUG("sect num : %u buff : 0x%0lx", sect_num
,
453 (unsigned long)buff_ptr
);
454 mg_mflash_do_read_sects(buff_ptr
, sect_num
, 256);
456 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
460 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
461 (unsigned long)buff_ptr
);
462 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
468 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
472 target_t
*target
= mflash_bank
->target
;
476 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
477 LOG_ERROR("mg_io_cmd_write fail");
481 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
483 duration_start_measure(&duration
);
485 for (i
= 0; i
< sect_cnt
; i
++) {
486 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
488 LOG_ERROR("mg_io_wait_drq time out");
490 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
492 LOG_ERROR("mem write error");
493 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
495 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
497 LOG_ERROR("mg_io_cmd_confirm_write error");
499 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
501 duration_stop_measure(&duration
, NULL
);
503 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
504 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
505 duration_start_measure(&duration
);
509 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
514 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
516 u32 quotient
, residue
, i
;
519 quotient
= sect_cnt
>> 8;
520 residue
= sect_cnt
% 256;
522 for (i
= 0; i
< quotient
; i
++) {
523 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
524 (unsigned long)buff_ptr
);
525 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
527 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
531 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
532 (unsigned long)buff_ptr
);
533 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
539 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
541 u8
*sect_buff
, *buff_ptr
= buff
;
542 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
546 end_addr
= addr
+ len
;
548 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
550 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
552 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
553 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
554 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
556 if (end_addr
< next_sec_addr
) {
557 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
558 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
561 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
562 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
563 buff_ptr
+= (next_sec_addr
- cur_addr
);
564 cur_addr
= next_sec_addr
;
568 if (cur_addr
< end_addr
) {
570 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
571 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
573 while (next_sec_addr
<= end_addr
) {
575 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
579 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
581 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
582 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
584 if (cur_addr
< end_addr
) {
586 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
587 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
588 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
589 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
599 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
601 u8
*sect_buff
, *buff_ptr
= buff
;
602 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
606 end_addr
= addr
+ len
;
608 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
610 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
612 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
613 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
614 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
616 if (end_addr
< next_sec_addr
) {
617 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
618 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
621 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
622 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
623 buff_ptr
+= (next_sec_addr
- cur_addr
);
624 cur_addr
= next_sec_addr
;
627 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
630 if (cur_addr
< end_addr
) {
632 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
633 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
635 while (next_sec_addr
<= end_addr
) {
637 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
641 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
643 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
644 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
646 if (cur_addr
< end_addr
) {
648 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
649 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
650 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
651 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
652 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
661 static int mg_write_cmd(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
663 u32 address
, buf_cnt
;
665 /* TODO : multi-bank support, large file support */
672 return ERROR_COMMAND_SYNTAX_ERROR
;
675 address
= strtoul(args
[2], NULL
, 0);
677 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
681 buffer
= malloc(fileio
.size
);
683 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
686 fileio_close(&fileio
);
690 duration_start_measure(&duration
);
692 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
694 duration_stop_measure(&duration
, &duration_text
);
696 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
697 fileio
.size
, args
[1], duration_text
,
698 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
702 fileio_close(&fileio
);
709 static int mg_dump_cmd(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
711 u32 address
, size_written
, size
;
713 /* TODO : multi-bank support */
719 return ERROR_COMMAND_SYNTAX_ERROR
;
722 address
= strtoul(args
[2], NULL
, 0);
723 size
= strtoul(args
[3], NULL
, 0);
725 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
729 buffer
= malloc(size
);
731 duration_start_measure(&duration
);
733 mg_mflash_read(address
, buffer
, size
);
735 duration_stop_measure(&duration
, &duration_text
);
737 fileio_write(&fileio
, size
, buffer
, &size_written
);
739 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
740 address
, size
, args
[1], duration_text
,
741 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
745 fileio_close(&fileio
);
752 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
755 register_command(cmd_ctx
, mflash_cmd
, "probe", mg_probe_cmd
, COMMAND_EXEC
, NULL
);
756 register_command(cmd_ctx
, mflash_cmd
, "write", mg_write_cmd
, COMMAND_EXEC
,
757 "mflash write <num> <file> <address>");
758 register_command(cmd_ctx
, mflash_cmd
, "dump", mg_dump_cmd
, COMMAND_EXEC
,
759 "mflash dump <num> <file> <address> <size>");
765 static int mg_bank_cmd(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
773 return ERROR_COMMAND_SYNTAX_ERROR
;
776 if ((target
= get_target(args
[3])) == NULL
)
778 LOG_ERROR("target '%s' not defined", args
[3]);
782 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
783 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
784 mflash_bank
->rst_pin
.num
= strtoul(args
[2], &str
, 0);
786 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
788 mflash_bank
->target
= target
;
790 for (i
= 0; mflash_gpio
[i
] ; i
++) {
791 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
792 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
796 if (! mflash_bank
->gpio_drv
) {
797 LOG_ERROR("%s is unsupported soc", args
[0]);
798 return ERROR_INVALID_ARGUMENTS
;
804 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
806 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
807 register_command(cmd_ctx
, mflash_cmd
, "bank", mg_bank_cmd
, COMMAND_CONFIG
,
808 "mflash bank <soc> <base> <RST pin> <target #>");
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)