OpenOCD
fespi.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
5  * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
6  ***************************************************************************/
7 
8 /* The Freedom E SPI controller is a SPI bus controller
9  * specifically designed for SPI Flash Memories on Freedom E platforms.
10  *
11  * Two working modes are available:
12  * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
13  * on the bus. Writes are only possible in this mode.
14  * - HW mode: Memory content is directly
15  * accessible in CPU memory space. CPU can read and execute memory content.
16  */
17 
18 /* ATTENTION:
19  * To have flash memory mapped in CPU memory space, the controller
20  * must have "HW mode" enabled.
21  * 1) The command "reset init" has to initialize the controller and put
22  * it in HW mode (this is actually the default out of reset for Freedom E systems).
23  * 2) every command in this file have to return to prompt in HW mode. */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include "imp.h"
30 #include "spi.h"
31 #include <jtag/jtag.h>
32 #include <helper/time_support.h>
33 #include <target/algorithm.h>
34 #include "target/riscv/riscv.h"
35 
36 /* Register offsets */
37 
38 #define FESPI_REG_SCKDIV 0x00
39 #define FESPI_REG_SCKMODE 0x04
40 #define FESPI_REG_CSID 0x10
41 #define FESPI_REG_CSDEF 0x14
42 #define FESPI_REG_CSMODE 0x18
43 
44 #define FESPI_REG_DCSSCK 0x28
45 #define FESPI_REG_DSCKCS 0x2a
46 #define FESPI_REG_DINTERCS 0x2c
47 #define FESPI_REG_DINTERXFR 0x2e
48 
49 #define FESPI_REG_FMT 0x40
50 #define FESPI_REG_TXFIFO 0x48
51 #define FESPI_REG_RXFIFO 0x4c
52 #define FESPI_REG_TXCTRL 0x50
53 #define FESPI_REG_RXCTRL 0x54
54 
55 #define FESPI_REG_FCTRL 0x60
56 #define FESPI_REG_FFMT 0x64
57 
58 #define FESPI_REG_IE 0x70
59 #define FESPI_REG_IP 0x74
60 
61 /* Fields */
62 
63 #define FESPI_SCK_POL 0x1
64 #define FESPI_SCK_PHA 0x2
65 
66 #define FESPI_FMT_PROTO(x) ((x) & 0x3)
67 #define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
68 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
69 #define FESPI_FMT_LEN(x) (((x) & 0xf) << 16)
70 
71 /* TXCTRL register */
72 #define FESPI_TXWM(x) ((x) & 0xffff)
73 /* RXCTRL register */
74 #define FESPI_RXWM(x) ((x) & 0xffff)
75 
76 #define FESPI_IP_TXWM 0x1
77 #define FESPI_IP_RXWM 0x2
78 
79 #define FESPI_FCTRL_EN 0x1
80 
81 #define FESPI_INSN_CMD_EN 0x1
82 #define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
83 #define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
84 #define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
85 #define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
86 #define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
87 #define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
88 #define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
89 
90 /* Values */
91 
92 #define FESPI_CSMODE_AUTO 0
93 #define FESPI_CSMODE_HOLD 2
94 #define FESPI_CSMODE_OFF 3
95 
96 #define FESPI_DIR_RX 0
97 #define FESPI_DIR_TX 1
98 
99 #define FESPI_PROTO_S 0
100 #define FESPI_PROTO_D 1
101 #define FESPI_PROTO_Q 2
102 
103 #define FESPI_ENDIAN_MSB 0
104 #define FESPI_ENDIAN_LSB 1
105 
106 
107 /* Timeout in ms */
108 #define FESPI_CMD_TIMEOUT (100)
109 #define FESPI_PROBE_TIMEOUT (100)
110 #define FESPI_MAX_TIMEOUT (3000)
111 
112 
114  bool probed;
116  const struct flash_device *dev;
117 };
118 
119 struct fespi_target {
120  char *name;
121  uint32_t tap_idcode;
122  uint32_t ctrl_base;
123 };
124 
125 /* TODO !!! What is the right naming convention here? */
126 static const struct fespi_target target_devices[] = {
127  /* name, tap_idcode, ctrl_base */
128  { "Freedom E310-G000 SPI Flash", 0x10e31913, 0x10014000 },
129  { "Freedom E310-G002 SPI Flash", 0x20000913, 0x10014000 },
130  { NULL, 0, 0 }
131 };
132 
133 FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)
134 {
135  struct fespi_flash_bank *fespi_info;
136 
137  LOG_DEBUG("%s", __func__);
138 
139  if (CMD_ARGC < 6)
141 
142  fespi_info = malloc(sizeof(struct fespi_flash_bank));
143  if (!fespi_info) {
144  LOG_ERROR("not enough memory");
145  return ERROR_FAIL;
146  }
147 
148  bank->driver_priv = fespi_info;
149  fespi_info->probed = false;
150  fespi_info->ctrl_base = 0;
151  if (CMD_ARGC >= 7) {
152  COMMAND_PARSE_ADDRESS(CMD_ARGV[6], fespi_info->ctrl_base);
153  LOG_DEBUG("ASSUMING FESPI device at ctrl_base = " TARGET_ADDR_FMT,
154  fespi_info->ctrl_base);
155  }
156 
157  return ERROR_OK;
158 }
159 
160 static int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)
161 {
162  struct target *target = bank->target;
163  struct fespi_flash_bank *fespi_info = bank->driver_priv;
164 
165  int result = target_read_u32(target, fespi_info->ctrl_base + address, value);
166  if (result != ERROR_OK) {
167  LOG_ERROR("fespi_read_reg() error at " TARGET_ADDR_FMT,
168  fespi_info->ctrl_base + address);
169  return result;
170  }
171  return ERROR_OK;
172 }
173 
174 static int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)
175 {
176  struct target *target = bank->target;
177  struct fespi_flash_bank *fespi_info = bank->driver_priv;
178 
179  int result = target_write_u32(target, fespi_info->ctrl_base + address, value);
180  if (result != ERROR_OK) {
181  LOG_ERROR("fespi_write_reg() error writing 0x%" PRIx32 " to " TARGET_ADDR_FMT,
182  value, fespi_info->ctrl_base + address);
183  return result;
184  }
185  return ERROR_OK;
186 }
187 
189 {
190  uint32_t fctrl;
191  if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
192  return ERROR_FAIL;
194 }
195 
197 {
198  uint32_t fctrl;
199  if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
200  return ERROR_FAIL;
202 }
203 
204 static int fespi_set_dir(struct flash_bank *bank, bool dir)
205 {
206  uint32_t fmt;
207  if (fespi_read_reg(bank, &fmt, FESPI_REG_FMT) != ERROR_OK)
208  return ERROR_FAIL;
209 
211  (fmt & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir));
212 }
213 
214 static int fespi_txwm_wait(struct flash_bank *bank)
215 {
216  int64_t start = timeval_ms();
217 
218  while (1) {
219  uint32_t ip;
221  return ERROR_FAIL;
222  if (ip & FESPI_IP_TXWM)
223  break;
224  int64_t now = timeval_ms();
225  if (now - start > 1000) {
226  LOG_ERROR("ip.txwm didn't get set.");
227  return ERROR_TARGET_TIMEOUT;
228  }
229  }
230 
231  return ERROR_OK;
232 }
233 
234 static int fespi_tx(struct flash_bank *bank, uint8_t in)
235 {
236  int64_t start = timeval_ms();
237 
238  while (1) {
239  uint32_t txfifo;
240  if (fespi_read_reg(bank, &txfifo, FESPI_REG_TXFIFO) != ERROR_OK)
241  return ERROR_FAIL;
242  if (!(txfifo >> 31))
243  break;
244  int64_t now = timeval_ms();
245  if (now - start > 1000) {
246  LOG_ERROR("txfifo stayed negative.");
247  return ERROR_TARGET_TIMEOUT;
248  }
249  }
250 
252 }
253 
254 static int fespi_rx(struct flash_bank *bank, uint8_t *out)
255 {
256  int64_t start = timeval_ms();
257  uint32_t value;
258 
259  while (1) {
260  if (fespi_read_reg(bank, &value, FESPI_REG_RXFIFO) != ERROR_OK)
261  return ERROR_FAIL;
262  if (!(value >> 31))
263  break;
264  int64_t now = timeval_ms();
265  if (now - start > 1000) {
266  LOG_ERROR("rxfifo didn't go positive (value=0x%" PRIx32 ").", value);
267  return ERROR_TARGET_TIMEOUT;
268  }
269  }
270 
271  if (out)
272  *out = value & 0xff;
273 
274  return ERROR_OK;
275 }
276 
277 /* TODO!!! Why don't we need to call this after writing? */
278 static int fespi_wip(struct flash_bank *bank, int timeout)
279 {
280  int64_t endtime;
281 
283 
285  return ERROR_FAIL;
286  endtime = timeval_ms() + timeout;
287 
289  if (fespi_rx(bank, NULL) != ERROR_OK)
290  return ERROR_FAIL;
291 
292  do {
293  alive_sleep(1);
294 
295  fespi_tx(bank, 0);
296  uint8_t rx;
297  if (fespi_rx(bank, &rx) != ERROR_OK)
298  return ERROR_FAIL;
299  if ((rx & SPIFLASH_BSY_BIT) == 0) {
301  return ERROR_FAIL;
303  return ERROR_OK;
304  }
305  } while (timeval_ms() < endtime);
306 
307  LOG_ERROR("timeout");
308  return ERROR_FAIL;
309 }
310 
311 static int fespi_erase_sector(struct flash_bank *bank, int sector)
312 {
313  struct fespi_flash_bank *fespi_info = bank->driver_priv;
314  int retval;
315 
317  if (retval != ERROR_OK)
318  return retval;
319  retval = fespi_txwm_wait(bank);
320  if (retval != ERROR_OK)
321  return retval;
322 
324  return ERROR_FAIL;
325  retval = fespi_tx(bank, fespi_info->dev->erase_cmd);
326  if (retval != ERROR_OK)
327  return retval;
328  sector = bank->sectors[sector].offset;
329  if (bank->size > 0x1000000) {
330  retval = fespi_tx(bank, sector >> 24);
331  if (retval != ERROR_OK)
332  return retval;
333  }
334  retval = fespi_tx(bank, sector >> 16);
335  if (retval != ERROR_OK)
336  return retval;
337  retval = fespi_tx(bank, sector >> 8);
338  if (retval != ERROR_OK)
339  return retval;
340  retval = fespi_tx(bank, sector);
341  if (retval != ERROR_OK)
342  return retval;
343  retval = fespi_txwm_wait(bank);
344  if (retval != ERROR_OK)
345  return retval;
347  return ERROR_FAIL;
348 
349  retval = fespi_wip(bank, FESPI_MAX_TIMEOUT);
350  if (retval != ERROR_OK)
351  return retval;
352 
353  return ERROR_OK;
354 }
355 
356 static int fespi_erase(struct flash_bank *bank, unsigned int first,
357  unsigned int last)
358 {
359  struct target *target = bank->target;
360  struct fespi_flash_bank *fespi_info = bank->driver_priv;
361  int retval = ERROR_OK;
362 
363  LOG_DEBUG("%s: from sector %u to sector %u", __func__, first, last);
364 
365  if (target->state != TARGET_HALTED) {
366  LOG_ERROR("Target not halted");
368  }
369 
370  if ((last < first) || (last >= bank->num_sectors)) {
371  LOG_ERROR("Flash sector invalid");
373  }
374 
375  if (!(fespi_info->probed)) {
376  LOG_ERROR("Flash bank not probed");
378  }
379 
380  for (unsigned int sector = first; sector <= last; sector++) {
381  if (bank->sectors[sector].is_protected) {
382  LOG_ERROR("Flash sector %u protected", sector);
383  return ERROR_FAIL;
384  }
385  }
386 
387  if (fespi_info->dev->erase_cmd == 0x00)
389 
391  return ERROR_FAIL;
392  retval = fespi_txwm_wait(bank);
393  if (retval != ERROR_OK) {
394  LOG_ERROR("WM Didn't go high before attempting.");
395  return retval;
396  }
397 
398  /* Disable Hardware accesses*/
400  return ERROR_FAIL;
401 
402  /* poll WIP */
404  if (retval != ERROR_OK)
405  goto done;
406 
407  for (unsigned int sector = first; sector <= last; sector++) {
408  retval = fespi_erase_sector(bank, sector);
409  if (retval != ERROR_OK)
410  goto done;
411  keep_alive();
412  }
413 
414  /* Switch to HW mode before return to prompt */
415 done:
417  return ERROR_FAIL;
418  return retval;
419 }
420 
421 static int fespi_protect(struct flash_bank *bank, int set,
422  unsigned int first, unsigned int last)
423 {
424  for (unsigned int sector = first; sector <= last; sector++)
425  bank->sectors[sector].is_protected = set;
426  return ERROR_OK;
427 }
428 
430  const uint8_t *buffer, uint32_t offset, uint32_t len)
431 {
432  struct fespi_flash_bank *fespi_info = bank->driver_priv;
433  uint32_t ii;
434 
435  /* TODO!!! assert that len < page size */
436 
438  return ERROR_FAIL;
439  if (fespi_txwm_wait(bank) != ERROR_OK)
440  return ERROR_FAIL;
441 
443  return ERROR_FAIL;
444 
445  if (fespi_tx(bank, fespi_info->dev->pprog_cmd) != ERROR_OK)
446  return ERROR_FAIL;
447 
448  if (bank->size > 0x1000000 && fespi_tx(bank, offset >> 24) != ERROR_OK)
449  return ERROR_FAIL;
450  if (fespi_tx(bank, offset >> 16) != ERROR_OK)
451  return ERROR_FAIL;
452  if (fespi_tx(bank, offset >> 8) != ERROR_OK)
453  return ERROR_FAIL;
454  if (fespi_tx(bank, offset) != ERROR_OK)
455  return ERROR_FAIL;
456 
457  for (ii = 0; ii < len; ii++) {
458  if (fespi_tx(bank, buffer[ii]) != ERROR_OK)
459  return ERROR_FAIL;
460  }
461 
462  if (fespi_txwm_wait(bank) != ERROR_OK)
463  return ERROR_FAIL;
464 
466  return ERROR_FAIL;
467 
468  keep_alive();
469 
470  return ERROR_OK;
471 }
472 
473 static const uint8_t riscv32_bin[] = {
474 #include "../../../contrib/loaders/flash/fespi/riscv32_fespi.inc"
475 };
476 
477 static const uint8_t riscv64_bin[] = {
478 #include "../../../contrib/loaders/flash/fespi/riscv64_fespi.inc"
479 };
480 
481 static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
482  uint32_t offset, uint32_t count)
483 {
484  struct target *target = bank->target;
485  struct fespi_flash_bank *fespi_info = bank->driver_priv;
486  uint32_t cur_count, page_size;
487  int retval = ERROR_OK;
488 
489  LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32 " count=0x%08" PRIx32,
490  bank->size, offset, count);
491 
492  if (target->state != TARGET_HALTED) {
493  LOG_ERROR("Target not halted");
495  }
496 
497  if (offset + count > fespi_info->dev->size_in_bytes) {
498  LOG_WARNING("Write past end of flash. Extra data discarded.");
499  count = fespi_info->dev->size_in_bytes - offset;
500  }
501 
502  /* Check sector protection */
503  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
504  /* Start offset in or before this sector? */
505  /* End offset in or behind this sector? */
506  if ((offset <
507  (bank->sectors[sector].offset + bank->sectors[sector].size))
508  && ((offset + count - 1) >= bank->sectors[sector].offset)
509  && bank->sectors[sector].is_protected) {
510  LOG_ERROR("Flash sector %u protected", sector);
511  return ERROR_FAIL;
512  }
513  }
514 
515  struct riscv_info *riscv = riscv_info(target);
516  if (!is_riscv(riscv)) {
517  LOG_ERROR("Unexpected target type");
518  return ERROR_FAIL;
519  }
520 
521  unsigned int xlen = riscv_xlen(target);
522  struct working_area *algorithm_wa = NULL;
523  struct working_area *data_wa = NULL;
524  const uint8_t *bin;
525  size_t bin_size;
526  if (xlen == 32) {
527  bin = riscv32_bin;
528  bin_size = sizeof(riscv32_bin);
529  } else {
530  bin = riscv64_bin;
531  bin_size = sizeof(riscv64_bin);
532  }
533 
534  unsigned data_wa_size = 0;
535  if (target_alloc_working_area(target, bin_size, &algorithm_wa) == ERROR_OK) {
536  retval = target_write_buffer(target, algorithm_wa->address,
537  bin_size, bin);
538  if (retval != ERROR_OK) {
539  LOG_ERROR("Failed to write code to " TARGET_ADDR_FMT ": %d",
540  algorithm_wa->address, retval);
541  target_free_working_area(target, algorithm_wa);
542  algorithm_wa = NULL;
543 
544  } else {
545  data_wa_size = MIN(target_get_working_area_avail(target), count);
546  if (data_wa_size < 128) {
547  LOG_WARNING("Couldn't allocate data working area.");
548  target_free_working_area(target, algorithm_wa);
549  algorithm_wa = NULL;
550  } else if (target_alloc_working_area(target, data_wa_size, &data_wa) != ERROR_OK) {
551  target_free_working_area(target, algorithm_wa);
552  algorithm_wa = NULL;
553  }
554  }
555  } else {
556  LOG_WARNING("Couldn't allocate %zd-byte working area.", bin_size);
557  algorithm_wa = NULL;
558  }
559 
560  /* If no valid page_size, use reasonable default. */
561  page_size = fespi_info->dev->pagesize ?
562  fespi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
563 
564  if (algorithm_wa) {
565  struct reg_param reg_params[6];
566  init_reg_param(&reg_params[0], "a0", xlen, PARAM_IN_OUT);
567  init_reg_param(&reg_params[1], "a1", xlen, PARAM_OUT);
568  init_reg_param(&reg_params[2], "a2", xlen, PARAM_OUT);
569  init_reg_param(&reg_params[3], "a3", xlen, PARAM_OUT);
570  init_reg_param(&reg_params[4], "a4", xlen, PARAM_OUT);
571  init_reg_param(&reg_params[5], "a5", xlen, PARAM_OUT);
572 
573  while (count > 0) {
574  cur_count = MIN(count, data_wa_size);
575  buf_set_u64(reg_params[0].value, 0, xlen, fespi_info->ctrl_base);
576  buf_set_u64(reg_params[1].value, 0, xlen, page_size);
577  buf_set_u64(reg_params[2].value, 0, xlen, data_wa->address);
578  buf_set_u64(reg_params[3].value, 0, xlen, offset);
579  buf_set_u64(reg_params[4].value, 0, xlen, cur_count);
580  buf_set_u64(reg_params[5].value, 0, xlen,
581  fespi_info->dev->pprog_cmd | (bank->size > 0x1000000 ? 0x100 : 0));
582 
583  retval = target_write_buffer(target, data_wa->address, cur_count,
584  buffer);
585  if (retval != ERROR_OK) {
586  LOG_DEBUG("Failed to write %d bytes to " TARGET_ADDR_FMT ": %d",
587  cur_count, data_wa->address, retval);
588  goto err;
589  }
590 
591  LOG_DEBUG("write(ctrl_base=0x%" TARGET_PRIxADDR ", page_size=0x%x, "
592  "address=0x%" TARGET_PRIxADDR ", offset=0x%" PRIx32
593  ", count=0x%" PRIx32 "), buffer=%02x %02x %02x %02x %02x %02x ..." PRIx32,
594  fespi_info->ctrl_base, page_size, data_wa->address, offset, cur_count,
595  buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
596  retval = target_run_algorithm(target, 0, NULL,
597  ARRAY_SIZE(reg_params), reg_params,
598  algorithm_wa->address, 0, cur_count * 2, NULL);
599  if (retval != ERROR_OK) {
600  LOG_ERROR("Failed to execute algorithm at " TARGET_ADDR_FMT ": %d",
601  algorithm_wa->address, retval);
602  goto err;
603  }
604 
605  uint64_t algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);
606  if (algorithm_result != 0) {
607  LOG_ERROR("Algorithm returned error %" PRId64, algorithm_result);
608  retval = ERROR_FAIL;
609  goto err;
610  }
611 
612  buffer += cur_count;
613  offset += cur_count;
614  count -= cur_count;
615  }
616 
618  target_free_working_area(target, algorithm_wa);
619 
620  } else {
622 
623  /* Disable Hardware accesses*/
625  return ERROR_FAIL;
626 
627  /* poll WIP */
629  if (retval != ERROR_OK)
630  goto err;
631 
632  uint32_t page_offset = offset % page_size;
633  /* central part, aligned words */
634  while (count > 0) {
635  /* clip block at page boundary */
636  if (page_offset + count > page_size)
637  cur_count = page_size - page_offset;
638  else
639  cur_count = count;
640 
641  retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);
642  if (retval != ERROR_OK)
643  goto err;
644 
645  page_offset = 0;
646  buffer += cur_count;
647  offset += cur_count;
648  count -= cur_count;
649  }
650 
651  /* Switch to HW mode before return to prompt */
653  return ERROR_FAIL;
654  }
655 
656  return ERROR_OK;
657 
658 err:
660  target_free_working_area(target, algorithm_wa);
661 
662  /* Switch to HW mode before return to prompt */
664  return ERROR_FAIL;
665 
666  return retval;
667 }
668 
669 /* Return ID of flash device */
670 /* On exit, SW mode is kept */
671 static int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id)
672 {
673  struct target *target = bank->target;
674  int retval;
675 
676  if (target->state != TARGET_HALTED) {
677  LOG_ERROR("Target not halted");
679  }
680 
682 
683  /* poll WIP */
685  if (retval != ERROR_OK)
686  return retval;
687 
689 
690  /* Send SPI command "read ID" */
692  return ERROR_FAIL;
693 
695  /* Send dummy bytes to actually read the ID.*/
696  fespi_tx(bank, 0);
697  fespi_tx(bank, 0);
698  fespi_tx(bank, 0);
699 
700  /* read ID from Receive Register */
701  *id = 0;
702  if (fespi_rx(bank, NULL) != ERROR_OK)
703  return ERROR_FAIL;
704  uint8_t rx;
705  if (fespi_rx(bank, &rx) != ERROR_OK)
706  return ERROR_FAIL;
707  *id = rx;
708  if (fespi_rx(bank, &rx) != ERROR_OK)
709  return ERROR_FAIL;
710  *id |= (rx << 8);
711  if (fespi_rx(bank, &rx) != ERROR_OK)
712  return ERROR_FAIL;
713  *id |= (rx << 16);
714 
716  return ERROR_FAIL;
717 
719 
720  return ERROR_OK;
721 }
722 
723 static int fespi_probe(struct flash_bank *bank)
724 {
725  struct target *target = bank->target;
726  struct fespi_flash_bank *fespi_info = bank->driver_priv;
727  struct flash_sector *sectors;
728  uint32_t id = 0; /* silence uninitialized warning */
729  const struct fespi_target *target_device;
730  int retval;
731  uint32_t sectorsize;
732 
733  if (fespi_info->probed)
734  free(bank->sectors);
735  fespi_info->probed = false;
736 
737  if (fespi_info->ctrl_base == 0) {
738  for (target_device = target_devices ; target_device->name ; ++target_device)
739  if (target_device->tap_idcode == target->tap->idcode)
740  break;
741 
742  if (!target_device->name) {
743  LOG_ERROR("Device ID 0x%" PRIx32 " is not known as FESPI capable",
744  target->tap->idcode);
745  return ERROR_FAIL;
746  }
747 
748  fespi_info->ctrl_base = target_device->ctrl_base;
749 
750  LOG_DEBUG("Valid FESPI on device %s at address " TARGET_ADDR_FMT,
751  target_device->name, bank->base);
752 
753  } else {
754  LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
755  " with ctrl at " TARGET_ADDR_FMT, fespi_info->ctrl_base,
756  bank->base);
757  }
758 
759  /* read and decode flash ID; returns in SW mode */
761  return ERROR_FAIL;
763 
764  /* Disable Hardware accesses*/
766  return ERROR_FAIL;
767 
768  retval = fespi_read_flash_id(bank, &id);
769 
771  return ERROR_FAIL;
772  if (retval != ERROR_OK)
773  return retval;
774 
775  fespi_info->dev = NULL;
776  for (const struct flash_device *p = flash_devices; p->name ; p++)
777  if (p->device_id == id) {
778  fespi_info->dev = p;
779  break;
780  }
781 
782  if (!fespi_info->dev) {
783  LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
784  return ERROR_FAIL;
785  }
786 
787  LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
788  fespi_info->dev->name, fespi_info->dev->device_id);
789 
790  /* Set correct size value */
791  bank->size = fespi_info->dev->size_in_bytes;
792 
793  if (bank->size <= (1UL << 16))
794  LOG_WARNING("device needs 2-byte addresses - not implemented");
795 
796  /* if no sectors, treat whole bank as single sector */
797  sectorsize = fespi_info->dev->sectorsize ?
798  fespi_info->dev->sectorsize : fespi_info->dev->size_in_bytes;
799 
800  /* create and fill sectors array */
801  bank->num_sectors = fespi_info->dev->size_in_bytes / sectorsize;
802  sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
803  if (!sectors) {
804  LOG_ERROR("not enough memory");
805  return ERROR_FAIL;
806  }
807 
808  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
809  sectors[sector].offset = sector * sectorsize;
810  sectors[sector].size = sectorsize;
811  sectors[sector].is_erased = -1;
812  sectors[sector].is_protected = 0;
813  }
814 
815  bank->sectors = sectors;
816  fespi_info->probed = true;
817  return ERROR_OK;
818 }
819 
820 static int fespi_auto_probe(struct flash_bank *bank)
821 {
822  struct fespi_flash_bank *fespi_info = bank->driver_priv;
823  if (fespi_info->probed)
824  return ERROR_OK;
825  return fespi_probe(bank);
826 }
827 
829 {
830  /* Nothing to do. Protection is only handled in SW. */
831  return ERROR_OK;
832 }
833 
835 {
836  struct fespi_flash_bank *fespi_info = bank->driver_priv;
837 
838  if (!(fespi_info->probed)) {
839  command_print_sameline(cmd, "\nFESPI flash bank not probed yet\n");
840  return ERROR_OK;
841  }
842 
843  command_print_sameline(cmd, "\nFESPI flash information:\n"
844  " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
845  fespi_info->dev->name, fespi_info->dev->device_id);
846 
847  return ERROR_OK;
848 }
849 
850 const struct flash_driver fespi_flash = {
851  .name = "fespi",
852  .flash_bank_command = fespi_flash_bank_command,
853  .erase = fespi_erase,
854  .protect = fespi_protect,
855  .write = fespi_write,
856  .read = default_flash_read,
857  .probe = fespi_probe,
858  .auto_probe = fespi_auto_probe,
859  .erase_check = default_flash_blank_check,
860  .protect_check = fespi_protect_check,
861  .info = get_fespi_info,
862  .free_driver_priv = default_flash_free_driver_priv
863 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
@ PARAM_OUT
Definition: algorithm.h:16
@ PARAM_IN_OUT
Definition: algorithm.h:17
static void buf_set_u64(uint8_t *_buffer, unsigned first, unsigned num, uint64_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:60
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
Definition: binarybuffer.h:127
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:450
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define COMMAND_PARSE_ADDRESS(in, out)
Definition: command.h:435
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
uint8_t bank
Definition: esirisc.c:135
static int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)
Definition: fespi.c:160
static int fespi_wip(struct flash_bank *bank, int timeout)
Definition: fespi.c:278
#define FESPI_REG_IP
Definition: fespi.c:59
static int fespi_rx(struct flash_bank *bank, uint8_t *out)
Definition: fespi.c:254
static int slow_fespi_write_buffer(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t len)
Definition: fespi.c:429
static int fespi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: fespi.c:481
static int fespi_protect_check(struct flash_bank *bank)
Definition: fespi.c:828
const struct flash_driver fespi_flash
Definition: fespi.c:850
#define FESPI_FMT_DIR(x)
Definition: fespi.c:68
static int fespi_tx(struct flash_bank *bank, uint8_t in)
Definition: fespi.c:234
static int fespi_enable_hw_mode(struct flash_bank *bank)
Definition: fespi.c:196
static const uint8_t riscv64_bin[]
Definition: fespi.c:477
static int fespi_probe(struct flash_bank *bank)
Definition: fespi.c:723
#define FESPI_IP_TXWM
Definition: fespi.c:76
#define FESPI_REG_TXCTRL
Definition: fespi.c:52
static int get_fespi_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: fespi.c:834
#define FESPI_TXWM(x)
Definition: fespi.c:72
static int fespi_txwm_wait(struct flash_bank *bank)
Definition: fespi.c:214
static int fespi_erase_sector(struct flash_bank *bank, int sector)
Definition: fespi.c:311
#define FESPI_DIR_TX
Definition: fespi.c:97
#define FESPI_FCTRL_EN
Definition: fespi.c:79
static int fespi_disable_hw_mode(struct flash_bank *bank)
Definition: fespi.c:188
static const struct fespi_target target_devices[]
Definition: fespi.c:126
static int fespi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: fespi.c:356
FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)
Definition: fespi.c:133
#define FESPI_CSMODE_HOLD
Definition: fespi.c:93
#define FESPI_REG_FCTRL
Definition: fespi.c:55
#define FESPI_REG_CSMODE
Definition: fespi.c:42
static int fespi_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: fespi.c:421
static int fespi_auto_probe(struct flash_bank *bank)
Definition: fespi.c:820
#define FESPI_REG_RXFIFO
Definition: fespi.c:51
static int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id)
Definition: fespi.c:671
static int fespi_set_dir(struct flash_bank *bank, bool dir)
Definition: fespi.c:204
#define FESPI_CSMODE_AUTO
Definition: fespi.c:92
static int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)
Definition: fespi.c:174
#define FESPI_REG_TXFIFO
Definition: fespi.c:50
#define FESPI_PROBE_TIMEOUT
Definition: fespi.c:109
#define FESPI_REG_FMT
Definition: fespi.c:49
static const uint8_t riscv32_bin[]
Definition: fespi.c:473
#define FESPI_DIR_RX
Definition: fespi.c:96
#define FESPI_MAX_TIMEOUT
Definition: fespi.c:110
#define ERROR_FLASH_OPER_UNSUPPORTED
Definition: flash/common.h:36
#define ERROR_FLASH_SECTOR_INVALID
Definition: flash/common.h:29
#define ERROR_FLASH_BANK_NOT_PROBED
Definition: flash/common.h:35
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
The JTAG interface can be implemented with a software or hardware fifo.
void alive_sleep(uint64_t ms)
Definition: log.c:460
void keep_alive(void)
Definition: log.c:419
static int64_t start
Definition: log.c:41
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
#define MIN(a, b)
Definition: replacements.h:22
unsigned riscv_xlen(const struct target *target)
Definition: riscv.c:3290
static struct riscv_info * riscv_info(const struct target *target) __attribute__((unused))
Definition: riscv.h:269
static bool is_riscv(const struct riscv_info *riscv_info)
Definition: riscv.h:276
const struct flash_device flash_devices[]
Definition: spi.c:24
#define SPIFLASH_READ_STATUS
Definition: spi.h:74
#define SPIFLASH_READ_ID
Definition: spi.h:72
#define SPIFLASH_WRITE_ENABLE
Definition: spi.h:75
#define SPIFLASH_DEF_PAGESIZE
Definition: spi.h:82
#define SPIFLASH_BSY_BIT
Definition: spi.h:67
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
target_addr_t ctrl_base
Definition: fespi.c:115
const struct flash_device * dev
Definition: fespi.c:116
uint32_t ctrl_base
Definition: fespi.c:122
uint32_t tap_idcode
Definition: fespi.c:121
char * name
Definition: fespi.c:120
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
uint32_t sectorsize
Definition: spi.h:29
uint32_t device_id
Definition: spi.h:27
const char * name
Definition: spi.h:21
uint32_t pagesize
Definition: spi.h:28
uint32_t size_in_bytes
Definition: spi.h:30
uint8_t pprog_cmd
Definition: spi.h:24
uint8_t erase_cmd
Definition: spi.h:25
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
Definition: nor/core.h:42
uint32_t offset
Bus offset from start of the flash chip (in bytes).
Definition: nor/core.h:30
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown.
Definition: nor/core.h:55
uint32_t size
Number of bytes in this flash sector.
Definition: nor/core.h:32
uint32_t idcode
device identification code
Definition: jtag.h:114
uint8_t * value
Definition: algorithm.h:30
int xlen
Definition: riscv.h:109
Definition: target.h:120
struct jtag_tap * tap
Definition: target.h:124
enum target_state state
Definition: target.h:162
Definition: psoc6.c:84
target_addr_t address
Definition: target.h:90
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2408
uint32_t target_get_working_area_avail(struct target *target)
Definition: target.c:2233
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2129
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2707
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2187
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:846
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2616
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:792
@ TARGET_HALTED
Definition: target.h:55
#define ERROR_TARGET_TIMEOUT
Definition: target.h:791
int64_t timeval_ms(void)
#define TARGET_ADDR_FMT
Definition: types.h:342
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
uint64_t target_addr_t
Definition: types.h:335
#define TARGET_PRIxADDR
Definition: types.h:340
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22