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 mflash_rst(u8 level
)
196 return mflash_bank
->gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, level
);
199 static int mflash_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);
206 if (mflash_bank
->wp_pin
.num
!= -1) {
207 gpio_drv
->set_gpio_to_output(mflash_bank
->wp_pin
);
208 gpio_drv
->set_gpio_output_val(mflash_bank
->wp_pin
, 1);
211 if (mflash_bank
->dpd_pin
.num
!= -1) {
212 gpio_drv
->set_gpio_to_output(mflash_bank
->dpd_pin
);
213 gpio_drv
->set_gpio_output_val(mflash_bank
->dpd_pin
, 1);
219 static int mg_dsk_wait(mg_io_type_wait wait
, u32 time
)
222 target_t
*target
= mflash_bank
->target
;
223 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
227 duration_start_measure(&duration
);
231 target_read_u8(target
, mg_task_reg
+ MG_REG_STATUS
, &status
);
233 if (status
& mg_io_rbit_status_busy
)
235 if (wait
== mg_io_wait_bsy
)
240 case mg_io_wait_not_bsy
:
242 case mg_io_wait_rdy_noerr
:
243 if (status
& mg_io_rbit_status_ready
)
246 case mg_io_wait_drq_noerr
:
247 if (status
& mg_io_rbit_status_data_req
)
254 /* Now we check the error condition! */
255 if (status
& mg_io_rbit_status_error
)
257 target_read_u8(target
, mg_task_reg
+ MG_REG_ERROR
, &error
);
259 if (error
& mg_io_rbit_err_bad_sect_num
) {
260 LOG_ERROR("sector not found");
263 else if (error
& (mg_io_rbit_err_bad_block
| mg_io_rbit_err_uncorrectable
)) {
264 LOG_ERROR("bad block");
267 LOG_ERROR("disk operation fail");
275 if (status
& mg_io_rbit_status_ready
)
279 if (status
& mg_io_rbit_status_data_req
)
287 duration_stop_measure(&duration
, NULL
);
289 t
=duration
.duration
.tv_usec
/1000;
290 t
+=duration
.duration
.tv_sec
*1000;
296 LOG_ERROR("timeout occured");
300 static int mg_dsk_srst(u8 on
)
302 target_t
*target
= mflash_bank
->target
;
303 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
307 if ((ret
= target_read_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, &value
)) != ERROR_OK
)
311 value
|= (mg_io_rbit_devc_srst
);
313 value
&= ~mg_io_rbit_devc_srst
;
316 ret
= target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, value
);
320 static int mg_dsk_io_cmd(u32 sect_num
, u32 cnt
, u8 cmd
)
322 target_t
*target
= mflash_bank
->target
;
323 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
326 if (mg_dsk_wait(mg_io_wait_rdy_noerr
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
329 value
= mg_io_rval_dev_drv_master
| mg_io_rval_dev_lba_mode
|((sect_num
>> 24) & 0xf);
331 target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_HEAD
, value
);
332 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_CNT
, (u8
)cnt
);
333 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_NUM
, (u8
)sect_num
);
334 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_LOW
, (u8
)(sect_num
>> 8));
335 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_HIGH
, (u8
)(sect_num
>> 16));
337 target_write_u8(target
, mg_task_reg
+ MG_REG_COMMAND
, cmd
);
342 static int mg_dsk_drv_info(void)
344 target_t
*target
= mflash_bank
->target
;
345 u32 mg_buff
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
347 if ( mg_dsk_io_cmd(0, 1, mg_io_cmd_identify
) != ERROR_OK
)
350 if ( mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
353 LOG_INFO("read drive info.");
355 if (! mflash_bank
->drv_info
)
356 mflash_bank
->drv_info
= malloc(sizeof(mg_drv_info_t
));
358 target
->type
->read_memory(target
, mg_buff
, 2, sizeof(mg_io_type_drv_info
) >> 1,
359 (u8
*)&mflash_bank
->drv_info
->drv_id
);
361 mflash_bank
->drv_info
->tot_sects
= (u32
)(mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_hi
<< 16)
362 + mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_lo
;
364 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
369 static int mg_mflash_probe(void)
371 mflash_bank
->proved
= 0;
375 LOG_INFO("reset mflash");
379 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
384 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
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
)
397 if (mg_dsk_drv_info() != ERROR_OK
)
400 mflash_bank
->proved
= 1;
405 static int mflash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
409 ret
= mg_mflash_probe();
411 if (ret
== ERROR_OK
) {
412 command_print(cmd_ctx
, "mflash (total %u sectors) found at 0x%8.8x",
413 mflash_bank
->drv_info
->tot_sects
, mflash_bank
->base
);
419 static int mg_mflash_do_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
423 target_t
*target
= mflash_bank
->target
;
427 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_read
) != ERROR_OK
)
430 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
432 duration_start_measure(&duration
);
434 for (i
= 0; i
< sect_cnt
; i
++) {
435 mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
437 target
->type
->read_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
438 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
440 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
442 LOG_DEBUG("%u (0x%8.8x) sector read", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
444 duration_stop_measure(&duration
, NULL
);
446 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
447 LOG_INFO("read %u'th sectors", sect_num
+ i
);
448 duration_start_measure(&duration
);
452 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
457 static int mg_mflash_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
459 u32 quotient
, residue
, i
;
462 quotient
= sect_cnt
>> 8;
463 residue
= sect_cnt
% 256;
465 for (i
= 0; i
< quotient
; i
++) {
466 LOG_DEBUG("sect num : %u buff : 0x%0lx", sect_num
,
467 (unsigned long)buff_ptr
);
468 mg_mflash_do_read_sects(buff_ptr
, sect_num
, 256);
470 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
474 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
475 (unsigned long)buff_ptr
);
476 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
482 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
486 target_t
*target
= mflash_bank
->target
;
490 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
491 LOG_ERROR("mg_io_cmd_write fail");
495 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
497 duration_start_measure(&duration
);
499 for (i
= 0; i
< sect_cnt
; i
++) {
500 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
502 LOG_ERROR("mg_io_wait_drq time out");
504 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
506 LOG_ERROR("mem write error");
507 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
509 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
511 LOG_ERROR("mg_io_cmd_confirm_write error");
513 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
515 duration_stop_measure(&duration
, NULL
);
517 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
518 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
519 duration_start_measure(&duration
);
523 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
528 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
530 u32 quotient
, residue
, i
;
533 quotient
= sect_cnt
>> 8;
534 residue
= sect_cnt
% 256;
536 for (i
= 0; i
< quotient
; i
++) {
537 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
538 (unsigned long)buff_ptr
);
539 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
541 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
545 LOG_DEBUG("sect num : %u buff : %0lx", sect_num
,
546 (unsigned long)buff_ptr
);
547 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
553 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
555 u8
*sect_buff
, *buff_ptr
= buff
;
556 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
560 end_addr
= addr
+ len
;
562 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
564 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
566 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
567 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
568 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
570 if (end_addr
< next_sec_addr
) {
571 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
572 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
575 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
576 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
577 buff_ptr
+= (next_sec_addr
- cur_addr
);
578 cur_addr
= next_sec_addr
;
582 if (cur_addr
< end_addr
) {
584 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
585 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
587 while (next_sec_addr
<= end_addr
) {
589 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
593 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
595 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
596 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
598 if (cur_addr
< end_addr
) {
600 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
601 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
602 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
603 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
613 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
615 u8
*sect_buff
, *buff_ptr
= buff
;
616 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
620 end_addr
= addr
+ len
;
622 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
624 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
626 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
627 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
628 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
630 if (end_addr
< next_sec_addr
) {
631 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
632 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
635 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
636 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
637 buff_ptr
+= (next_sec_addr
- cur_addr
);
638 cur_addr
= next_sec_addr
;
641 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
644 if (cur_addr
< end_addr
) {
646 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
647 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
649 while (next_sec_addr
<= end_addr
) {
651 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
655 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
657 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
658 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
660 if (cur_addr
< end_addr
) {
662 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
663 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
664 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
665 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
666 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
675 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
677 u32 address
, buf_cnt
;
679 /* TODO : multi-bank support, large file support */
686 return ERROR_COMMAND_SYNTAX_ERROR
;
689 address
= strtoul(args
[2], NULL
, 0);
691 if (! mflash_bank
->proved
) {
695 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
699 buffer
= malloc(fileio
.size
);
701 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
704 fileio_close(&fileio
);
708 duration_start_measure(&duration
);
710 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
712 duration_stop_measure(&duration
, &duration_text
);
714 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
715 fileio
.size
, args
[1], duration_text
,
716 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
720 fileio_close(&fileio
);
727 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
729 u32 address
, size_written
, size
;
731 /* TODO : multi-bank support */
737 return ERROR_COMMAND_SYNTAX_ERROR
;
740 address
= strtoul(args
[2], NULL
, 0);
741 size
= strtoul(args
[3], NULL
, 0);
743 if (! mflash_bank
->proved
) {
747 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
751 buffer
= malloc(size
);
753 duration_start_measure(&duration
);
755 mg_mflash_read(address
, buffer
, size
);
757 duration_stop_measure(&duration
, &duration_text
);
759 fileio_write(&fileio
, size
, buffer
, &size_written
);
761 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
762 address
, size
, args
[1], duration_text
,
763 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
767 fileio_close(&fileio
);
774 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
777 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
778 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
779 "mflash write <num> <file> <address>");
780 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
781 "mflash dump <num> <file> <address> <size>");
787 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
795 return ERROR_COMMAND_SYNTAX_ERROR
;
798 if ((target
= get_target(args
[7])) == NULL
)
800 LOG_ERROR("target '%s' not defined", args
[7]);
804 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
805 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
806 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
807 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
808 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
810 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
811 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
813 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
814 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
816 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
818 mflash_bank
->target
= target
;
820 for (i
= 0; mflash_gpio
[i
] ; i
++) {
821 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
822 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
826 if (! mflash_bank
->gpio_drv
) {
827 LOG_ERROR("%s is unsupported soc", args
[0]);
828 return ERROR_INVALID_ARGUMENTS
;
834 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
836 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
837 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
838 "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)