fileio: fileio_size() can now fail
[openocd.git] / src / flash / mflash.c
1 /***************************************************************************
2 * Copyright (C) 2007-2008 by unsik Kim <donari75@gmail.com> *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "mflash.h"
25 #include <target/target.h>
26 #include <helper/time_support.h>
27 #include <helper/fileio.h>
28 #include <helper/log.h>
29
30
31 static int s3c2440_set_gpio_to_output (struct mflash_gpio_num gpio);
32 static int s3c2440_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val);
33 static int pxa270_set_gpio_to_output (struct mflash_gpio_num gpio);
34 static int pxa270_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val);
35
36 static struct mflash_bank *mflash_bank;
37
38 static struct mflash_gpio_drv pxa270_gpio = {
39 .name = "pxa270",
40 .set_gpio_to_output = pxa270_set_gpio_to_output,
41 .set_gpio_output_val = pxa270_set_gpio_output_val
42 };
43
44 static struct mflash_gpio_drv s3c2440_gpio = {
45 .name = "s3c2440",
46 .set_gpio_to_output = s3c2440_set_gpio_to_output,
47 .set_gpio_output_val = s3c2440_set_gpio_output_val
48 };
49
50 static struct mflash_gpio_drv *mflash_gpio[] =
51 {
52 &pxa270_gpio,
53 &s3c2440_gpio,
54 NULL
55 };
56
57 #define PXA270_GAFR0_L 0x40E00054
58 #define PXA270_GAFR3_U 0x40E00070
59 #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
60 #define PXA270_GPDR0 0x40E0000C
61 #define PXA270_GPDR3 0x40E0010C
62 #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
63 #define PXA270_GPSR0 0x40E00018
64 #define PXA270_GPCR0 0x40E00024
65
66 static int pxa270_set_gpio_to_output (struct mflash_gpio_num gpio)
67 {
68 uint32_t addr, value, mask;
69 struct target *target = mflash_bank->target;
70 int ret;
71
72 /* remove alternate function. */
73 mask = 0x3u << (gpio.num & 0xF)*2;
74
75 addr = PXA270_GAFR0_L + (gpio.num >> 4) * 4;
76
77 if ((ret = target_read_u32(target, addr, &value)) != ERROR_OK)
78 return ret;
79
80 value &= ~mask;
81 if (addr == PXA270_GAFR3_U)
82 value &= ~PXA270_GAFR3_U_RESERVED_BITS;
83
84 if ((ret = target_write_u32(target, addr, value)) != ERROR_OK)
85 return ret;
86
87 /* set direction to output */
88 mask = 0x1u << (gpio.num & 0x1F);
89
90 addr = PXA270_GPDR0 + (gpio.num >> 5) * 4;
91
92 if ((ret = target_read_u32(target, addr, &value)) != ERROR_OK)
93 return ret;
94
95 value |= mask;
96 if (addr == PXA270_GPDR3)
97 value &= ~PXA270_GPDR3_RESERVED_BITS;
98
99 ret = target_write_u32(target, addr, value);
100 return ret;
101 }
102
103 static int pxa270_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val)
104 {
105 uint32_t addr, value, mask;
106 struct target *target = mflash_bank->target;
107 int ret;
108
109 mask = 0x1u << (gpio.num & 0x1F);
110
111 if (val) {
112 addr = PXA270_GPSR0 + (gpio.num >> 5) * 4;
113 } else {
114 addr = PXA270_GPCR0 + (gpio.num >> 5) * 4;
115 }
116
117 if ((ret = target_read_u32(target, addr, &value)) != ERROR_OK)
118 return ret;
119
120 value |= mask;
121
122 ret = target_write_u32(target, addr, value);
123
124 return ret;
125 }
126
127 #define S3C2440_GPACON 0x56000000
128 #define S3C2440_GPADAT 0x56000004
129 #define S3C2440_GPJCON 0x560000d0
130 #define S3C2440_GPJDAT 0x560000d4
131
132 static int s3c2440_set_gpio_to_output (struct mflash_gpio_num gpio)
133 {
134 uint32_t data, mask, gpio_con;
135 struct target *target = mflash_bank->target;
136 int ret;
137
138 if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') {
139 gpio_con = S3C2440_GPACON + (gpio.port[0] - 'a') * 0x10;
140 } else if (gpio.port[0] == 'j') {
141 gpio_con = S3C2440_GPJCON;
142 } else {
143 LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
144 return ERROR_INVALID_ARGUMENTS;
145 }
146
147 ret = target_read_u32(target, gpio_con, &data);
148
149 if (ret == ERROR_OK) {
150 if (gpio.port[0] == 'a') {
151 mask = 1 << gpio.num;
152 data &= ~mask;
153 } else {
154 mask = 3 << gpio.num * 2;
155 data &= ~mask;
156 data |= (1 << gpio.num * 2);
157 }
158
159 ret = target_write_u32(target, gpio_con, data);
160 }
161 return ret;
162 }
163
164 static int s3c2440_set_gpio_output_val (struct mflash_gpio_num gpio, uint8_t val)
165 {
166 uint32_t data, mask, gpio_dat;
167 struct target *target = mflash_bank->target;
168 int ret;
169
170 if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') {
171 gpio_dat = S3C2440_GPADAT + (gpio.port[0] - 'a') * 0x10;
172 } else if (gpio.port[0] == 'j') {
173 gpio_dat = S3C2440_GPJDAT;
174 } else {
175 LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
176 return ERROR_INVALID_ARGUMENTS;
177 }
178
179 ret = target_read_u32(target, gpio_dat, &data);
180
181 if (ret == ERROR_OK) {
182 mask = 1 << gpio.num;
183 if (val)
184 data |= mask;
185 else
186 data &= ~mask;
187
188 ret = target_write_u32(target, gpio_dat, data);
189 }
190 return ret;
191 }
192
193 static int mg_hdrst(uint8_t level)
194 {
195 return mflash_bank->gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, level);
196 }
197
198 static int mg_init_gpio (void)
199 {
200 int ret;
201 struct mflash_gpio_drv *gpio_drv = mflash_bank->gpio_drv;
202
203 ret = gpio_drv->set_gpio_to_output(mflash_bank->rst_pin);
204 if (ret != ERROR_OK)
205 return ret;
206
207 ret = gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, 1);
208
209 return ret;
210 }
211
212 static int mg_dsk_wait(mg_io_type_wait wait_local, uint32_t time_var)
213 {
214 uint8_t status, error;
215 struct target *target = mflash_bank->target;
216 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
217 int ret;
218 long long t = 0;
219
220 struct duration bench;
221 duration_start(&bench);
222
223 while (time_var) {
224
225 ret = target_read_u8(target, mg_task_reg + MG_REG_STATUS, &status);
226 if (ret != ERROR_OK)
227 return ret;
228
229 if (status & mg_io_rbit_status_busy)
230 {
231 if (wait_local == mg_io_wait_bsy)
232 return ERROR_OK;
233 } else {
234 switch (wait_local)
235 {
236 case mg_io_wait_not_bsy:
237 return ERROR_OK;
238 case mg_io_wait_rdy_noerr:
239 if (status & mg_io_rbit_status_ready)
240 return ERROR_OK;
241 break;
242 case mg_io_wait_drq_noerr:
243 if (status & mg_io_rbit_status_data_req)
244 return ERROR_OK;
245 break;
246 default:
247 break;
248 }
249
250 /* Now we check the error condition! */
251 if (status & mg_io_rbit_status_error)
252 {
253 ret = target_read_u8(target, mg_task_reg + MG_REG_ERROR, &error);
254 if (ret != ERROR_OK)
255 return ret;
256
257 LOG_ERROR("mflash: io error 0x%02x", error);
258
259 return ERROR_MG_IO;
260 }
261
262 switch (wait_local)
263 {
264 case mg_io_wait_rdy:
265 if (status & mg_io_rbit_status_ready)
266 return ERROR_OK;
267
268 case mg_io_wait_drq:
269 if (status & mg_io_rbit_status_data_req)
270 return ERROR_OK;
271
272 default:
273 break;
274 }
275 }
276
277 ret = duration_measure(&bench);
278 if (ERROR_OK == ret)
279 t = duration_elapsed(&bench) * 1000.0;
280 else
281 LOG_ERROR("mflash: duration measurement failed: %d", ret);
282
283 if (t > time_var)
284 break;
285 }
286
287 LOG_ERROR("mflash: timeout occured");
288 return ERROR_MG_TIMEOUT;
289 }
290
291 static int mg_dsk_srst(uint8_t on)
292 {
293 struct target *target = mflash_bank->target;
294 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
295 uint8_t value;
296 int ret;
297
298 if ((ret = target_read_u8(target, mg_task_reg + MG_REG_DRV_CTRL, &value)) != ERROR_OK)
299 return ret;
300
301 if (on) {
302 value |= (mg_io_rbit_devc_srst);
303 } else {
304 value &= ~mg_io_rbit_devc_srst;
305 }
306
307 ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_CTRL, value);
308 return ret;
309 }
310
311 static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd)
312 {
313 struct target *target = mflash_bank->target;
314 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
315 uint8_t value;
316 int ret;
317
318 ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL);
319 if (ret != ERROR_OK)
320 return ret;
321
322 value = mg_io_rval_dev_drv_master | mg_io_rval_dev_lba_mode |((sect_num >> 24) & 0xf);
323
324 ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_HEAD, value);
325 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, (uint8_t)cnt);
326 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_NUM, (uint8_t)sect_num);
327 ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_LOW, (uint8_t)(sect_num >> 8));
328 ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_HIGH, (uint8_t)(sect_num >> 16));
329
330 if (ret != ERROR_OK)
331 return ret;
332
333 return target_write_u8(target, mg_task_reg + MG_REG_COMMAND, cmd);
334 }
335
336 static int mg_dsk_drv_info(void)
337 {
338 struct target *target = mflash_bank->target;
339 uint32_t mg_buff = mflash_bank->base + MG_BUFFER_OFFSET;
340 int ret;
341
342 if ((ret = mg_dsk_io_cmd(0, 1, mg_io_cmd_identify)) != ERROR_OK)
343 return ret;
344
345 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
346 if (ret != ERROR_OK)
347 return ret;
348
349 LOG_INFO("mflash: read drive info");
350
351 if (! mflash_bank->drv_info)
352 mflash_bank->drv_info = malloc(sizeof(struct mg_drv_info));
353
354 ret = target_read_memory(target, mg_buff, 2,
355 sizeof(mg_io_type_drv_info) >> 1,
356 (uint8_t *)&mflash_bank->drv_info->drv_id);
357 if (ret != ERROR_OK)
358 return ret;
359
360 mflash_bank->drv_info->tot_sects = (uint32_t)(mflash_bank->drv_info->drv_id.total_user_addressable_sectors_hi << 16)
361 + mflash_bank->drv_info->drv_id.total_user_addressable_sectors_lo;
362
363 return target_write_u8(target, mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, mg_io_cmd_confirm_read);
364 }
365
366 static int mg_mflash_rst(void)
367 {
368 int ret;
369
370 if ((ret = mg_init_gpio()) != ERROR_OK)
371 return ret;
372
373 if ((ret = mg_hdrst(0)) != ERROR_OK)
374 return ret;
375
376 if ((ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG)) != ERROR_OK)
377 return ret;
378
379 if ((ret = mg_hdrst(1)) != ERROR_OK)
380 return ret;
381
382 if ((ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG)) != ERROR_OK)
383 return ret;
384
385 if ((ret = mg_dsk_srst(1)) != ERROR_OK)
386 return ret;
387
388 if ((ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG)) != ERROR_OK)
389 return ret;
390
391 if ((ret = mg_dsk_srst(0)) != ERROR_OK)
392 return ret;
393
394 if ((ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG)) != ERROR_OK)
395 return ret;
396
397 LOG_INFO("mflash: reset ok");
398
399 return ERROR_OK;
400 }
401
402 static int mg_mflash_probe(void)
403 {
404 int ret;
405
406 if ((ret = mg_mflash_rst()) != ERROR_OK)
407 return ret;
408
409 return mg_dsk_drv_info();
410 }
411
412 COMMAND_HANDLER(mg_probe_cmd)
413 {
414 int ret;
415
416 ret = mg_mflash_probe();
417
418 if (ret == ERROR_OK) {
419 command_print(CMD_CTX, "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "",
420 mflash_bank->drv_info->tot_sects, mflash_bank->base);
421 }
422
423 return ret;
424 }
425
426 static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
427 {
428 uint32_t i, address;
429 int ret;
430 struct target *target = mflash_bank->target;
431 uint8_t *buff_ptr = buff;
432
433 if ((ret = mg_dsk_io_cmd(sect_num, sect_cnt, mg_io_cmd_read)) != ERROR_OK)
434 return ret;
435
436 address = mflash_bank->base + MG_BUFFER_OFFSET;
437
438 struct duration bench;
439 duration_start(&bench);
440
441 for (i = 0; i < sect_cnt; i++) {
442 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
443 if (ret != ERROR_OK)
444 return ret;
445
446 ret = target_read_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
447 if (ret != ERROR_OK)
448 return ret;
449
450 buff_ptr += MG_MFLASH_SECTOR_SIZE;
451
452 ret = target_write_u8(target, mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, mg_io_cmd_confirm_read);
453 if (ret != ERROR_OK)
454 return ret;
455
456 LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector read", sect_num + i, (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
457
458 ret = duration_measure(&bench);
459 if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
460 LOG_INFO("mflash: read %" PRIu32 "'th sectors", sect_num + i);
461 duration_start(&bench);
462 }
463 }
464
465 return mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
466 }
467
468 static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
469 {
470 uint32_t quotient, residue, i;
471 uint8_t *buff_ptr = buff;
472 int ret = ERROR_OK;
473
474 quotient = sect_cnt >> 8;
475 residue = sect_cnt % 256;
476
477 for (i = 0; i < quotient; i++) {
478 LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p",
479 sect_num, buff_ptr);
480 ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256);
481 if (ret != ERROR_OK)
482 return ret;
483
484 sect_num += 256;
485 buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
486 }
487
488 if (residue) {
489 LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %p",
490 sect_num, buff_ptr);
491 return mg_mflash_do_read_sects(buff_ptr, sect_num, residue);
492 }
493
494 return ret;
495 }
496
497 static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt,
498 mg_io_type_cmd cmd)
499 {
500 uint32_t i, address;
501 int ret;
502 struct target *target = mflash_bank->target;
503 uint8_t *buff_ptr = buff;
504
505 if ((ret = mg_dsk_io_cmd(sect_num, sect_cnt, cmd)) != ERROR_OK)
506 return ret;
507
508 address = mflash_bank->base + MG_BUFFER_OFFSET;
509
510 struct duration bench;
511 duration_start(&bench);
512
513 for (i = 0; i < sect_cnt; i++) {
514 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
515 if (ret != ERROR_OK)
516 return ret;
517
518 ret = target_write_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
519 if (ret != ERROR_OK)
520 return ret;
521
522 buff_ptr += MG_MFLASH_SECTOR_SIZE;
523
524 ret = target_write_u8(target, mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, mg_io_cmd_confirm_write);
525 if (ret != ERROR_OK)
526 return ret;
527
528 LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector write", sect_num + i, (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
529
530 ret = duration_measure(&bench);
531 if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
532 LOG_INFO("mflash: wrote %" PRIu32 "'th sectors", sect_num + i);
533 duration_start(&bench);
534 }
535 }
536
537 if (cmd == mg_io_cmd_write)
538 ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
539 else
540 ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_LONG);
541
542 return ret;
543 }
544
545 static int mg_mflash_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
546 {
547 uint32_t quotient, residue, i;
548 uint8_t *buff_ptr = buff;
549 int ret = ERROR_OK;
550
551 quotient = sect_cnt >> 8;
552 residue = sect_cnt % 256;
553
554 for (i = 0; i < quotient; i++) {
555 LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num,
556 buff_ptr);
557 ret = mg_mflash_do_write_sects(buff_ptr, sect_num, 256, mg_io_cmd_write);
558 if (ret != ERROR_OK)
559 return ret;
560
561 sect_num += 256;
562 buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
563 }
564
565 if (residue) {
566 LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num,
567 buff_ptr);
568 return mg_mflash_do_write_sects(buff_ptr, sect_num, residue, mg_io_cmd_write);
569 }
570
571 return ret;
572 }
573
574 static int mg_mflash_read (uint32_t addr, uint8_t *buff, uint32_t len)
575 {
576 uint8_t *buff_ptr = buff;
577 uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
578 uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
579 int ret = ERROR_OK;
580
581 cnt = 0;
582 cur_addr = addr;
583 end_addr = addr + len;
584
585 if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
586
587 next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
588 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
589 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
590 if (ret != ERROR_OK)
591 return ret;
592
593 if (end_addr < next_sec_addr) {
594 memcpy(buff_ptr, sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), end_addr - cur_addr);
595 LOG_DEBUG("mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "", end_addr - cur_addr, cur_addr);
596 cur_addr = end_addr;
597 } else {
598 memcpy(buff_ptr, sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), next_sec_addr - cur_addr);
599 LOG_DEBUG("mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "", next_sec_addr - cur_addr, cur_addr);
600 buff_ptr += (next_sec_addr - cur_addr);
601 cur_addr = next_sec_addr;
602 }
603 }
604
605 if (cur_addr < end_addr) {
606
607 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
608 next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
609
610 while (next_sec_addr <= end_addr) {
611 cnt++;
612 next_sec_addr += MG_MFLASH_SECTOR_SIZE;
613 }
614
615 if (cnt)
616 if ((ret = mg_mflash_read_sects(buff_ptr, sect_num, cnt)) != ERROR_OK)
617 return ret;
618
619 buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
620 cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
621
622 if (cur_addr < end_addr) {
623
624 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
625 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
626 if (ret != ERROR_OK)
627 return ret;
628
629 memcpy(buff_ptr, sect_buff, end_addr - cur_addr);
630 LOG_DEBUG("mflash: copies %u byte", (unsigned)(end_addr - cur_addr));
631
632 }
633 }
634
635 return ret;
636 }
637
638 static int mg_mflash_write(uint32_t addr, uint8_t *buff, uint32_t len)
639 {
640 uint8_t *buff_ptr = buff;
641 uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
642 uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
643 int ret = ERROR_OK;
644
645 cnt = 0;
646 cur_addr = addr;
647 end_addr = addr + len;
648
649 if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
650
651 next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
652 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
653 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
654 if (ret != ERROR_OK)
655 return ret;
656
657 if (end_addr < next_sec_addr) {
658 memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), buff_ptr, end_addr - cur_addr);
659 LOG_DEBUG("mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "", end_addr - cur_addr, cur_addr);
660 cur_addr = end_addr;
661 } else {
662 memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), buff_ptr, next_sec_addr - cur_addr);
663 LOG_DEBUG("mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "", next_sec_addr - cur_addr, cur_addr);
664 buff_ptr += (next_sec_addr - cur_addr);
665 cur_addr = next_sec_addr;
666 }
667
668 ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
669 if (ret != ERROR_OK)
670 return ret;
671 }
672
673 if (cur_addr < end_addr) {
674
675 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
676 next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
677
678 while (next_sec_addr <= end_addr) {
679 cnt++;
680 next_sec_addr += MG_MFLASH_SECTOR_SIZE;
681 }
682
683 if (cnt)
684 if ((ret = mg_mflash_write_sects(buff_ptr, sect_num, cnt)) != ERROR_OK)
685 return ret;
686
687 buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
688 cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
689
690 if (cur_addr < end_addr) {
691
692 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
693 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
694 if (ret != ERROR_OK)
695 return ret;
696
697 memcpy(sect_buff, buff_ptr, end_addr - cur_addr);
698 LOG_DEBUG("mflash: copies %" PRIu32 " byte", end_addr - cur_addr);
699 ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
700 }
701 }
702
703 return ret;
704 }
705
706 COMMAND_HANDLER(mg_write_cmd)
707 {
708 uint32_t address, cnt, res, i;
709 uint8_t *buffer;
710 struct fileio fileio;
711 int ret;
712
713 if (CMD_ARGC != 3) {
714 return ERROR_COMMAND_SYNTAX_ERROR;
715 }
716
717 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
718
719 ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
720 if (ret != ERROR_OK)
721 return ret;
722
723 int filesize;
724 buffer = malloc(MG_FILEIO_CHUNK);
725 if (!buffer) {
726 fileio_close(&fileio);
727 return ERROR_FAIL;
728 }
729 int retval = fileio_size(&fileio, &filesize);
730 if (retval != ERROR_OK) {
731 fileio_close(&fileio);
732 return retval;
733 }
734
735 cnt = filesize / MG_FILEIO_CHUNK;
736 res = filesize % MG_FILEIO_CHUNK;
737
738 struct duration bench;
739 duration_start(&bench);
740
741 size_t buf_cnt;
742 for (i = 0; i < cnt; i++) {
743 if ((ret = fileio_read(&fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt)) !=
744 ERROR_OK)
745 goto mg_write_cmd_err;
746 if ((ret = mg_mflash_write(address, buffer, MG_FILEIO_CHUNK)) != ERROR_OK)
747 goto mg_write_cmd_err;
748 address += MG_FILEIO_CHUNK;
749 }
750
751 if (res) {
752 if ((ret = fileio_read(&fileio, res, buffer, &buf_cnt)) != ERROR_OK)
753 goto mg_write_cmd_err;
754 if ((ret = mg_mflash_write(address, buffer, res)) != ERROR_OK)
755 goto mg_write_cmd_err;
756 }
757
758 if (duration_measure(&bench) == ERROR_OK)
759 {
760 command_print(CMD_CTX, "wrote %ld bytes from file %s "
761 "in %fs (%0.3f kB/s)", (long)filesize, CMD_ARGV[1],
762 duration_elapsed(&bench), duration_kbps(&bench, filesize));
763 }
764
765 free(buffer);
766 fileio_close(&fileio);
767
768 return ERROR_OK;
769
770 mg_write_cmd_err:
771 free(buffer);
772 fileio_close(&fileio);
773
774 return ret;
775 }
776
777 COMMAND_HANDLER(mg_dump_cmd)
778 {
779 uint32_t address, size, cnt, res, i;
780 uint8_t *buffer;
781 struct fileio fileio;
782 int ret;
783
784 if (CMD_ARGC != 4) {
785 return ERROR_COMMAND_SYNTAX_ERROR;
786 }
787
788 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
789 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], size);
790
791 ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
792 if (ret != ERROR_OK)
793 return ret;
794
795 buffer = malloc(MG_FILEIO_CHUNK);
796 if (!buffer) {
797 fileio_close(&fileio);
798 return ERROR_FAIL;
799 }
800
801 cnt = size / MG_FILEIO_CHUNK;
802 res = size % MG_FILEIO_CHUNK;
803
804 struct duration bench;
805 duration_start(&bench);
806
807 size_t size_written;
808 for (i = 0; i < cnt; i++) {
809 if ((ret = mg_mflash_read(address, buffer, MG_FILEIO_CHUNK)) != ERROR_OK)
810 goto mg_dump_cmd_err;
811 if ((ret = fileio_write(&fileio, MG_FILEIO_CHUNK, buffer, &size_written))
812 != ERROR_OK)
813 goto mg_dump_cmd_err;
814 address += MG_FILEIO_CHUNK;
815 }
816
817 if (res) {
818 if ((ret = mg_mflash_read(address, buffer, res)) != ERROR_OK)
819 goto mg_dump_cmd_err;
820 if ((ret = fileio_write(&fileio, res, buffer, &size_written)) != ERROR_OK)
821 goto mg_dump_cmd_err;
822 }
823
824 if (duration_measure(&bench) == ERROR_OK)
825 {
826 command_print(CMD_CTX, "dump image (address 0x%8.8" PRIx32 " "
827 "size %" PRIu32 ") to file %s in %fs (%0.3f kB/s)",
828 address, size, CMD_ARGV[1],
829 duration_elapsed(&bench), duration_kbps(&bench, size));
830 }
831
832 free(buffer);
833 fileio_close(&fileio);
834
835 return ERROR_OK;
836
837 mg_dump_cmd_err:
838 free(buffer);
839 fileio_close(&fileio);
840
841 return ret;
842 }
843
844 static int mg_set_feature(mg_feature_id feature, mg_feature_val config)
845 {
846 struct target *target = mflash_bank->target;
847 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
848 int ret;
849
850 if ((ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL))
851 != ERROR_OK)
852 return ret;
853
854 ret = target_write_u8(target, mg_task_reg + MG_REG_FEATURE, feature);
855 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, config);
856 ret |= target_write_u8(target, mg_task_reg + MG_REG_COMMAND,
857 mg_io_cmd_set_feature);
858
859 return ret;
860 }
861
862 static int mg_is_valid_pll(double XIN, int N, double CLK_OUT, int NO)
863 {
864 double v1 = XIN / N;
865 double v2 = CLK_OUT * NO;
866
867 if (v1 <1000000 || v1 > 15000000 || v2 < 100000000 || v2 > 500000000)
868 return ERROR_MG_INVALID_PLL;
869
870 return ERROR_OK;
871 }
872
873 static int mg_pll_get_M(unsigned short feedback_div)
874 {
875 int i, M;
876
877 for (i = 1, M = 0; i < 512; i <<= 1, feedback_div >>= 1)
878 M += (feedback_div & 1) * i;
879
880 return M + 2;
881 }
882
883 static int mg_pll_get_N(unsigned char input_div)
884 {
885 int i, N;
886
887 for (i = 1, N = 0; i < 32; i <<= 1, input_div >>= 1)
888 N += (input_div & 1) * i;
889
890 return N + 2;
891 }
892
893 static int mg_pll_get_NO(unsigned char output_div)
894 {
895 int i, NO;
896
897 for (i = 0, NO = 1; i < 2; ++i, output_div >>= 1)
898 if (output_div & 1)
899 NO = NO << 1;
900
901 return NO;
902 }
903
904 static double mg_do_calc_pll(double XIN, mg_pll_t * p_pll_val, int is_approximate)
905 {
906 unsigned short i;
907 unsigned char j, k;
908 int M, N, NO;
909 double CLK_OUT;
910 double DIV = 1;
911 double ROUND = 0;
912
913 if (is_approximate) {
914 DIV = 1000000;
915 ROUND = 500000;
916 }
917
918 for (i = 0; i < MG_PLL_MAX_FEEDBACKDIV_VAL ; ++i) {
919 M = mg_pll_get_M(i);
920
921 for (j = 0; j < MG_PLL_MAX_INPUTDIV_VAL ; ++j) {
922 N = mg_pll_get_N(j);
923
924 for (k = 0; k < MG_PLL_MAX_OUTPUTDIV_VAL ; ++k) {
925 NO = mg_pll_get_NO(k);
926
927 CLK_OUT = XIN * ((double)M / N) / NO;
928
929 if ((int)((CLK_OUT + ROUND) / DIV)
930 == (int)(MG_PLL_CLK_OUT / DIV)) {
931 if (mg_is_valid_pll(XIN, N, CLK_OUT, NO) == ERROR_OK)
932 {
933 p_pll_val->lock_cyc = (int)(XIN * MG_PLL_STD_LOCKCYCLE / MG_PLL_STD_INPUTCLK);
934 p_pll_val->feedback_div = i;
935 p_pll_val->input_div = j;
936 p_pll_val->output_div = k;
937
938 return CLK_OUT;
939 }
940 }
941 }
942 }
943 }
944
945 return 0;
946 }
947
948 static double mg_calc_pll(double XIN, mg_pll_t *p_pll_val)
949 {
950 double CLK_OUT;
951
952 CLK_OUT = mg_do_calc_pll(XIN, p_pll_val, 0);
953
954 if (!CLK_OUT)
955 return mg_do_calc_pll(XIN, p_pll_val, 1);
956 else
957 return CLK_OUT;
958 }
959
960 static int mg_verify_interface(void)
961 {
962 uint16_t buff[MG_MFLASH_SECTOR_SIZE >> 1];
963 uint16_t i, j;
964 uint32_t address = mflash_bank->base + MG_BUFFER_OFFSET;
965 struct target *target = mflash_bank->target;
966 int ret;
967
968 for (j = 0; j < 10; j++) {
969 for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++)
970 buff[i] = i;
971
972 ret = target_write_memory(target, address, 2,
973 MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
974 if (ret != ERROR_OK)
975 return ret;
976
977 memset(buff, 0xff, MG_MFLASH_SECTOR_SIZE);
978
979 ret = target_read_memory(target, address, 2,
980 MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
981 if (ret != ERROR_OK)
982 return ret;
983
984 for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++) {
985 if (buff[i] != i) {
986 LOG_ERROR("mflash: verify interface fail");
987 return ERROR_MG_INTERFACE;
988 }
989 }
990 }
991
992 LOG_INFO("mflash: verify interface ok");
993 return ret;
994 }
995
996 static const char g_strSEG_SerialNum[20] = {
997 'G','m','n','i','-','e','e','S','g','a','e','l',
998 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20
999 };
1000
1001 static const char g_strSEG_FWRev[8] = {
1002 'F','X','L','T','2','v','0','.'
1003 };
1004
1005 static const char g_strSEG_ModelNum[40] = {
1006 'F','X','A','L','H','S','2',0x20,'0','0','s','7',
1007 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
1008 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
1009 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20
1010 };
1011
1012 static void mg_gen_ataid(mg_io_type_drv_info *pSegIdDrvInfo)
1013 {
1014 /* b15 is ATA device(0) , b7 is Removable Media Device */
1015 pSegIdDrvInfo->general_configuration = 0x045A;
1016 /* 128MB : Cylinder=> 977 , Heads=> 8 , Sectors=> 32
1017 * 256MB : Cylinder=> 980 , Heads=> 16 , Sectors=> 32
1018 * 384MB : Cylinder=> 745 , Heads=> 16 , Sectors=> 63
1019 */
1020 pSegIdDrvInfo->number_of_cylinders = 0x02E9;
1021 pSegIdDrvInfo->reserved1 = 0x0;
1022 pSegIdDrvInfo->number_of_heads = 0x10;
1023 pSegIdDrvInfo->unformatted_bytes_per_track = 0x0;
1024 pSegIdDrvInfo->unformatted_bytes_per_sector = 0x0;
1025 pSegIdDrvInfo->sectors_per_track = 0x3F;
1026 pSegIdDrvInfo->vendor_unique1[0] = 0x000B;
1027 pSegIdDrvInfo->vendor_unique1[1] = 0x7570;
1028 pSegIdDrvInfo->vendor_unique1[2] = 0x8888;
1029
1030 memcpy(pSegIdDrvInfo->serial_number, (void *)g_strSEG_SerialNum,20);
1031 /* 0x2 : dual buffer */
1032 pSegIdDrvInfo->buffer_type = 0x2;
1033 /* buffer size : 2KB */
1034 pSegIdDrvInfo->buffer_sector_size = 0x800;
1035 pSegIdDrvInfo->number_of_ecc_bytes = 0;
1036
1037 memcpy(pSegIdDrvInfo->firmware_revision, (void *)g_strSEG_FWRev,8);
1038
1039 memcpy(pSegIdDrvInfo->model_number, (void *)g_strSEG_ModelNum,40);
1040
1041 pSegIdDrvInfo->maximum_block_transfer = 0x4;
1042 pSegIdDrvInfo->vendor_unique2 = 0x0;
1043 pSegIdDrvInfo->dword_io = 0x00;
1044 /* b11 : IORDY support(PIO Mode 4), b10 : Disable/Enbale IORDY
1045 * b9 : LBA support, b8 : DMA mode support
1046 */
1047 pSegIdDrvInfo->capabilities = 0x1 << 9;
1048
1049 pSegIdDrvInfo->reserved2 = 0x4000;
1050 pSegIdDrvInfo->vendor_unique3 = 0x00;
1051 /* PIOMode-2 support */
1052 pSegIdDrvInfo->pio_cycle_timing_mode = 0x02;
1053 pSegIdDrvInfo->vendor_unique4 = 0x00;
1054 /* MultiWord-2 support */
1055 pSegIdDrvInfo->dma_cycle_timing_mode = 0x00;
1056 /* b1 : word64~70 is valid
1057 * b0 : word54~58 are valid and reflect the current numofcyls,heads,sectors
1058 * b2 : If device supports Ultra DMA , set to one to vaildate word88
1059 */
1060 pSegIdDrvInfo->translation_fields_valid = (0x1 << 1) | (0x1 << 0);
1061 pSegIdDrvInfo->number_of_current_cylinders = 0x02E9;
1062 pSegIdDrvInfo->number_of_current_heads = 0x10;
1063 pSegIdDrvInfo->current_sectors_per_track = 0x3F;
1064 pSegIdDrvInfo->current_sector_capacity_lo = 0x7570;
1065 pSegIdDrvInfo->current_sector_capacity_hi = 0x000B;
1066
1067 pSegIdDrvInfo->multi_sector_count = 0x04;
1068 /* b8 : Multiple secotr setting valid , b[7:0] num of secotrs per block */
1069 pSegIdDrvInfo->multi_sector_setting_valid = 0x01;
1070 pSegIdDrvInfo->total_user_addressable_sectors_lo = 0x7570;
1071 pSegIdDrvInfo->total_user_addressable_sectors_hi = 0x000B;
1072 pSegIdDrvInfo->single_dma_modes_supported = 0x00;
1073 pSegIdDrvInfo->single_dma_transfer_active = 0x00;
1074 /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
1075 pSegIdDrvInfo->multi_dma_modes_supported = (0x1 << 0);
1076 /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
1077 pSegIdDrvInfo->multi_dma_transfer_active = (0x1 << 0);
1078 /* b0 : PIO Mode-3 support, b1 : PIO Mode-4 support */
1079 pSegIdDrvInfo->adv_pio_mode = 0x00;
1080 /* 480(0x1E0)nsec for Multi-word DMA mode0
1081 * 150(0x96) nsec for Multi-word DMA mode1
1082 * 120(0x78) nsec for Multi-word DMA mode2
1083 */
1084 pSegIdDrvInfo->min_dma_cyc = 0x1E0;
1085 pSegIdDrvInfo->recommend_dma_cyc = 0x1E0;
1086 pSegIdDrvInfo->min_pio_cyc_no_iordy = 0x1E0;
1087 pSegIdDrvInfo->min_pio_cyc_with_iordy = 0x1E0;
1088 memset((void *)pSegIdDrvInfo->reserved3, 0x00, 22);
1089 /* b7 : ATA/ATAPI-7 ,b6 : ATA/ATAPI-6 ,b5 : ATA/ATAPI-5,b4 : ATA/ATAPI-4 */
1090 pSegIdDrvInfo->major_ver_num = 0x7E;
1091 /* 0x1C : ATA/ATAPI-6 T13 1532D revision1 */
1092 pSegIdDrvInfo->minor_ver_num = 0x19;
1093 /* NOP/READ BUFFER/WRITE BUFFER/Power management feature set support */
1094 pSegIdDrvInfo->feature_cmd_set_suprt0 = 0x7068;
1095 /* Features/command set is valid/Advanced Pwr management/CFA feature set
1096 * not support
1097 */
1098 pSegIdDrvInfo->feature_cmd_set_suprt1 = 0x400C;
1099 pSegIdDrvInfo->feature_cmd_set_suprt2 = 0x4000;
1100 /* READ/WRITE BUFFER/PWR Management enable */
1101 pSegIdDrvInfo->feature_cmd_set_en0 = 0x7000;
1102 /* CFA feature is disabled / Advancde power management disable */
1103 pSegIdDrvInfo->feature_cmd_set_en1 = 0x0;
1104 pSegIdDrvInfo->feature_cmd_set_en2 = 0x4000;
1105 pSegIdDrvInfo->reserved4 = 0x0;
1106 /* 0x1 * 2minutes */
1107 pSegIdDrvInfo->req_time_for_security_er_done = 0x19;
1108 pSegIdDrvInfo->req_time_for_enhan_security_er_done = 0x19;
1109 /* Advanced power management level 1 */
1110 pSegIdDrvInfo->adv_pwr_mgm_lvl_val = 0x0;
1111 pSegIdDrvInfo->reserved5 = 0x0;
1112 memset((void *)pSegIdDrvInfo->reserved6, 0x00, 68);
1113 /* Security mode feature is disabled */
1114 pSegIdDrvInfo->security_stas = 0x0;
1115 memset((void *)pSegIdDrvInfo->vendor_uniq_bytes, 0x00, 62);
1116 /* CFA power mode 1 support in maximum 200mA */
1117 pSegIdDrvInfo->cfa_pwr_mode = 0x0100;
1118 memset((void *)pSegIdDrvInfo->reserved7, 0x00, 190);
1119 }
1120
1121 static int mg_storage_config(void)
1122 {
1123 uint8_t buff[512];
1124 int ret;
1125
1126 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd))
1127 != ERROR_OK)
1128 return ret;
1129
1130 mg_gen_ataid((mg_io_type_drv_info *)(void *)buff);
1131
1132 if ((ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_stgdrvinfo))
1133 != ERROR_OK)
1134 return ret;
1135
1136 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default))
1137 != ERROR_OK)
1138 return ret;
1139
1140 LOG_INFO("mflash: storage config ok");
1141 return ret;
1142 }
1143
1144 static int mg_boot_config(void)
1145 {
1146 uint8_t buff[512];
1147 int ret;
1148
1149 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd))
1150 != ERROR_OK)
1151 return ret;
1152
1153 memset(buff, 0xff, 512);
1154
1155 buff[0] = mg_op_mode_snd; /* operation mode */
1156 buff[1] = MG_UNLOCK_OTP_AREA;
1157 buff[2] = 4; /* boot size */
1158 *((uint32_t *)(void *)(buff + 4)) = 0; /* XIP size */
1159
1160 if ((ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_xipinfo))
1161 != ERROR_OK)
1162 return ret;
1163
1164 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default))
1165 != ERROR_OK)
1166 return ret;
1167
1168 LOG_INFO("mflash: boot config ok");
1169 return ret;
1170 }
1171
1172 static int mg_set_pll(mg_pll_t *pll)
1173 {
1174 uint8_t buff[512];
1175 int ret;
1176
1177 memset(buff, 0xff, 512);
1178 /* PLL Lock cycle and Feedback 9bit Divider */
1179 memcpy(buff, &pll->lock_cyc, sizeof(uint32_t));
1180 memcpy(buff + 4, &pll->feedback_div, sizeof(uint16_t));
1181 buff[6] = pll->input_div; /* PLL Input 5bit Divider */
1182 buff[7] = pll->output_div; /* PLL Output Divider */
1183
1184 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd))
1185 != ERROR_OK)
1186 return ret;
1187
1188 if ((ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_wr_pll))
1189 != ERROR_OK)
1190 return ret;
1191
1192 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default))
1193 != ERROR_OK)
1194 return ret;
1195
1196 LOG_INFO("mflash: set pll ok");
1197 return ret;
1198 }
1199
1200 static int mg_erase_nand(void)
1201 {
1202 int ret;
1203
1204 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd))
1205 != ERROR_OK)
1206 return ret;
1207
1208 if ((ret = mg_mflash_do_write_sects(NULL, 0, 0, mg_vcmd_purge_nand))
1209 != ERROR_OK)
1210 return ret;
1211
1212 if ((ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default))
1213 != ERROR_OK)
1214 return ret;
1215
1216 LOG_INFO("mflash: erase nand ok");
1217 return ret;
1218 }
1219
1220 COMMAND_HANDLER(mg_config_cmd)
1221 {
1222 double fin, fout;
1223 mg_pll_t pll;
1224 int ret;
1225
1226 if ((ret = mg_verify_interface()) != ERROR_OK)
1227 return ret;
1228
1229 if ((ret = mg_mflash_rst()) != ERROR_OK)
1230 return ret;
1231
1232 switch (CMD_ARGC) {
1233 case 2:
1234 if (!strcmp(CMD_ARGV[1], "boot"))
1235 return mg_boot_config();
1236 else if (!strcmp(CMD_ARGV[1], "storage"))
1237 return mg_storage_config();
1238 else
1239 return ERROR_COMMAND_NOTFOUND;
1240 break;
1241 case 3:
1242 if (!strcmp(CMD_ARGV[1], "pll")) {
1243 unsigned long freq;
1244 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], freq);
1245 fin = freq;
1246
1247 if (fin > MG_PLL_CLK_OUT) {
1248 LOG_ERROR("mflash: input freq. is too large");
1249 return ERROR_MG_INVALID_OSC;
1250 }
1251
1252 fout = mg_calc_pll(fin, &pll);
1253
1254 if (!fout) {
1255 LOG_ERROR("mflash: cannot generate valid pll");
1256 return ERROR_MG_INVALID_PLL;
1257 }
1258
1259 LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u,"
1260 "indiv=%u, outdiv=%u, lock=%u",
1261 (uint32_t)fout, pll.feedback_div,
1262 pll.input_div, pll.output_div,
1263 pll.lock_cyc);
1264
1265 if ((ret = mg_erase_nand()) != ERROR_OK)
1266 return ret;
1267
1268 return mg_set_pll(&pll);
1269 } else
1270 return ERROR_COMMAND_NOTFOUND;
1271 break;
1272 default:
1273 return ERROR_COMMAND_SYNTAX_ERROR;
1274 }
1275 }
1276
1277 static const struct command_registration mflash_exec_command_handlers[] = {
1278 {
1279 .name = "probe",
1280 .handler = mg_probe_cmd,
1281 .mode = COMMAND_EXEC,
1282 .help = "Detect bank configuration information",
1283 },
1284 {
1285 .name = "write",
1286 .handler = mg_write_cmd,
1287 .mode = COMMAND_EXEC,
1288 /* FIXME bank_num is unused */
1289 .usage = "bank_num filename address",
1290 .help = "Write binary file at the specified address.",
1291 },
1292 {
1293 .name = "dump",
1294 .handler = mg_dump_cmd,
1295 .mode = COMMAND_EXEC,
1296 /* FIXME bank_num is unused */
1297 .usage = "bank_num filename address size",
1298 .help = "Write specified number of bytes from a binary file "
1299 "to the specified, address.",
1300 },
1301 {
1302 .name = "config",
1303 .handler = mg_config_cmd,
1304 .mode = COMMAND_EXEC,
1305 .help = "Configure MFLASH options.",
1306 .usage = "('boot'|'storage'|'pll' frequency)",
1307 },
1308 COMMAND_REGISTRATION_DONE
1309 };
1310
1311 static int mflash_init_drivers(struct command_context *cmd_ctx)
1312 {
1313 if (!mflash_bank)
1314 return ERROR_OK;
1315 return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers);
1316 }
1317
1318 COMMAND_HANDLER(handle_mflash_init_command)
1319 {
1320 if (CMD_ARGC != 0)
1321 return ERROR_COMMAND_SYNTAX_ERROR;
1322
1323 static bool mflash_initialized = false;
1324 if (mflash_initialized)
1325 {
1326 LOG_INFO("'mflash init' has already been called");
1327 return ERROR_OK;
1328 }
1329 mflash_initialized = true;
1330
1331 LOG_DEBUG("Initializing mflash devices...");
1332 return mflash_init_drivers(CMD_CTX);
1333 }
1334
1335 COMMAND_HANDLER(mg_bank_cmd)
1336 {
1337 struct target *target;
1338 int i;
1339
1340 if (CMD_ARGC < 4)
1341 {
1342 return ERROR_COMMAND_SYNTAX_ERROR;
1343 }
1344
1345 if ((target = get_target(CMD_ARGV[3])) == NULL)
1346 {
1347 LOG_ERROR("target '%s' not defined", CMD_ARGV[3]);
1348 return ERROR_FAIL;
1349 }
1350
1351 mflash_bank = calloc(sizeof(struct mflash_bank), 1);
1352 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], mflash_bank->base);
1353 /// @todo Verify how this parsing should work, then document it.
1354 char *str;
1355 mflash_bank->rst_pin.num = strtoul(CMD_ARGV[2], &str, 0);
1356 if (*str)
1357 mflash_bank->rst_pin.port[0] = (uint16_t)
1358 tolower((unsigned)str[0]);
1359
1360 mflash_bank->target = target;
1361
1362 for (i = 0; mflash_gpio[i] ; i++) {
1363 if (! strcmp(mflash_gpio[i]->name, CMD_ARGV[0])) {
1364 mflash_bank->gpio_drv = mflash_gpio[i];
1365 }
1366 }
1367
1368 if (! mflash_bank->gpio_drv) {
1369 LOG_ERROR("%s is unsupported soc", CMD_ARGV[0]);
1370 return ERROR_MG_UNSUPPORTED_SOC;
1371 }
1372
1373 return ERROR_OK;
1374 }
1375
1376 static const struct command_registration mflash_config_command_handlers[] = {
1377 {
1378 .name = "bank",
1379 .handler = mg_bank_cmd,
1380 .mode = COMMAND_CONFIG,
1381 .help = "configure a mflash device bank",
1382 .usage = "soc_type base_addr pin_id target",
1383 },
1384 {
1385 .name = "init",
1386 .mode = COMMAND_CONFIG,
1387 .handler = handle_mflash_init_command,
1388 .help = "initialize mflash devices",
1389 },
1390 COMMAND_REGISTRATION_DONE
1391 };
1392 static const struct command_registration mflash_command_handler[] = {
1393 {
1394 .name = "mflash",
1395 .mode = COMMAND_ANY,
1396 .help = "mflash command group",
1397 .chain = mflash_config_command_handlers,
1398 },
1399 COMMAND_REGISTRATION_DONE
1400 };
1401 int mflash_register_commands(struct command_context *cmd_ctx)
1402 {
1403 return register_commands(cmd_ctx, NULL, mflash_command_handler);
1404 }

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)