flash: Add support for Atheros (ath79) SPI interface
[openocd.git] / src / flash / nor / ath79.c
1 /***************************************************************************
2 * Copyright (C) 2015 by Tobias Diedrich *
3 * <ranma+openwrt@tdiedrich.de> *
4 * *
5 * based on the stmsmi code written by Antonio Borneo *
6 * <borneo.antonio@gmail.com> *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc. *
21 * *
22 ***************************************************************************/
23 /*
24 * Driver for the Atheros AR7xxx/AR9xxx SPI flash interface.
25 *
26 * Since no SPI mode register is present, presumably only
27 * SPI "mode 3" (CPOL=1 and CPHA=1) is supported.
28 *
29 * The SPI interface supports up to 3 chip selects, however the SPI flash
30 * used for booting the system must be connected to CS0.
31 *
32 * On boot, the first 4MiB of flash space are memory-mapped into the
33 * area bf000000 - bfffffff (4 copies), so the MIPS bootstrap
34 * vector bfc00000 is mapped to the beginning of the flash.
35 *
36 * By writing a 1 to the REMAP_DISABLE bit in the SPI_CONTROL register,
37 * the full area of 16MiB is mapped.
38 *
39 * By writing a 0 to the SPI_FUNCTION_SELECT register (write-only dword
40 * register @bf000000), memory mapping is disabled and the SPI registers
41 * are exposed to the CPU instead:
42 * bf000000 SPI_FUNCTION_SELECT
43 * bf000004 SPI_CONTROL
44 * bf000008 SPI_IO_CONTROL
45 * bf00000c SPI_READ_DATA
46 *
47 * When not memory-mapped, the SPI interface is essentially bitbanged
48 * using SPI_CONTROL and SPI_IO_CONTROL with the only hardware-assistance
49 * being the 32bit read-only shift-register SPI_READ_DATA.
50 */
51
52 #ifdef HAVE_CONFIG_H
53 #include "config.h"
54 #endif
55
56 #include "imp.h"
57 #include "spi.h"
58 #include <jtag/jtag.h>
59 #include <helper/time_support.h>
60 #include <helper/types.h>
61 #include <target/mips32.h>
62 #include <target/mips32_pracc.h>
63 #include <target/target.h>
64
65 #define BITS_PER_BYTE 8
66
67 #define ATH79_REG_FS 0
68 #define ATH79_REG_CLOCK 4
69 #define ATH79_REG_WRITE 8
70 #define ATH79_REG_DATA 12
71
72 #define ATH79_SPI_CS_ALLHI 0x70000
73 #define ATH79_SPI_CS0_HI 0x10000
74 #define ATH79_SPI_CS1_HI 0x20000
75 #define ATH79_SPI_CS2_HI 0x40000
76 #define ATH79_SPI_CE_HI 0x00100
77 #define ATH79_SPI_DO_HI 0x00001
78
79 #define ATH79_XFER_FINAL 0x00000001
80 #define ATH79_XFER_PARTIAL 0x00000000
81
82 /* Timeout in ms */
83 #define ATH79_MAX_TIMEOUT (3000)
84
85 struct ath79_spi_ctx {
86 uint8_t *page_buf;
87 int pre_deselect;
88 int post_deselect;
89 };
90
91 struct ath79_flash_bank {
92 int probed;
93 int chipselect;
94 uint32_t io_base;
95 const struct flash_device *dev;
96 struct ath79_spi_ctx spi;
97 };
98
99 struct ath79_target {
100 char *name;
101 uint32_t tap_idcode;
102 uint32_t io_base;
103 };
104
105 static const struct ath79_target target_devices[] = {
106 /* name, tap_idcode, io_base */
107 { "ATH79", 0x00000001, 0xbf000000 },
108 { NULL, 0, 0 }
109 };
110
111 static const uint32_t ath79_chipselects[] = {
112 (~ATH79_SPI_CS0_HI & ATH79_SPI_CS_ALLHI),
113 (~ATH79_SPI_CS1_HI & ATH79_SPI_CS_ALLHI),
114 (~ATH79_SPI_CS2_HI & ATH79_SPI_CS_ALLHI),
115 };
116
117 static void ath79_pracc_addn(struct pracc_queue_info *ctx,
118 const uint32_t *instr,
119 int n)
120 {
121 for (int i = 0; i < n; i++)
122 pracc_add(ctx, 0, instr[i]);
123 }
124
125 static int ath79_spi_bitbang_codegen(struct ath79_flash_bank *ath79_info,
126 struct pracc_queue_info *ctx,
127 uint8_t *data, int len,
128 int partial_xfer)
129 {
130 uint32_t cs_high = ATH79_SPI_CS_ALLHI;
131 uint32_t cs_low = ath79_chipselects[ath79_info->chipselect];
132 uint32_t clock_high = cs_low | ATH79_SPI_CE_HI;
133 uint32_t clock_low = cs_low;
134 uint32_t pracc_out = 0;
135 uint32_t io_base = ath79_info->io_base;
136
137 const uint32_t preamble1[] = {
138 /* $15 = MIPS32_PRACC_BASE_ADDR */
139 MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR),
140 /* $1 = io_base */
141 MIPS32_LUI(1, UPPER16(io_base)),
142 };
143 ath79_pracc_addn(ctx, preamble1, ARRAY_SIZE(preamble1));
144 if (ath79_info->spi.pre_deselect) {
145 /* Clear deselect flag so we don't deselect again if
146 * this is a partial xfer.
147 */
148 ath79_info->spi.pre_deselect = 0;
149 const uint32_t pre_deselect[] = {
150 /* [$1 + FS] = 1 (enable flash io register access) */
151 MIPS32_LUI(2, UPPER16(1)),
152 MIPS32_ORI(2, 2, LOWER16(1)),
153 MIPS32_SW(2, ATH79_REG_FS, 1),
154 /* deselect flash just in case */
155 /* $2 = SPI_CS_DIS */
156 MIPS32_LUI(2, UPPER16(cs_high)),
157 MIPS32_ORI(2, 2, LOWER16(cs_high)),
158 /* [$1 + WRITE] = $2 */
159 MIPS32_SW(2, ATH79_REG_WRITE, 1),
160 };
161 ath79_pracc_addn(ctx, pre_deselect, ARRAY_SIZE(pre_deselect));
162 }
163 const uint32_t preamble2[] = {
164 /* t0 = CLOCK_LOW + 0-bit */
165 MIPS32_LUI(8, UPPER16((clock_low + 0))),
166 MIPS32_ORI(8, 8, LOWER16((clock_low + 0))),
167 /* t1 = CLOCK_LOW + 1-bit */
168 MIPS32_LUI(9, UPPER16((clock_low + 1))),
169 MIPS32_ORI(9, 9, LOWER16((clock_low + 1))),
170 /* t2 = CLOCK_HIGH + 0-bit */
171 MIPS32_LUI(10, UPPER16((clock_high + 0))),
172 MIPS32_ORI(10, 10, LOWER16((clock_high + 0))),
173 /* t3 = CLOCK_HIGH + 1-bit */
174 MIPS32_LUI(11, UPPER16((clock_high + 1))),
175 MIPS32_ORI(11, 11, LOWER16((clock_high + 1))),
176 };
177 ath79_pracc_addn(ctx, preamble2, ARRAY_SIZE(preamble2));
178
179 for (int i = 0; i < len; i++) {
180 uint8_t x = data[i];
181
182 /* Generate bitbang code for one byte, highest bit first .*/
183 for (int j = BITS_PER_BYTE - 1; j >= 0; j--) {
184 int bit = ((x >> j) & 1);
185
186 if (bit) {
187 /* [$1 + WRITE] = t1 */
188 pracc_add(ctx, 0,
189 MIPS32_SW(9, ATH79_REG_WRITE, 1));
190 /* [$1 + WRITE] = t3 */
191 pracc_add(ctx, 0,
192 MIPS32_SW(11, ATH79_REG_WRITE, 1));
193 } else {
194 /* [$1 + WRITE] = t0 */
195 pracc_add(ctx, 0,
196 MIPS32_SW(8, ATH79_REG_WRITE, 1));
197 /* [$1 + WRITE] = t2 */
198 pracc_add(ctx, 0,
199 MIPS32_SW(10, ATH79_REG_WRITE, 1));
200 }
201 }
202 if (i % 4 == 3) {
203 /* $3 = [$1 + DATA] */
204 pracc_add(ctx, 0, MIPS32_LW(3, ATH79_REG_DATA, 1));
205 /* [OUTi] = $3 */
206 pracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,
207 MIPS32_SW(3, PRACC_OUT_OFFSET +
208 pracc_out, 15));
209 pracc_out += 4;
210 }
211 }
212 if (len & 3) { /* not a multiple of 4 bytes */
213 /* $3 = [$1 + DATA] */
214 pracc_add(ctx, 0, MIPS32_LW(3, ATH79_REG_DATA, 1));
215 /* [OUTi] = $3 */
216 pracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,
217 MIPS32_SW(3, PRACC_OUT_OFFSET + pracc_out, 15));
218 pracc_out += 4;
219 }
220
221 if (ath79_info->spi.post_deselect && !partial_xfer) {
222 const uint32_t post_deselect[] = {
223 /* $2 = SPI_CS_DIS */
224 MIPS32_LUI(2, UPPER16(cs_high)),
225 MIPS32_ORI(2, 2, LOWER16(cs_high)),
226 /* [$1 + WRITE] = $2 */
227 MIPS32_SW(2, ATH79_REG_WRITE, 1),
228
229 /* [$1 + FS] = 0 (disable flash io register access) */
230 MIPS32_XORI(2, 2, 0),
231 MIPS32_SW(2, ATH79_REG_FS, 1),
232 };
233 ath79_pracc_addn(ctx, post_deselect, ARRAY_SIZE(post_deselect));
234 }
235
236 /* common pracc epilogue */
237 /* jump to start */
238 pracc_add(ctx, 0, MIPS32_B(NEG16(ctx->code_count + 1)));
239 /* restore $15 from DeSave */
240 pracc_add(ctx, 0, MIPS32_MFC0(15, 31, 0));
241
242 return pracc_out / 4;
243 }
244
245 static int ath79_spi_bitbang_chunk(struct flash_bank *bank,
246 uint8_t *data, int len, int *transferred)
247 {
248 struct target *target = bank->target;
249 struct ath79_flash_bank *ath79_info = bank->driver_priv;
250 struct mips32_common *mips32 = target_to_mips32(target);
251 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
252 int pracc_words;
253
254 /*
255 * These constants must match the worst case in the above code
256 * generator function ath79_spi_bitbang_codegen.
257 */
258 const int pracc_pre_post = 26;
259 const int pracc_loop_byte = 8 * 2 + 2;
260
261 struct pracc_queue_info ctx = {
262 .max_code = PRACC_MAX_INSTRUCTIONS
263 };
264 int max_len = (ctx.max_code - pracc_pre_post) / pracc_loop_byte;
265 int to_xfer = len > max_len ? max_len : len;
266 int partial_xfer = len != to_xfer;
267 int padded_len = (to_xfer + 3) & ~3;
268 uint32_t *out = malloc(padded_len);
269
270 if (!out) {
271 LOG_ERROR("not enough memory");
272 return ERROR_FAIL;
273 }
274
275 *transferred = 0;
276 pracc_queue_init(&ctx);
277 if (ctx.retval != ERROR_OK)
278 goto exit;
279
280 LOG_DEBUG("ath79_spi_bitbang_bytes(%p, %08x, %p, %d)",
281 target, ath79_info->io_base, data, len);
282
283 LOG_DEBUG("max code %d => max len %d. to_xfer %d",
284 ctx.max_code, max_len, to_xfer);
285
286 pracc_words = ath79_spi_bitbang_codegen(
287 ath79_info, &ctx, data, to_xfer, partial_xfer);
288
289 LOG_DEBUG("Assembled %d instructions, %d stores",
290 ctx.code_count, ctx.store_count);
291
292 ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, out);
293 if (ctx.retval != ERROR_OK)
294 goto exit;
295
296 if (to_xfer & 3) { /* Not a multiple of 4 bytes. */
297 /*
298 * Need to realign last word since we didn't shift the
299 * full 32 bits.
300 */
301 int missed_bytes = 4 - (to_xfer & 3);
302
303 out[pracc_words - 1] <<= BITS_PER_BYTE * missed_bytes;
304 }
305
306 /*
307 * pracc reads return uint32_t in host endianness, convert to
308 * target endianness.
309 * Since we know the ATH79 target is big endian and the SPI
310 * shift register has the bytes in highest to lowest bit order,
311 * this will ensure correct memory byte order regardless of host
312 * endianness.
313 */
314 target_buffer_set_u32_array(target, (uint8_t *)out, pracc_words, out);
315
316 if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
317 for (int i = 0; i < to_xfer; i++) {
318 LOG_DEBUG("bitbang %02x => %02x",
319 data[i], ((uint8_t *)out)[i]);
320 }
321 }
322 memcpy(data, out, to_xfer);
323 *transferred = to_xfer;
324
325 exit:
326 pracc_queue_free(&ctx);
327 free(out);
328 return ctx.retval;
329 }
330
331 static void ath79_spi_bitbang_prepare(struct flash_bank *bank)
332 {
333 struct ath79_flash_bank *ath79_info = bank->driver_priv;
334
335 ath79_info->spi.pre_deselect = 1;
336 }
337
338 static int ath79_spi_bitbang_bytes(struct flash_bank *bank,
339 uint8_t *data, int len, uint32_t flags)
340 {
341 struct ath79_flash_bank *ath79_info = bank->driver_priv;
342 int retval;
343 int transferred;
344
345 ath79_info->spi.post_deselect = !!(flags & ATH79_XFER_FINAL);
346
347 do {
348 transferred = 0;
349 retval = ath79_spi_bitbang_chunk(
350 bank, data, len, &transferred);
351 if (retval != ERROR_OK)
352 return retval;
353
354 data += transferred;
355 len -= transferred;
356 } while (len > 0);
357
358 return ERROR_OK;
359 }
360
361 FLASH_BANK_COMMAND_HANDLER(ath79_flash_bank_command)
362 {
363 struct ath79_flash_bank *ath79_info;
364 int chipselect = 0;
365
366 LOG_DEBUG("%s", __func__);
367
368 if (CMD_ARGC < 6 || CMD_ARGC > 7)
369 return ERROR_COMMAND_SYNTAX_ERROR;
370
371 if (CMD_ARGC == 7) {
372 if (strcmp(CMD_ARGV[6], "cs0") == 0)
373 chipselect = 0; /* default */
374 else if (strcmp(CMD_ARGV[6], "cs1") == 0)
375 chipselect = 1;
376 else if (strcmp(CMD_ARGV[6], "cs2") == 0)
377 chipselect = 2;
378 else {
379 LOG_ERROR("Unknown arg: %s", CMD_ARGV[6]);
380 return ERROR_COMMAND_SYNTAX_ERROR;
381 }
382 }
383
384 ath79_info = calloc(1, sizeof(struct ath79_flash_bank));
385 if (!ath79_info) {
386 LOG_ERROR("not enough memory");
387 return ERROR_FAIL;
388 }
389
390 ath79_info->chipselect = chipselect;
391 bank->driver_priv = ath79_info;
392
393 return ERROR_OK;
394 }
395
396 /* Read the status register of the external SPI flash chip. */
397 static int read_status_reg(struct flash_bank *bank, uint32_t *status)
398 {
399 uint8_t spi_bytes[] = {SPIFLASH_READ_STATUS, 0};
400 int retval;
401
402 /* Send SPI command "read STATUS" */
403 ath79_spi_bitbang_prepare(bank);
404 retval = ath79_spi_bitbang_bytes(
405 bank, spi_bytes, sizeof(spi_bytes),
406 ATH79_XFER_FINAL);
407
408 *status = spi_bytes[1];
409
410 return retval;
411 }
412
413 /* check for WIP (write in progress) bit in status register */
414 /* timeout in ms */
415 static int wait_till_ready(struct flash_bank *bank, int timeout)
416 {
417 uint32_t status;
418 int retval;
419 long long endtime;
420
421 endtime = timeval_ms() + timeout;
422 do {
423 /* read flash status register */
424 retval = read_status_reg(bank, &status);
425 if (retval != ERROR_OK)
426 return retval;
427
428 if ((status & SPIFLASH_BSY_BIT) == 0)
429 return ERROR_OK;
430 alive_sleep(1);
431 } while (timeval_ms() < endtime);
432
433 LOG_ERROR("timeout");
434 return ERROR_FAIL;
435 }
436
437 /* Send "write enable" command to SPI flash chip. */
438 static int ath79_write_enable(struct flash_bank *bank)
439 {
440 uint32_t status;
441 int retval;
442
443 uint8_t spi_bytes[] = {SPIFLASH_WRITE_ENABLE};
444
445 /* Send SPI command "write enable" */
446 ath79_spi_bitbang_prepare(bank);
447 retval = ath79_spi_bitbang_bytes(
448 bank, spi_bytes, sizeof(spi_bytes),
449 ATH79_XFER_FINAL);
450 if (retval != ERROR_OK)
451 return retval;
452
453 /* read flash status register */
454 retval = read_status_reg(bank, &status);
455 if (retval != ERROR_OK)
456 return retval;
457
458 /* Check write enabled */
459 if ((status & SPIFLASH_WE_BIT) == 0) {
460 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32,
461 status);
462 return ERROR_FAIL;
463 }
464
465 return ERROR_OK;
466 }
467
468 static int erase_command(struct flash_bank *bank, int sector)
469 {
470 struct ath79_flash_bank *ath79_info = bank->driver_priv;
471 uint32_t offset = bank->sectors[sector].offset;
472
473 uint8_t spi_bytes[] = {
474 ath79_info->dev->erase_cmd,
475 offset >> 16,
476 offset >> 8,
477 offset
478 };
479
480 /* bitbang command */
481 ath79_spi_bitbang_prepare(bank);
482 return ath79_spi_bitbang_bytes(
483 bank, spi_bytes, sizeof(spi_bytes),
484 ATH79_XFER_FINAL);
485 }
486
487 static int ath79_erase_sector(struct flash_bank *bank, int sector)
488 {
489 int retval = ath79_write_enable(bank);
490
491 if (retval != ERROR_OK)
492 return retval;
493
494 /* send SPI command "block erase" */
495 retval = erase_command(bank, sector);
496 if (retval != ERROR_OK)
497 return retval;
498
499 /* poll WIP for end of self timed Sector Erase cycle */
500 return wait_till_ready(bank, ATH79_MAX_TIMEOUT);
501 }
502
503 static int ath79_erase(struct flash_bank *bank, int first, int last)
504 {
505 struct target *target = bank->target;
506 struct ath79_flash_bank *ath79_info = bank->driver_priv;
507 int retval = ERROR_OK;
508 int sector;
509
510 LOG_DEBUG("%s: from sector %d to sector %d", __func__, first, last);
511
512 if (target->state != TARGET_HALTED) {
513 LOG_ERROR("Target not halted");
514 return ERROR_TARGET_NOT_HALTED;
515 }
516
517 if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
518 LOG_ERROR("Flash sector invalid");
519 return ERROR_FLASH_SECTOR_INVALID;
520 }
521
522 if (!ath79_info->probed) {
523 LOG_ERROR("Flash bank not probed");
524 return ERROR_FLASH_BANK_NOT_PROBED;
525 }
526
527 for (sector = first; sector <= last; sector++) {
528 if (bank->sectors[sector].is_protected) {
529 LOG_ERROR("Flash sector %d protected", sector);
530 return ERROR_FAIL;
531 }
532 }
533
534 for (sector = first; sector <= last; sector++) {
535 retval = ath79_erase_sector(bank, sector);
536 if (retval != ERROR_OK)
537 break;
538 keep_alive();
539 }
540
541 return retval;
542 }
543
544 static int ath79_protect(struct flash_bank *bank, int set,
545 int first, int last)
546 {
547 int sector;
548
549 for (sector = first; sector <= last; sector++)
550 bank->sectors[sector].is_protected = set;
551 return ERROR_OK;
552 }
553
554 static int ath79_write_page(struct flash_bank *bank, const uint8_t *buffer,
555 uint32_t address, uint32_t len)
556 {
557 struct ath79_flash_bank *ath79_info = bank->driver_priv;
558 uint8_t spi_bytes[] = {
559 SPIFLASH_PAGE_PROGRAM,
560 address >> 16,
561 address >> 8,
562 address,
563 };
564 int retval;
565 uint32_t i;
566
567 if (address & 0xff) {
568 LOG_ERROR("ath79_write_page: unaligned write address: %08x",
569 address);
570 return ERROR_FAIL;
571 }
572 if (!ath79_info->spi.page_buf) {
573 LOG_ERROR("ath79_write_page: page buffer not initialized");
574 return ERROR_FAIL;
575 }
576 if (len > ath79_info->dev->pagesize) {
577 LOG_ERROR("ath79_write_page: len bigger than page size %d: %d",
578 ath79_info->dev->pagesize, len);
579 return ERROR_FAIL;
580 }
581
582 for (i = 0; i < len; i++) {
583 if (buffer[i] != 0xff)
584 break;
585 }
586 if (i == len) /* all 0xff, no need to program. */
587 return ERROR_OK;
588
589 LOG_INFO("writing %d bytes to flash page @0x%08x", len, address);
590
591 memcpy(ath79_info->spi.page_buf, buffer, len);
592
593 /* unlock writes */
594 retval = ath79_write_enable(bank);
595 if (retval != ERROR_OK)
596 return retval;
597
598 /* bitbang command */
599 ath79_spi_bitbang_prepare(bank);
600 retval = ath79_spi_bitbang_bytes(
601 bank, spi_bytes, sizeof(spi_bytes),
602 ATH79_XFER_PARTIAL);
603 if (retval != ERROR_OK)
604 return retval;
605
606 /* write data */
607 return ath79_spi_bitbang_bytes(
608 bank, ath79_info->spi.page_buf, len,
609 ATH79_XFER_FINAL);
610 }
611
612 static int ath79_write_buffer(struct flash_bank *bank, const uint8_t *buffer,
613 uint32_t address, uint32_t len)
614 {
615 struct ath79_flash_bank *ath79_info = bank->driver_priv;
616 const uint32_t page_size = ath79_info->dev->pagesize;
617 int retval;
618
619 LOG_DEBUG("%s: address=0x%08" PRIx32 " len=0x%08" PRIx32,
620 __func__, address, len);
621
622 while (len > 0) {
623 int page_len = len > page_size ? page_size : len;
624
625 retval = ath79_write_page(
626 bank, buffer, address, page_len);
627 if (retval != ERROR_OK)
628 return retval;
629
630 buffer += page_size;
631 address += page_size;
632 len -= page_len;
633 }
634
635 return ERROR_OK;
636 }
637
638 static int ath79_write(struct flash_bank *bank, const uint8_t *buffer,
639 uint32_t offset, uint32_t count)
640 {
641 struct target *target = bank->target;
642 int sector;
643
644 LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32,
645 __func__, offset, count);
646
647 if (offset < bank->base || offset >= bank->base + bank->size) {
648 LOG_ERROR("Start address out of range");
649 return ERROR_FAIL;
650 }
651
652 offset -= bank->base;
653
654 if (target->state != TARGET_HALTED) {
655 LOG_ERROR("Target not halted");
656 return ERROR_TARGET_NOT_HALTED;
657 }
658
659 if (offset + count > bank->size) {
660 LOG_WARNING("Write pasts end of flash. Extra data discarded.");
661 count = bank->size - offset;
662 }
663
664 /* Check sector protection */
665 for (sector = 0; sector < bank->num_sectors; sector++) {
666 /* Start offset in or before this sector? */
667 /* End offset in or behind this sector? */
668 struct flash_sector *bs = &bank->sectors[sector];
669
670 if ((offset < (bs->offset + bs->size)) &&
671 ((offset + count - 1) >= bs->offset) &&
672 bs->is_protected) {
673 LOG_ERROR("Flash sector %d protected", sector);
674 return ERROR_FAIL;
675 }
676 }
677
678 return ath79_write_buffer(bank, buffer, offset, count);
679 }
680
681 static int ath79_read_buffer(struct flash_bank *bank, uint8_t *buffer,
682 uint32_t address, uint32_t len)
683 {
684 uint8_t spi_bytes[] = {
685 SPIFLASH_READ,
686 address >> 16,
687 address >> 8,
688 address,
689 };
690 int retval;
691
692 LOG_DEBUG("%s: address=0x%08" PRIx32 " len=0x%08" PRIx32,
693 __func__, address, len);
694
695 if (address & 0xff) {
696 LOG_ERROR("ath79_read_buffer: unaligned read address: %08x",
697 address);
698 return ERROR_FAIL;
699 }
700
701 LOG_INFO("reading %d bytes from flash @0x%08x", len, address);
702
703 /* bitbang command */
704 ath79_spi_bitbang_prepare(bank);
705 retval = ath79_spi_bitbang_bytes(
706 bank, spi_bytes, sizeof(spi_bytes), ATH79_XFER_PARTIAL);
707 if (retval != ERROR_OK)
708 return retval;
709
710 /* read data */
711 return ath79_spi_bitbang_bytes(
712 bank, buffer, len, ATH79_XFER_FINAL);
713 }
714
715 static int ath79_read(struct flash_bank *bank, uint8_t *buffer,
716 uint32_t offset, uint32_t count)
717 {
718 struct target *target = bank->target;
719
720 LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32,
721 __func__, offset, count);
722
723 if (offset < bank->base || offset >= bank->base + bank->size) {
724 LOG_ERROR("Start address out of range");
725 return ERROR_FAIL;
726 }
727
728 offset -= bank->base;
729
730 if (target->state != TARGET_HALTED) {
731 LOG_ERROR("Target not halted");
732 return ERROR_TARGET_NOT_HALTED;
733 }
734
735 if (offset + count > bank->size) {
736 LOG_WARNING("Reads past end of flash. Extra data discarded.");
737 count = bank->size - offset;
738 }
739
740 return ath79_read_buffer(bank, buffer, offset, count);
741 }
742
743 /* Return ID of flash device */
744 static int read_flash_id(struct flash_bank *bank, uint32_t *id)
745 {
746 struct target *target = bank->target;
747 int retval;
748 uint8_t spi_bytes[] = {SPIFLASH_READ_ID, 0, 0, 0};
749
750 if (target->state != TARGET_HALTED) {
751 LOG_ERROR("Target not halted");
752 return ERROR_TARGET_NOT_HALTED;
753 }
754
755 /* Send SPI command "read ID" */
756 ath79_spi_bitbang_prepare(bank);
757 retval = ath79_spi_bitbang_bytes(
758 bank, spi_bytes, sizeof(spi_bytes), ATH79_XFER_FINAL);
759 if (retval != ERROR_OK)
760 return retval;
761
762 *id = (spi_bytes[1] << 0)
763 | (spi_bytes[2] << 8)
764 | (spi_bytes[3] << 16);
765
766 if (*id == 0xffffff) {
767 LOG_ERROR("No SPI flash found");
768 return ERROR_FAIL;
769 }
770
771 return ERROR_OK;
772 }
773
774 static int ath79_probe(struct flash_bank *bank)
775 {
776 struct target *target = bank->target;
777 struct ath79_flash_bank *ath79_info = bank->driver_priv;
778 struct flash_sector *sectors;
779 uint32_t id = 0; /* silence uninitialized warning */
780 const struct ath79_target *target_device;
781 int retval;
782
783 if (ath79_info->probed) {
784 free(bank->sectors);
785 free(ath79_info->spi.page_buf);
786 }
787 ath79_info->probed = 0;
788
789 for (target_device = target_devices; target_device->name;
790 ++target_device)
791 if (target_device->tap_idcode == target->tap->idcode)
792 break;
793 if (!target_device->name) {
794 LOG_ERROR("Device ID 0x%" PRIx32 " is not known",
795 target->tap->idcode);
796 return ERROR_FAIL;
797 }
798
799 ath79_info->io_base = target_device->io_base;
800
801 LOG_DEBUG("Found device %s at address 0x%" PRIx32,
802 target_device->name, bank->base);
803
804 retval = read_flash_id(bank, &id);
805 if (retval != ERROR_OK)
806 return retval;
807
808 ath79_info->dev = NULL;
809 for (const struct flash_device *p = flash_devices; p->name; p++)
810 if (p->device_id == id) {
811 ath79_info->dev = p;
812 break;
813 }
814
815 if (!ath79_info->dev) {
816 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
817 return ERROR_FAIL;
818 }
819
820 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
821 ath79_info->dev->name, ath79_info->dev->device_id);
822
823 /* Set correct size value */
824 bank->size = ath79_info->dev->size_in_bytes;
825
826 /* create and fill sectors array */
827 bank->num_sectors =
828 ath79_info->dev->size_in_bytes / ath79_info->dev->sectorsize;
829 sectors = calloc(1, sizeof(struct flash_sector) * bank->num_sectors);
830 if (!sectors) {
831 LOG_ERROR("not enough memory");
832 return ERROR_FAIL;
833 }
834 ath79_info->spi.page_buf = malloc(ath79_info->dev->pagesize);
835 if (!ath79_info->spi.page_buf) {
836 LOG_ERROR("not enough memory");
837 free(sectors);
838 return ERROR_FAIL;
839 }
840
841 for (int sector = 0; sector < bank->num_sectors; sector++) {
842 sectors[sector].offset = sector * ath79_info->dev->sectorsize;
843 sectors[sector].size = ath79_info->dev->sectorsize;
844 sectors[sector].is_erased = 0;
845 sectors[sector].is_protected = 1;
846 }
847
848 bank->sectors = sectors;
849 ath79_info->probed = 1;
850 return ERROR_OK;
851 }
852
853 static int ath79_auto_probe(struct flash_bank *bank)
854 {
855 struct ath79_flash_bank *ath79_info = bank->driver_priv;
856
857 if (ath79_info->probed)
858 return ERROR_OK;
859 return ath79_probe(bank);
860 }
861
862 static int ath79_flash_blank_check(struct flash_bank *bank)
863 {
864 /* Not implemented */
865 return ERROR_OK;
866 }
867
868 static int ath79_protect_check(struct flash_bank *bank)
869 {
870 /* Not implemented */
871 return ERROR_OK;
872 }
873
874 static int get_ath79_info(struct flash_bank *bank, char *buf, int buf_size)
875 {
876 struct ath79_flash_bank *ath79_info = bank->driver_priv;
877
878 if (!ath79_info->probed) {
879 snprintf(buf, buf_size,
880 "\nATH79 flash bank not probed yet\n");
881 return ERROR_OK;
882 }
883
884 snprintf(buf, buf_size, "\nATH79 flash information:\n"
885 " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
886 ath79_info->dev->name, ath79_info->dev->device_id);
887
888 return ERROR_OK;
889 }
890
891 struct flash_driver ath79_flash = {
892 .name = "ath79",
893 .flash_bank_command = ath79_flash_bank_command,
894 .erase = ath79_erase,
895 .protect = ath79_protect,
896 .write = ath79_write,
897 .read = ath79_read,
898 .probe = ath79_probe,
899 .auto_probe = ath79_auto_probe,
900 .erase_check = ath79_flash_blank_check,
901 .protect_check = ath79_protect_check,
902 .info = get_ath79_info,
903 };

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)