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
);
645 static int mg_mflash_write(u32 addr
, u8
*buff
, u32 len
)
647 u8
*sect_buff
, *buff_ptr
= buff
;
648 u32 cur_addr
, next_sec_addr
, end_addr
, cnt
, sect_num
;
652 end_addr
= addr
+ len
;
654 sect_buff
= malloc(MG_MFLASH_SECTOR_SIZE
);
656 if (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
) {
658 next_sec_addr
= (cur_addr
+ MG_MFLASH_SECTOR_SIZE
) & ~MG_MFLASH_SECTOR_SIZE_MASK
;
659 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
660 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
662 if (end_addr
< next_sec_addr
) {
663 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, end_addr
- cur_addr
);
664 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", end_addr
- cur_addr
, cur_addr
);
667 memcpy(sect_buff
+ (cur_addr
& MG_MFLASH_SECTOR_SIZE_MASK
), buff_ptr
, next_sec_addr
- cur_addr
);
668 LOG_DEBUG("copies %u byte to sector offset 0x%8.8x", next_sec_addr
- cur_addr
, cur_addr
);
669 buff_ptr
+= (next_sec_addr
- cur_addr
);
670 cur_addr
= next_sec_addr
;
673 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
677 if (cur_addr
< end_addr
) {
679 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
680 next_sec_addr
= cur_addr
+ MG_MFLASH_SECTOR_SIZE
;
682 while (next_sec_addr
<= end_addr
) {
684 next_sec_addr
+= MG_MFLASH_SECTOR_SIZE
;
688 mg_mflash_write_sects(buff_ptr
, sect_num
, cnt
);
690 buff_ptr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
691 cur_addr
+= cnt
* MG_MFLASH_SECTOR_SIZE
;
693 if (cur_addr
< end_addr
) {
695 sect_num
= cur_addr
>> MG_MFLASH_SECTOR_SIZE_SHIFT
;
696 mg_mflash_read_sects(sect_buff
, sect_num
, 1);
697 memcpy(sect_buff
, buff_ptr
, end_addr
- cur_addr
);
698 LOG_DEBUG("copies %u byte", end_addr
- cur_addr
);
699 mg_mflash_write_sects(sect_buff
, sect_num
, 1);
710 static int mflash_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
712 u32 address
, buf_cnt
;
714 // TODO : multi-bank support, large file support
721 return ERROR_COMMAND_SYNTAX_ERROR
;
724 address
= strtoul(args
[2], NULL
, 0);
726 if (! mflash_bank
->proved
) {
731 if (fileio_open(&fileio
, args
[1], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
) {
735 buffer
= malloc(fileio
.size
);
737 if (fileio_read(&fileio
, fileio
.size
, buffer
, &buf_cnt
) != ERROR_OK
)
740 fileio_close(&fileio
);
744 duration_start_measure(&duration
);
746 ret
= mg_mflash_write(address
, buffer
, (u32
)fileio
.size
);
748 duration_stop_measure(&duration
, &duration_text
);
750 command_print(cmd_ctx
, "wrote %lli byte from file %s in %s (%f kB/s)",
751 fileio
.size
, args
[1], duration_text
,
752 (float)fileio
.size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
756 fileio_close(&fileio
);
763 static int mflash_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
765 u32 address
, size_written
, size
;
767 // TODO : multi-bank support
773 return ERROR_COMMAND_SYNTAX_ERROR
;
776 address
= strtoul(args
[2], NULL
, 0);
777 size
= strtoul(args
[3], NULL
, 0);
779 if (! mflash_bank
->proved
) {
783 if (fileio_open(&fileio
, args
[1], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
) {
787 buffer
= malloc(size
);
789 duration_start_measure(&duration
);
791 mg_mflash_read(address
, buffer
, size
);
793 duration_stop_measure(&duration
, &duration_text
);
795 fileio_write(&fileio
, size
, buffer
, &size_written
);
797 command_print(cmd_ctx
, "dump image (address 0x%8.8x size %u) to file %s in %s (%f kB/s)",
798 address
, size
, args
[1], duration_text
,
799 (float)size
/ 1024.0 / ((float)duration
.duration
.tv_sec
+ ((float)duration
.duration
.tv_usec
/ 1000000.0)));
803 fileio_close(&fileio
);
810 int mflash_init_drivers(struct command_context_s
*cmd_ctx
)
813 register_command(cmd_ctx
, mflash_cmd
, "probe", mflash_probe_command
, COMMAND_EXEC
, NULL
);
814 register_command(cmd_ctx
, mflash_cmd
, "write", mflash_write_command
, COMMAND_EXEC
,
815 "mflash write <num> <file> <address>");
816 register_command(cmd_ctx
, mflash_cmd
, "dump", mflash_dump_command
, COMMAND_EXEC
,
817 "mflash dump <num> <file> <address> <size>");
823 static int mflash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
831 return ERROR_COMMAND_SYNTAX_ERROR
;
834 if ((target
= get_target_by_num(strtoul(args
[7], NULL
, 0))) == NULL
)
836 LOG_ERROR("target %lu not defined", strtoul(args
[7], NULL
, 0));
840 mflash_bank
= calloc(sizeof(mflash_bank_t
), 1);
841 mflash_bank
->base
= strtoul(args
[1], NULL
, 0);
842 mflash_bank
->chip_width
= strtoul(args
[2], NULL
, 0);
843 mflash_bank
->bus_width
= strtoul(args
[3], NULL
, 0);
844 mflash_bank
->rst_pin
.num
= strtoul(args
[4], &str
, 0);
846 mflash_bank
->rst_pin
.port
[0] = (u16
)tolower(str
[0]);
847 mflash_bank
->wp_pin
.num
= strtol(args
[5], &str
, 0);
849 mflash_bank
->wp_pin
.port
[0] = (u16
)tolower(str
[0]);
850 mflash_bank
->dpd_pin
.num
= strtol(args
[6], &str
, 0);
852 mflash_bank
->dpd_pin
.port
[0] = (u16
)tolower(str
[0]);
854 mflash_bank
->target
= target
;
856 for (i
= 0; mflash_gpio
[i
] ; i
++) {
857 if (! strcmp(mflash_gpio
[i
]->name
, args
[0])) {
858 mflash_bank
->gpio_drv
= mflash_gpio
[i
];
862 if (! mflash_bank
->gpio_drv
) {
863 LOG_ERROR("%s is unsupported soc", args
[0]);
864 return ERROR_INVALID_ARGUMENTS
;
870 int mflash_register_commands(struct command_context_s
*cmd_ctx
)
872 mflash_cmd
= register_command(cmd_ctx
, NULL
, "mflash", NULL
, COMMAND_ANY
, NULL
);
873 register_command(cmd_ctx
, mflash_cmd
, "bank", mflash_bank_command
, COMMAND_CONFIG
,
874 "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)