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 ***************************************************************************/
28 #include <sys/types.h>
36 #include "time_support.h"
40 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
);
41 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
42 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
);
43 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
);
45 static command_t
*mflash_cmd
;
47 static mflash_bank_t
*mflash_bank
;
49 static mflash_gpio_drv_t pxa270_gpio
= {
51 .set_gpio_to_output
= pxa270_set_gpio_to_output
,
52 .set_gpio_output_val
= pxa270_set_gpio_output_val
55 static mflash_gpio_drv_t s3c2440_gpio
= {
57 .set_gpio_to_output
= s3c2440_set_gpio_to_output
,
58 .set_gpio_output_val
= s3c2440_set_gpio_output_val
61 static mflash_gpio_drv_t
*mflash_gpio
[] =
68 #define PXA270_GAFR0_L 0x40E00054
69 #define PXA270_GAFR3_U 0x40E00070
70 #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
71 #define PXA270_GPDR0 0x40E0000C
72 #define PXA270_GPDR3 0x40E0010C
73 #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
74 #define PXA270_GPSR0 0x40E00018
75 #define PXA270_GPCR0 0x40E00024
77 static int pxa270_set_gpio_to_output (mflash_gpio_num_t gpio
)
79 u32 addr
, value
, mask
;
80 target_t
*target
= mflash_bank
->target
;
83 /* remove alternate function. */
84 mask
= 0x3u
<< (gpio
.num
& 0xF)*2;
86 addr
= PXA270_GAFR0_L
+ (gpio
.num
>> 4) * 4;
88 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
92 if (addr
== PXA270_GAFR3_U
)
93 value
&= ~PXA270_GAFR3_U_RESERVED_BITS
;
95 if ((ret
= target_write_u32(target
, addr
, value
)) != ERROR_OK
)
98 /* set direction to output */
99 mask
= 0x1u
<< (gpio
.num
& 0x1F);
101 addr
= PXA270_GPDR0
+ (gpio
.num
>> 5) * 4;
103 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
107 if (addr
== PXA270_GPDR3
)
108 value
&= ~PXA270_GPDR3_RESERVED_BITS
;
110 ret
= target_write_u32(target
, addr
, value
);
114 static int pxa270_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
116 u32 addr
, value
, mask
;
117 target_t
*target
= mflash_bank
->target
;
120 mask
= 0x1u
<< (gpio
.num
& 0x1F);
123 addr
= PXA270_GPSR0
+ (gpio
.num
>> 5) * 4;
125 addr
= PXA270_GPCR0
+ (gpio
.num
>> 5) * 4;
128 if ((ret
= target_read_u32(target
, addr
, &value
)) != ERROR_OK
)
133 ret
= target_write_u32(target
, addr
, value
);
138 #define S3C2440_GPACON 0x56000000
139 #define S3C2440_GPADAT 0x56000004
140 #define S3C2440_GPJCON 0x560000d0
141 #define S3C2440_GPJDAT 0x560000d4
143 static int s3c2440_set_gpio_to_output (mflash_gpio_num_t gpio
)
145 u32 data
, mask
, gpio_con
;
146 target_t
*target
= mflash_bank
->target
;
149 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
150 gpio_con
= S3C2440_GPACON
+ (gpio
.port
[0] - 'a') * 0x10;
151 } else if (gpio
.port
[0] == 'j') {
152 gpio_con
= S3C2440_GPJCON
;
154 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
155 return ERROR_INVALID_ARGUMENTS
;
158 ret
= target_read_u32(target
, gpio_con
, &data
);
160 if (ret
== ERROR_OK
) {
161 if (gpio
.port
[0] == 'a') {
162 mask
= 1 << gpio
.num
;
165 mask
= 3 << gpio
.num
* 2;
167 data
|= (1 << gpio
.num
* 2);
170 ret
= target_write_u32(target
, gpio_con
, data
);
175 static int s3c2440_set_gpio_output_val (mflash_gpio_num_t gpio
, u8 val
)
177 u32 data
, mask
, gpio_dat
;
178 target_t
*target
= mflash_bank
->target
;
181 if (gpio
.port
[0] >= 'a' && gpio
.port
[0] <= 'h') {
182 gpio_dat
= S3C2440_GPADAT
+ (gpio
.port
[0] - 'a') * 0x10;
183 } else if (gpio
.port
[0] == 'j') {
184 gpio_dat
= S3C2440_GPJDAT
;
186 LOG_ERROR("invalid port %d%s", gpio
.num
, gpio
.port
);
187 return ERROR_INVALID_ARGUMENTS
;
190 ret
= target_read_u32(target
, gpio_dat
, &data
);
192 if (ret
== ERROR_OK
) {
193 mask
= 1 << gpio
.num
;
199 ret
= target_write_u32(target
, gpio_dat
, data
);
204 static int mflash_rst(u8 level
)
206 return mflash_bank
->gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, level
);
209 static int mflash_init_gpio (void)
211 mflash_gpio_drv_t
*gpio_drv
= mflash_bank
->gpio_drv
;
213 gpio_drv
->set_gpio_to_output(mflash_bank
->rst_pin
);
214 gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, 1);
216 if (mflash_bank
->wp_pin
.num
!= -1) {
217 gpio_drv
->set_gpio_to_output(mflash_bank
->wp_pin
);
218 gpio_drv
->set_gpio_output_val(mflash_bank
->wp_pin
, 1);
221 if (mflash_bank
->dpd_pin
.num
!= -1) {
222 gpio_drv
->set_gpio_to_output(mflash_bank
->dpd_pin
);
223 gpio_drv
->set_gpio_output_val(mflash_bank
->dpd_pin
, 1);
229 static int mg_dsk_wait(mg_io_type_wait wait
, u32 time
)
232 target_t
*target
= mflash_bank
->target
;
233 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
237 duration_start_measure(&duration
);
241 target_read_u8(target
, mg_task_reg
+ MG_REG_STATUS
, &status
);
243 if (status
& mg_io_rbit_status_busy
)
245 if (wait
== mg_io_wait_bsy
)
250 case mg_io_wait_not_bsy
:
252 case mg_io_wait_rdy_noerr
:
253 if (status
& mg_io_rbit_status_ready
)
256 case mg_io_wait_drq_noerr
:
257 if (status
& mg_io_rbit_status_data_req
)
264 /* Now we check the error condition! */
265 if (status
& mg_io_rbit_status_error
)
267 target_read_u8(target
, mg_task_reg
+ MG_REG_ERROR
, &error
);
269 if (error
& mg_io_rbit_err_bad_sect_num
) {
270 LOG_ERROR("sector not found");
273 else if (error
& (mg_io_rbit_err_bad_block
| mg_io_rbit_err_uncorrectable
)) {
274 LOG_ERROR("bad block");
277 LOG_ERROR("disk operation fail");
285 if (status
& mg_io_rbit_status_ready
)
289 if (status
& mg_io_rbit_status_data_req
)
297 duration_stop_measure(&duration
, NULL
);
299 t
=duration
.duration
.tv_usec
/1000;
300 t
+=duration
.duration
.tv_sec
*1000;
306 LOG_ERROR("timeout occured");
310 static int mg_dsk_srst(u8 on
)
312 target_t
*target
= mflash_bank
->target
;
313 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
317 if ((ret
= target_read_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, &value
)) != ERROR_OK
)
321 value
|= (mg_io_rbit_devc_srst
);
323 value
&= ~mg_io_rbit_devc_srst
;
326 ret
= target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, value
);
330 static int mg_dsk_io_cmd(u32 sect_num
, u32 cnt
, u8 cmd
)
332 target_t
*target
= mflash_bank
->target
;
333 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
336 if (mg_dsk_wait(mg_io_wait_rdy_noerr
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
339 value
= mg_io_rval_dev_drv_master
| mg_io_rval_dev_lba_mode
|((sect_num
>> 24) & 0xf);
341 target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_HEAD
, value
);
342 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_CNT
, (u8
)cnt
);
343 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_NUM
, (u8
)sect_num
);
344 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_LOW
, (u8
)(sect_num
>> 8));
345 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_HIGH
, (u8
)(sect_num
>> 16));
347 target_write_u8(target
, mg_task_reg
+ MG_REG_COMMAND
, cmd
);
352 static int mg_dsk_drv_info(void)
354 target_t
*target
= mflash_bank
->target
;
355 u32 mg_buff
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
357 if ( mg_dsk_io_cmd(0, 1, mg_io_cmd_identify
) != ERROR_OK
)
360 if ( mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
363 LOG_INFO("read drive info.");
365 if (! mflash_bank
->drv_info
)
366 mflash_bank
->drv_info
= malloc(sizeof(mg_drv_info_t
));
368 target
->type
->read_memory(target
, mg_buff
, 2, sizeof(mg_io_type_drv_info
) >> 1,
369 (u8
*)&mflash_bank
->drv_info
->drv_id
);
371 mflash_bank
->drv_info
->tot_sects
= (u32
)(mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_hi
<< 16)
372 + mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_lo
;
374 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
379 static int mg_mflash_probe(void)
381 mflash_bank
->proved
= 0;
385 LOG_INFO("reset mflash");
389 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
394 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
399 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
404 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
407 if (mg_dsk_drv_info() != ERROR_OK
)
410 mflash_bank
->proved
= 1;
415 static int mflash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
419 ret
= mg_mflash_probe();
421 if (ret
== ERROR_OK
) {
422 command_print(cmd_ctx
, "mflash (total %u sectors) found at 0x%8.8x",
423 mflash_bank
->drv_info
->tot_sects
, mflash_bank
->base
);
429 static int mg_mflash_do_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
433 target_t
*target
= mflash_bank
->target
;
437 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_read
) != ERROR_OK
)
440 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
442 duration_start_measure(&duration
);
444 for (i
= 0; i
< sect_cnt
; i
++) {
445 mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
447 target
->type
->read_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
448 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
450 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
452 LOG_DEBUG("%u (0x%8.8x) sector read", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
454 duration_stop_measure(&duration
, NULL
);
456 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
457 LOG_INFO("read %u'th sectors", sect_num
+ i
);
458 duration_start_measure(&duration
);
462 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
467 static int mg_mflash_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
469 u32 quotient
, residue
, i
;
472 quotient
= sect_cnt
>> 8;
473 residue
= sect_cnt
% 256;
475 for (i
= 0; i
< quotient
; i
++) {
476 LOG_DEBUG("sect num : %u buff : 0x%8.8x", sect_num
, (u32
)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 : %8.8x", sect_num
, (u32
)buff_ptr
);
484 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
490 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
494 target_t
*target
= mflash_bank
->target
;
498 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
499 LOG_ERROR("mg_io_cmd_write fail");
503 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
505 duration_start_measure(&duration
);
507 for (i
= 0; i
< sect_cnt
; i
++) {
508 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
510 LOG_ERROR("mg_io_wait_drq time out");
512 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
514 LOG_ERROR("mem write error");
515 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
517 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
519 LOG_ERROR("mg_io_cmd_confirm_write error");
521 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
523 duration_stop_measure(&duration
, NULL
);
525 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
526 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
527 duration_start_measure(&duration
);
531 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
536 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
538 u32 quotient
, residue
, i
;
541 quotient
= sect_cnt
>> 8;
542 residue
= sect_cnt
% 256;
544 for (i
= 0; i
< quotient
; i
++) {
545 LOG_DEBUG("sect num : %u buff : %8.8x", sect_num
, (u32
)buff_ptr
);
546 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
548 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
552 LOG_DEBUG("sect num : %u buff : %8.8x", sect_num
, (u32
)buff_ptr
);
553 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
559 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
561 u8
*sect_buff
, *buff_ptr
= buff
;
562 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
566 end_addr
= addr
+ len
;
568 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
570 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
572 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
573 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
574 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
576 if (end_addr
< next_sec_addr
) {
577 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
578 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
581 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
582 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
583 buff_ptr
+= (next_sec_addr
- cur_addr
);
584 cur_addr
= next_sec_addr
;
588 if (cur_addr
< end_addr
) {
590 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
591 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
593 while (next_sec_addr
<= end_addr
) {
595 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
599 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
601 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
602 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
604 if (cur_addr
< end_addr
) {
606 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
607 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
608 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
609 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
619 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
621 u8
*sect_buff
, *buff_ptr
= buff
;
622 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
626 end_addr
= addr
+ len
;
628 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
630 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
632 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
633 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
634 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
636 if (end_addr
< next_sec_addr
) {
637 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
638 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
641 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
642 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
643 buff_ptr
+= (next_sec_addr
- cur_addr
);
644 cur_addr
= next_sec_addr
;
647 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
650 if (cur_addr
< end_addr
) {
652 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
653 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
655 while (next_sec_addr
<= end_addr
) {
657 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
661 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
663 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
664 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
666 if (cur_addr
< end_addr
) {
668 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
669 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
670 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
671 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
672 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
681 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
683 u32 address
, buf_cnt
;
685 /* TODO : multi-bank support, large file support */
692 return ERROR_COMMAND_SYNTAX_ERROR
;
695 address
= strtoul(args
[2], NULL
, 0);
697 if (! mflash_bank
->proved
) {
701 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
705 buffer
= malloc(fileio
.size
);
707 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
710 fileio_close(&fileio
);
714 duration_start_measure(&duration
);
716 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
718 duration_stop_measure(&duration
, &duration_text
);
720 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
721 fileio
.size
, args
[1], duration_text
,
722 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
726 fileio_close(&fileio
);
733 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
735 u32 address
, size_written
, size
;
737 /* TODO : multi-bank support */
743 return ERROR_COMMAND_SYNTAX_ERROR
;
746 address
= strtoul(args
[2], NULL
, 0);
747 size
= strtoul(args
[3], NULL
, 0);
749 if (! mflash_bank
->proved
) {
753 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
757 buffer
= malloc(size
);
759 duration_start_measure(&duration
);
761 mg_mflash_read(address
, buffer
, size
);
763 duration_stop_measure(&duration
, &duration_text
);
765 fileio_write(&fileio
, size
, buffer
, &size_written
);
767 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
768 address
, size
, args
[1], duration_text
,
769 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
773 fileio_close(&fileio
);
780 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
783 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
784 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
785 "mflash write <num> <file> <address>");
786 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
787 "mflash dump <num> <file> <address> <size>");
793 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
801 return ERROR_COMMAND_SYNTAX_ERROR
;
804 if ((target
= get_target_by_num(strtoul(args
[7], NULL
, 0))) == NULL
)
806 LOG_ERROR("target %lu not defined", strtoul(args
[7], NULL
, 0));
810 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
811 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
812 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
813 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
814 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
816 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
817 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
819 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
820 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
822 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
824 mflash_bank
->target
= target
;
826 for (i
= 0; mflash_gpio
[i
] ; i
++) {
827 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
828 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
832 if (! mflash_bank
->gpio_drv
) {
833 LOG_ERROR("%s is unsupported soc", args
[0]);
834 return ERROR_INVALID_ARGUMENTS
;
840 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
842 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
843 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
844 "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)