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%0lx", sect_num
,
477 (unsigned long)buff_ptr
);
478 mg_mflash_do_read_sects(buff_ptr
, sect_num
, 256);
480 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
484 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
485 (unsigned long)buff_ptr
);
486 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
492 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
496 target_t
*target
= mflash_bank
->target
;
500 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
501 LOG_ERROR("mg_io_cmd_write fail");
505 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
507 duration_start_measure(&duration
);
509 for (i
= 0; i
< sect_cnt
; i
++) {
510 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
512 LOG_ERROR("mg_io_wait_drq time out");
514 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
516 LOG_ERROR("mem write error");
517 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
519 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
521 LOG_ERROR("mg_io_cmd_confirm_write error");
523 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
525 duration_stop_measure(&duration
, NULL
);
527 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
528 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
529 duration_start_measure(&duration
);
533 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
538 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
540 u32 quotient
, residue
, i
;
543 quotient
= sect_cnt
>> 8;
544 residue
= sect_cnt
% 256;
546 for (i
= 0; i
< quotient
; i
++) {
547 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
548 (unsigned long)buff_ptr
);
549 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
551 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
555 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
556 (unsigned long)buff_ptr
);
557 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
563 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
565 u8
*sect_buff
, *buff_ptr
= buff
;
566 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
570 end_addr
= addr
+ len
;
572 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
574 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
576 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
577 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
578 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
580 if (end_addr
< next_sec_addr
) {
581 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
582 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
585 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
586 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
587 buff_ptr
+= (next_sec_addr
- cur_addr
);
588 cur_addr
= next_sec_addr
;
592 if (cur_addr
< end_addr
) {
594 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
595 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
597 while (next_sec_addr
<= end_addr
) {
599 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
603 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
605 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
606 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
608 if (cur_addr
< end_addr
) {
610 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
611 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
612 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
613 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
623 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
625 u8
*sect_buff
, *buff_ptr
= buff
;
626 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
630 end_addr
= addr
+ len
;
632 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
634 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
636 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
637 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
638 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
640 if (end_addr
< next_sec_addr
) {
641 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
642 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
645 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
646 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
647 buff_ptr
+= (next_sec_addr
- cur_addr
);
648 cur_addr
= next_sec_addr
;
651 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
654 if (cur_addr
< end_addr
) {
656 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
657 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
659 while (next_sec_addr
<= end_addr
) {
661 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
665 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
667 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
668 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
670 if (cur_addr
< end_addr
) {
672 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
673 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
674 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
675 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
676 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
685 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
687 u32 address
, buf_cnt
;
689 /* TODO : multi-bank support, large file support */
696 return ERROR_COMMAND_SYNTAX_ERROR
;
699 address
= strtoul(args
[2], NULL
, 0);
701 if (! mflash_bank
->proved
) {
705 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
709 buffer
= malloc(fileio
.size
);
711 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
714 fileio_close(&fileio
);
718 duration_start_measure(&duration
);
720 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
722 duration_stop_measure(&duration
, &duration_text
);
724 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
725 fileio
.size
, args
[1], duration_text
,
726 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
730 fileio_close(&fileio
);
737 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
739 u32 address
, size_written
, size
;
741 /* TODO : multi-bank support */
747 return ERROR_COMMAND_SYNTAX_ERROR
;
750 address
= strtoul(args
[2], NULL
, 0);
751 size
= strtoul(args
[3], NULL
, 0);
753 if (! mflash_bank
->proved
) {
757 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
761 buffer
= malloc(size
);
763 duration_start_measure(&duration
);
765 mg_mflash_read(address
, buffer
, size
);
767 duration_stop_measure(&duration
, &duration_text
);
769 fileio_write(&fileio
, size
, buffer
, &size_written
);
771 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
772 address
, size
, args
[1], duration_text
,
773 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
777 fileio_close(&fileio
);
784 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
787 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
788 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
789 "mflash write <num> <file> <address>");
790 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
791 "mflash dump <num> <file> <address> <size>");
797 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
805 return ERROR_COMMAND_SYNTAX_ERROR
;
808 if ((target
= get_target_by_num(strtoul(args
[7], NULL
, 0))) == NULL
)
810 LOG_ERROR("target %lu not defined", strtoul(args
[7], NULL
, 0));
814 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
815 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
816 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
817 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
818 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
820 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
821 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
823 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
824 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
826 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
828 mflash_bank
->target
= target
;
830 for (i
= 0; mflash_gpio
[i
] ; i
++) {
831 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
832 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
836 if (! mflash_bank
->gpio_drv
) {
837 LOG_ERROR("%s is unsupported soc", args
[0]);
838 return ERROR_INVALID_ARGUMENTS
;
844 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
846 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
847 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
848 "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)