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 ***************************************************************************/
35 #include "time_support.h"
39 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
);
40 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
41 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
);
42 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
44 static command_t
*mflash_cmd
;
46 static mflash_bank_t
*mflash_bank
;
48 static mflash_gpio_drv_t pxa270_gpio
= {
50 .set_gpio_to_output
= pxa270_set_gpio_to_output
,
51 .set_gpio_output_val
= pxa270_set_gpio_output_val
54 static mflash_gpio_drv_t s3c2440_gpio
= {
56 .set_gpio_to_output
= s3c2440_set_gpio_to_output
,
57 .set_gpio_output_val
= s3c2440_set_gpio_output_val
60 static mflash_gpio_drv_t
*mflash_gpio
[] =
67 #define PXA270_GAFR0_L 0x40E00054
68 #define PXA270_GAFR3_U 0x40E00070
69 #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
70 #define PXA270_GPDR0 0x40E0000C
71 #define PXA270_GPDR3 0x40E0010C
72 #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
73 #define PXA270_GPSR0 0x40E00018
74 #define PXA270_GPCR0 0x40E00024
76 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
)
78 u32 addr
, value
, mask
;
79 target_t
*target
= mflash_bank
->target
;
82 /* remove alternate function. */
83 mask
= 0x3u
<< (gpio
.num
& 0xF)*2;
85 addr
= PXA270_GAFR0_L
+ (gpio
.num
>> 4) * 4;
87 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
91 if (addr
== PXA270_GAFR3_U
)
92 value
&= ~PXA270_GAFR3_U_RESERVED_BITS
;
94 if ((ret
= target_write_u32(target
, addr
, value
)) != ERROR_OK
)
97 /* set direction to output */
98 mask
= 0x1u
<< (gpio
.num
& 0x1F);
100 addr
= PXA270_GPDR0
+ (gpio
.num
>> 5) * 4;
102 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
106 if (addr
== PXA270_GPDR3
)
107 value
&= ~PXA270_GPDR3_RESERVED_BITS
;
109 ret
= target_write_u32(target
, addr
, value
);
113 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
115 u32 addr
, value
, mask
;
116 target_t
*target
= mflash_bank
->target
;
119 mask
= 0x1u
<< (gpio
.num
& 0x1F);
122 addr
= PXA270_GPSR0
+ (gpio
.num
>> 5) * 4;
124 addr
= PXA270_GPCR0
+ (gpio
.num
>> 5) * 4;
127 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
132 ret
= target_write_u32(target
, addr
, value
);
137 #define S3C2440_GPACON 0x56000000
138 #define S3C2440_GPADAT 0x56000004
139 #define S3C2440_GPJCON 0x560000d0
140 #define S3C2440_GPJDAT 0x560000d4
142 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
)
144 u32 data
, mask
, gpio_con
;
145 target_t
*target
= mflash_bank
->target
;
148 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
149 gpio_con
= S3C2440_GPACON
+ (gpio
.port
[0] - 'a') * 0x10;
150 } else if (gpio
.port
[0] == 'j') {
151 gpio_con
= S3C2440_GPJCON
;
153 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
154 return ERROR_INVALID_ARGUMENTS
;
157 ret
= target_read_u32(target
, gpio_con
, &data
);
159 if (ret
== ERROR_OK
) {
160 if (gpio
.port
[0] == 'a') {
161 mask
= 1 << gpio
.num
;
164 mask
= 3 << gpio
.num
* 2;
166 data
|= (1 << gpio
.num
* 2);
169 ret
= target_write_u32(target
, gpio_con
, data
);
174 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
176 u32 data
, mask
, gpio_dat
;
177 target_t
*target
= mflash_bank
->target
;
180 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
181 gpio_dat
= S3C2440_GPADAT
+ (gpio
.port
[0] - 'a') * 0x10;
182 } else if (gpio
.port
[0] == 'j') {
183 gpio_dat
= S3C2440_GPJDAT
;
185 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
186 return ERROR_INVALID_ARGUMENTS
;
189 ret
= target_read_u32(target
, gpio_dat
, &data
);
191 if (ret
== ERROR_OK
) {
192 mask
= 1 << gpio
.num
;
198 ret
= target_write_u32(target
, gpio_dat
, data
);
203 static int mflash_rst(u8 level
)
205 return mflash_bank
->gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, level
);
208 static int mflash_init_gpio (void)
210 mflash_gpio_drv_t
*gpio_drv
= mflash_bank
->gpio_drv
;
212 gpio_drv
->set_gpio_to_output(mflash_bank
->rst_pin
);
213 gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, 1);
215 if (mflash_bank
->wp_pin
.num
!= -1) {
216 gpio_drv
->set_gpio_to_output(mflash_bank
->wp_pin
);
217 gpio_drv
->set_gpio_output_val(mflash_bank
->wp_pin
, 1);
220 if (mflash_bank
->dpd_pin
.num
!= -1) {
221 gpio_drv
->set_gpio_to_output(mflash_bank
->dpd_pin
);
222 gpio_drv
->set_gpio_output_val(mflash_bank
->dpd_pin
, 1);
228 static int mg_dsk_wait(mg_io_type_wait wait
, u32 time
)
231 target_t
*target
= mflash_bank
->target
;
232 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
236 duration_start_measure(&duration
);
240 target_read_u8(target
, mg_task_reg
+ MG_REG_STATUS
, &status
);
242 if (status
& mg_io_rbit_status_busy
)
244 if (wait
== mg_io_wait_bsy
)
249 case mg_io_wait_not_bsy
:
251 case mg_io_wait_rdy_noerr
:
252 if (status
& mg_io_rbit_status_ready
)
255 case mg_io_wait_drq_noerr
:
256 if (status
& mg_io_rbit_status_data_req
)
263 /* Now we check the error condition! */
264 if (status
& mg_io_rbit_status_error
)
266 target_read_u8(target
, mg_task_reg
+ MG_REG_ERROR
, &error
);
268 if (error
& mg_io_rbit_err_bad_sect_num
) {
269 LOG_ERROR("sector not found");
272 else if (error
& (mg_io_rbit_err_bad_block
| mg_io_rbit_err_uncorrectable
)) {
273 LOG_ERROR("bad block");
276 LOG_ERROR("disk operation fail");
284 if (status
& mg_io_rbit_status_ready
)
288 if (status
& mg_io_rbit_status_data_req
)
296 duration_stop_measure(&duration
, NULL
);
298 t
=duration
.duration
.tv_usec
/1000;
299 t
+=duration
.duration
.tv_sec
*1000;
305 LOG_ERROR("timeout occured");
309 static int mg_dsk_srst(u8 on
)
311 target_t
*target
= mflash_bank
->target
;
312 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
316 if ((ret
= target_read_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, &value
)) != ERROR_OK
)
320 value
|= (mg_io_rbit_devc_srst
);
322 value
&= ~mg_io_rbit_devc_srst
;
325 ret
= target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, value
);
329 static int mg_dsk_io_cmd(u32 sect_num
, u32 cnt
, u8 cmd
)
331 target_t
*target
= mflash_bank
->target
;
332 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
335 if (mg_dsk_wait(mg_io_wait_rdy_noerr
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
338 value
= mg_io_rval_dev_drv_master
| mg_io_rval_dev_lba_mode
|((sect_num
>> 24) & 0xf);
340 target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_HEAD
, value
);
341 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_CNT
, (u8
)cnt
);
342 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_NUM
, (u8
)sect_num
);
343 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_LOW
, (u8
)(sect_num
>> 8));
344 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_HIGH
, (u8
)(sect_num
>> 16));
346 target_write_u8(target
, mg_task_reg
+ MG_REG_COMMAND
, cmd
);
351 static int mg_dsk_drv_info(void)
353 target_t
*target
= mflash_bank
->target
;
354 u32 mg_buff
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
356 if ( mg_dsk_io_cmd(0, 1, mg_io_cmd_identify
) != ERROR_OK
)
359 if ( mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
362 LOG_INFO("read drive info.");
364 if (! mflash_bank
->drv_info
)
365 mflash_bank
->drv_info
= malloc(sizeof(mg_drv_info_t
));
367 target
->type
->read_memory(target
, mg_buff
, 2, sizeof(mg_io_type_drv_info
) >> 1,
368 (u8
*)&mflash_bank
->drv_info
->drv_id
);
370 mflash_bank
->drv_info
->tot_sects
= (u32
)(mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_hi
<< 16)
371 + mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_lo
;
373 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
378 static int mg_mflash_probe(void)
380 mflash_bank
->proved
= 0;
384 LOG_INFO("reset mflash");
388 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
393 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
398 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
403 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
406 if (mg_dsk_drv_info() != ERROR_OK
)
409 mflash_bank
->proved
= 1;
414 static int mflash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
418 ret
= mg_mflash_probe();
420 if (ret
== ERROR_OK
) {
421 command_print(cmd_ctx
, "mflash (total %u sectors) found at 0x%8.8x",
422 mflash_bank
->drv_info
->tot_sects
, mflash_bank
->base
);
428 static int mg_mflash_do_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
432 target_t
*target
= mflash_bank
->target
;
436 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_read
) != ERROR_OK
)
439 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
441 duration_start_measure(&duration
);
443 for (i
= 0; i
< sect_cnt
; i
++) {
444 mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
446 target
->type
->read_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
447 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
449 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
451 LOG_DEBUG("%u (0x%8.8x) sector read", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
453 duration_stop_measure(&duration
, NULL
);
455 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
456 LOG_INFO("read %u'th sectors", sect_num
+ i
);
457 duration_start_measure(&duration
);
461 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
466 static int mg_mflash_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
468 u32 quotient
, residue
, i
;
471 quotient
= sect_cnt
>> 8;
472 residue
= sect_cnt
% 256;
474 for (i
= 0; i
< quotient
; i
++) {
475 LOG_DEBUG("sect num : %u buff : 0x%0lx", sect_num
,
476 (unsigned long)buff_ptr
);
477 mg_mflash_do_read_sects(buff_ptr
, sect_num
, 256);
479 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
483 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
484 (unsigned long)buff_ptr
);
485 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
491 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
495 target_t
*target
= mflash_bank
->target
;
499 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
500 LOG_ERROR("mg_io_cmd_write fail");
504 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
506 duration_start_measure(&duration
);
508 for (i
= 0; i
< sect_cnt
; i
++) {
509 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
511 LOG_ERROR("mg_io_wait_drq time out");
513 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
515 LOG_ERROR("mem write error");
516 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
518 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
520 LOG_ERROR("mg_io_cmd_confirm_write error");
522 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
524 duration_stop_measure(&duration
, NULL
);
526 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
527 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
528 duration_start_measure(&duration
);
532 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
537 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
539 u32 quotient
, residue
, i
;
542 quotient
= sect_cnt
>> 8;
543 residue
= sect_cnt
% 256;
545 for (i
= 0; i
< quotient
; i
++) {
546 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
547 (unsigned long)buff_ptr
);
548 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
550 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
554 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
555 (unsigned long)buff_ptr
);
556 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
562 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
564 u8
*sect_buff
, *buff_ptr
= buff
;
565 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
569 end_addr
= addr
+ len
;
571 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
573 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
575 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
576 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
577 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
579 if (end_addr
< next_sec_addr
) {
580 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
581 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
584 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
585 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
586 buff_ptr
+= (next_sec_addr
- cur_addr
);
587 cur_addr
= next_sec_addr
;
591 if (cur_addr
< end_addr
) {
593 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
594 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
596 while (next_sec_addr
<= end_addr
) {
598 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
602 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
604 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
605 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
607 if (cur_addr
< end_addr
) {
609 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
610 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
611 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
612 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
622 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
624 u8
*sect_buff
, *buff_ptr
= buff
;
625 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
629 end_addr
= addr
+ len
;
631 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
633 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
635 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
636 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
637 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
639 if (end_addr
< next_sec_addr
) {
640 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
641 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
644 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
645 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
646 buff_ptr
+= (next_sec_addr
- cur_addr
);
647 cur_addr
= next_sec_addr
;
650 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
653 if (cur_addr
< end_addr
) {
655 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
656 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
658 while (next_sec_addr
<= end_addr
) {
660 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
664 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
666 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
667 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
669 if (cur_addr
< end_addr
) {
671 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
672 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
673 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
674 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
675 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
684 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
686 u32 address
, buf_cnt
;
688 /* TODO : multi-bank support, large file support */
695 return ERROR_COMMAND_SYNTAX_ERROR
;
698 address
= strtoul(args
[2], NULL
, 0);
700 if (! mflash_bank
->proved
) {
704 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
708 buffer
= malloc(fileio
.size
);
710 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
713 fileio_close(&fileio
);
717 duration_start_measure(&duration
);
719 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
721 duration_stop_measure(&duration
, &duration_text
);
723 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
724 fileio
.size
, args
[1], duration_text
,
725 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
729 fileio_close(&fileio
);
736 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
738 u32 address
, size_written
, size
;
740 /* TODO : multi-bank support */
746 return ERROR_COMMAND_SYNTAX_ERROR
;
749 address
= strtoul(args
[2], NULL
, 0);
750 size
= strtoul(args
[3], NULL
, 0);
752 if (! mflash_bank
->proved
) {
756 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
760 buffer
= malloc(size
);
762 duration_start_measure(&duration
);
764 mg_mflash_read(address
, buffer
, size
);
766 duration_stop_measure(&duration
, &duration_text
);
768 fileio_write(&fileio
, size
, buffer
, &size_written
);
770 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
771 address
, size
, args
[1], duration_text
,
772 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
776 fileio_close(&fileio
);
783 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
786 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
787 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
788 "mflash write <num> <file> <address>");
789 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
790 "mflash dump <num> <file> <address> <size>");
796 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
804 return ERROR_COMMAND_SYNTAX_ERROR
;
807 if ((target
= get_target_by_num(strtoul(args
[7], NULL
, 0))) == NULL
)
809 LOG_ERROR("target %lu not defined", strtoul(args
[7], NULL
, 0));
813 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
814 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
815 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
816 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
817 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
819 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
820 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
822 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
823 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
825 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
827 mflash_bank
->target
= target
;
829 for (i
= 0; mflash_gpio
[i
] ; i
++) {
830 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
831 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
835 if (! mflash_bank
->gpio_drv
) {
836 LOG_ERROR("%s is unsupported soc", args
[0]);
837 return ERROR_INVALID_ARGUMENTS
;
843 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
845 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
846 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
847 "mflash bank <soc> <base> <chip_width> <bus_width> <RST pin> <WP pin> <DPD 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)