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 mg_dump_task_reg (void)
211 target_t
*target
= mflash_bank
->target
;
212 u32 address
= mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_ERROR
;
214 char *reg_name
[9] = {
217 "sector num (LBA 7- 0) ",
218 "cyl. low (LBA 15- 8) ",
219 "cyl. high (LBA 23-16) ",
226 for (i
= 0; i
< 9; i
++) {
227 target_read_u8(target
, address
+ i
* 2, &value
);
228 LOG_INFO("%s : 0x%2.2x", reg_name
[i
], value
);
234 static int mflash_init_gpio (void)
236 mflash_gpio_drv_t
*gpio_drv
= mflash_bank
->gpio_drv
;
238 gpio_drv
->set_gpio_to_output(mflash_bank
->rst_pin
);
239 gpio_drv
->set_gpio_output_val(mflash_bank
->rst_pin
, 1);
241 if (mflash_bank
->wp_pin
.num
!= -1) {
242 gpio_drv
->set_gpio_to_output(mflash_bank
->wp_pin
);
243 gpio_drv
->set_gpio_output_val(mflash_bank
->wp_pin
, 1);
246 if (mflash_bank
->dpd_pin
.num
!= -1) {
247 gpio_drv
->set_gpio_to_output(mflash_bank
->dpd_pin
);
248 gpio_drv
->set_gpio_output_val(mflash_bank
->dpd_pin
, 1);
254 static int mg_dsk_wait(mg_io_type_wait wait
, u32 time
)
257 target_t
*target
= mflash_bank
->target
;
258 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
262 duration_start_measure(&duration
);
266 target_read_u8(target
, mg_task_reg
+ MG_REG_STATUS
, &status
);
268 if (status
& mg_io_rbit_status_busy
)
270 if (wait
== mg_io_wait_bsy
)
275 case mg_io_wait_not_bsy
:
277 case mg_io_wait_rdy_noerr
:
278 if (status
& mg_io_rbit_status_ready
)
281 case mg_io_wait_drq_noerr
:
282 if (status
& mg_io_rbit_status_data_req
)
289 /* Now we check the error condition! */
290 if (status
& mg_io_rbit_status_error
)
292 target_read_u8(target
, mg_task_reg
+ MG_REG_ERROR
, &error
);
294 if (error
& mg_io_rbit_err_bad_sect_num
) {
295 LOG_ERROR("sector not found");
298 else if (error
& (mg_io_rbit_err_bad_block
| mg_io_rbit_err_uncorrectable
)) {
299 LOG_ERROR("bad block");
302 LOG_ERROR("disk operation fail");
310 if (status
& mg_io_rbit_status_ready
)
314 if (status
& mg_io_rbit_status_data_req
)
322 duration_stop_measure(&duration
, NULL
);
324 t
=duration
.duration
.tv_usec
/1000;
325 t
+=duration
.duration
.tv_sec
*1000;
331 LOG_ERROR("timeout occured");
335 static int mg_dsk_srst(u8 on
)
337 target_t
*target
= mflash_bank
->target
;
338 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
342 if ((ret
= target_read_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, &value
)) != ERROR_OK
)
346 value
|= (mg_io_rbit_devc_srst
);
348 value
&= ~mg_io_rbit_devc_srst
;
351 ret
= target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_CTRL
, value
);
355 static int mg_dsk_io_cmd(u32 sect_num
, u32 cnt
, u8 cmd
)
357 target_t
*target
= mflash_bank
->target
;
358 u32 mg_task_reg
= mflash_bank
->base
+ MG_REG_OFFSET
;
361 if (mg_dsk_wait(mg_io_wait_rdy_noerr
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
364 value
= mg_io_rval_dev_drv_master
| mg_io_rval_dev_lba_mode
|((sect_num
>> 24) & 0xf);
366 target_write_u8(target
, mg_task_reg
+ MG_REG_DRV_HEAD
, value
);
367 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_CNT
, (u8
)cnt
);
368 target_write_u8(target
, mg_task_reg
+ MG_REG_SECT_NUM
, (u8
)sect_num
);
369 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_LOW
, (u8
)(sect_num
>> 8));
370 target_write_u8(target
, mg_task_reg
+ MG_REG_CYL_HIGH
, (u8
)(sect_num
>> 16));
372 target_write_u8(target
, mg_task_reg
+ MG_REG_COMMAND
, cmd
);
377 static int mg_dsk_drv_info(void)
379 target_t
*target
= mflash_bank
->target
;
380 u32 mg_buff
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
382 if ( mg_dsk_io_cmd(0, 1, mg_io_cmd_identify
) != ERROR_OK
)
385 if ( mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
) != ERROR_OK
)
388 LOG_INFO("read drive info.");
390 if (! mflash_bank
->drv_info
)
391 mflash_bank
->drv_info
= malloc(sizeof(mg_drv_info_t
));
393 target
->type
->read_memory(target
, mg_buff
, 2, sizeof(mg_io_type_drv_info
) >> 1,
394 (u8
*)&mflash_bank
->drv_info
->drv_id
);
396 mflash_bank
->drv_info
->tot_sects
= (u32
)(mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_hi
<< 16)
397 + mflash_bank
->drv_info
->drv_id
.total_user_addressable_sectors_lo
;
399 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
404 static int mg_mflash_probe(void)
406 mflash_bank
->proved
= 0;
410 LOG_INFO("reset mflash");
414 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
419 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
424 if (mg_dsk_wait(mg_io_wait_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
429 if (mg_dsk_wait(mg_io_wait_not_bsy
, MG_OEM_DISK_WAIT_TIME_LONG
) != ERROR_OK
)
432 if (mg_dsk_drv_info() != ERROR_OK
)
435 mflash_bank
->proved
= 1;
440 static int mflash_probe_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
444 ret
= mg_mflash_probe();
446 if (ret
== ERROR_OK
) {
447 command_print(cmd_ctx
, "mflash (total %u sectors) found at 0x%8.8x",
448 mflash_bank
->drv_info
->tot_sects
, mflash_bank
->base
);
454 static int mg_mflash_do_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
458 target_t
*target
= mflash_bank
->target
;
462 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_read
) != ERROR_OK
)
465 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
467 duration_start_measure(&duration
);
469 for (i
= 0; i
< sect_cnt
; i
++) {
470 mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
472 target
->type
->read_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
473 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
475 target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_read
);
477 LOG_DEBUG("%u (0x%8.8x) sector read", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
479 duration_stop_measure(&duration
, NULL
);
481 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
482 LOG_INFO("read %u'th sectors", sect_num
+ i
);
483 duration_start_measure(&duration
);
487 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
492 static int mg_mflash_read_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
494 u32 quotient
, residue
, i
;
497 quotient
= sect_cnt
>> 8;
498 residue
= sect_cnt
% 256;
500 for (i
= 0; i
< quotient
; i
++) {
501 LOG_DEBUG("sect num : %u buff : 0x%8.8x", sect_num
, (u32
)buff_ptr
);
502 mg_mflash_do_read_sects(buff_ptr
, sect_num
, 256);
504 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
508 LOG_DEBUG("sect num : %u buff : %8.8x", sect_num
, (u32
)buff_ptr
);
509 mg_mflash_do_read_sects(buff_ptr
, sect_num
, residue
);
515 static int mg_mflash_do_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
519 target_t
*target
= mflash_bank
->target
;
523 if ( mg_dsk_io_cmd(sect_num
, sect_cnt
, mg_io_cmd_write
) != ERROR_OK
) {
524 LOG_ERROR("mg_io_cmd_write fail");
528 address
= mflash_bank
->base
+ MG_BUFFER_OFFSET
;
530 duration_start_measure(&duration
);
532 for (i
= 0; i
< sect_cnt
; i
++) {
533 ret
= mg_dsk_wait(mg_io_wait_drq
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
535 LOG_ERROR("mg_io_wait_drq time out");
537 ret
= target
->type
->write_memory(target
, address
, 2, MG_MFLASH_SECTOR_SIZE
/ 2, buff_ptr
);
539 LOG_ERROR("mem write error");
540 buff_ptr
+= MG_MFLASH_SECTOR_SIZE
;
542 ret
= target_write_u8(target
, mflash_bank
->base
+ MG_REG_OFFSET
+ MG_REG_COMMAND
, mg_io_cmd_confirm_write
);
544 LOG_ERROR("mg_io_cmd_confirm_write error");
546 LOG_DEBUG("%u (0x%8.8x) sector write", sect_num
+ i
, (sect_num
+ i
) * MG_MFLASH_SECTOR_SIZE
);
548 duration_stop_measure(&duration
, NULL
);
550 if ((duration
.duration
.tv_sec
* 1000 + duration
.duration
.tv_usec
/ 1000) > 3000) {
551 LOG_INFO("wrote %u'th sectors", sect_num
+ i
);
552 duration_start_measure(&duration
);
556 ret
= mg_dsk_wait(mg_io_wait_rdy
, MG_OEM_DISK_WAIT_TIME_NORMAL
);
561 static int mg_mflash_write_sects(void *buff
, u32 sect_num
, u32 sect_cnt
)
563 u32 quotient
, residue
, i
;
566 quotient
= sect_cnt
>> 8;
567 residue
= sect_cnt
% 256;
569 for (i
= 0; i
< quotient
; i
++) {
570 LOG_DEBUG("sect num : %u buff : %8.8x", sect_num
, (u32
)buff_ptr
);
571 mg_mflash_do_write_sects(buff_ptr
, sect_num
, 256);
573 buff_ptr
+= 256 * MG_MFLASH_SECTOR_SIZE
;
577 LOG_DEBUG("sect num : %u buff : %8.8x", sect_num
, (u32
)buff_ptr
);
578 mg_mflash_do_write_sects(buff_ptr
, sect_num
, residue
);
584 static int mg_mflash_read (u32 addr
, u8
*buff
, u32 len
)
586 u8
*sect_buff
, *buff_ptr
= buff
;
587 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
591 end_addr
= addr
+ len
;
593 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
595 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
597 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
598 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
599 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
601 if (end_addr
< next_sec_addr
) {
602 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), end_addr
- cur_addr
);
603 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
606 memcpy(buff_ptr
, sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), next_sec_addr
- cur_addr
);
607 LOG_DEBUG("copies %u byte from sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
608 buff_ptr
+= (next_sec_addr
- cur_addr
);
609 cur_addr
= next_sec_addr
;
613 if (cur_addr
< end_addr
) {
615 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
616 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
618 while (next_sec_addr
<= end_addr
) {
620 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
624 mg_mflash_read_sects(buff_ptr
, sect_num
, cnt
);
626 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
627 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
629 if (cur_addr
< end_addr
) {
631 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
632 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
633 memcpy(buff_ptr
, sect_buff
, end_addr
- cur_addr
);
634 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
644 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
646 u8
*sect_buff
, *buff_ptr
= buff
;
647 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
651 end_addr
= addr
+ len
;
653 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
655 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
657 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
658 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
659 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
661 if (end_addr
< next_sec_addr
) {
662 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
663 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
666 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
667 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
668 buff_ptr
+= (next_sec_addr
- cur_addr
);
669 cur_addr
= next_sec_addr
;
672 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
675 if (cur_addr
< end_addr
) {
677 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
678 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
680 while (next_sec_addr
<= end_addr
) {
682 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
686 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
688 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
689 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
691 if (cur_addr
< end_addr
) {
693 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
694 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
695 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
696 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
697 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
706 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
708 u32 address
, buf_cnt
;
710 /* TODO : multi-bank support, large file support */
717 return ERROR_COMMAND_SYNTAX_ERROR
;
720 address
= strtoul(args
[2], NULL
, 0);
722 if (! mflash_bank
->proved
) {
726 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
730 buffer
= malloc(fileio
.size
);
732 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
735 fileio_close(&fileio
);
739 duration_start_measure(&duration
);
741 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
743 duration_stop_measure(&duration
, &duration_text
);
745 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
746 fileio
.size
, args
[1], duration_text
,
747 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
751 fileio_close(&fileio
);
758 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
760 u32 address
, size_written
, size
;
762 /* TODO : multi-bank support */
768 return ERROR_COMMAND_SYNTAX_ERROR
;
771 address
= strtoul(args
[2], NULL
, 0);
772 size
= strtoul(args
[3], NULL
, 0);
774 if (! mflash_bank
->proved
) {
778 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
782 buffer
= malloc(size
);
784 duration_start_measure(&duration
);
786 mg_mflash_read(address
, buffer
, size
);
788 duration_stop_measure(&duration
, &duration_text
);
790 fileio_write(&fileio
, size
, buffer
, &size_written
);
792 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
793 address
, size
, args
[1], duration_text
,
794 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
798 fileio_close(&fileio
);
805 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
808 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
809 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
810 "mflash write <num> <file> <address>");
811 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
812 "mflash dump <num> <file> <address> <size>");
818 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
826 return ERROR_COMMAND_SYNTAX_ERROR
;
829 if ((target
= get_target_by_num(strtoul(args
[7], NULL
, 0))) == NULL
)
831 LOG_ERROR("target %lu not defined", strtoul(args
[7], NULL
, 0));
835 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
836 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
837 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
838 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
839 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
841 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
842 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
844 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
845 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
847 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
849 mflash_bank
->target
= target
;
851 for (i
= 0; mflash_gpio
[i
] ; i
++) {
852 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
853 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
857 if (! mflash_bank
->gpio_drv
) {
858 LOG_ERROR("%s is unsupported soc", args
[0]);
859 return ERROR_INVALID_ARGUMENTS
;
865 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
867 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
868 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
869 "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)