OpenOCD
lpcspifi.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2012 by George Harris *
5  * george@luminairecoffee.com *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include "imp.h"
13 #include "spi.h"
14 #include <jtag/jtag.h>
15 #include <helper/time_support.h>
16 #include <target/algorithm.h>
17 #include <target/armv7m.h>
18 
19 /* Offsets from ssp_base into config & data registers */
20 #define SSP_CR0 (0x00) /* Control register 0 */
21 #define SSP_CR1 (0x04) /* Control register 1 */
22 #define SSP_DATA (0x08) /* Data register (TX and RX) */
23 #define SSP_SR (0x0C) /* Status register */
24 #define SSP_CPSR (0x10) /* Clock prescale register */
25 
26 /* Status register fields */
27 #define SSP_BSY (0x00000010)
28 
29 /* Timeout in ms */
30 #define SSP_CMD_TIMEOUT (100)
31 #define SSP_PROBE_TIMEOUT (100)
32 #define SSP_MAX_TIMEOUT (3000)
33 
34 /* Size of the stack to alloc in the working area for the execution of
35  * the ROM spifi_init() function */
36 #define SPIFI_INIT_STACK_SIZE 512
37 
39  bool probed;
40  uint32_t ssp_base;
41  uint32_t io_base;
42  uint32_t ioconfig_base;
43  uint32_t bank_num;
45  const struct flash_device *dev;
46 };
47 
48 /* flash_bank lpcspifi <base> <size> <chip_width> <bus_width> <target>
49  */
50 FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)
51 {
52  struct lpcspifi_flash_bank *lpcspifi_info;
53 
54  if (CMD_ARGC < 6)
56 
57  lpcspifi_info = malloc(sizeof(struct lpcspifi_flash_bank));
58  if (!lpcspifi_info) {
59  LOG_ERROR("not enough memory");
60  return ERROR_FAIL;
61  }
62 
63  bank->driver_priv = lpcspifi_info;
64  lpcspifi_info->probed = false;
65 
66  return ERROR_OK;
67 }
68 
69 static inline int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value)
70 {
71  return target_write_u32(target, ioconfig_base + offset, value);
72 }
73 
74 static inline int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value)
75 {
76  return target_write_u32(target, ssp_base + offset, value);
77 }
78 
79 static inline int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value)
80 {
81  return target_write_u32(target, io_base + offset, value);
82 }
83 
84 static inline int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value)
85 {
86  return target_read_u32(target, ssp_base + offset, value);
87 }
88 
89 static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value)
90 {
91  return io_write_reg(target, io_base, 0x12ac, value ? 0xffffffff : 0x00000000);
92 }
93 
94 /* Poll the SSP busy flag. When this comes back as 0, the transfer is complete
95  * and the controller is idle. */
96 static int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout)
97 {
98  int64_t endtime;
99  uint32_t value;
100  int retval;
101 
102  retval = ssp_read_reg(target, ssp_base, SSP_SR, &value);
103  if ((retval == ERROR_OK) && (value & SSP_BSY) == 0)
104  return ERROR_OK;
105  else if (retval != ERROR_OK)
106  return retval;
107 
108  endtime = timeval_ms() + timeout;
109  do {
110  alive_sleep(1);
111  retval = ssp_read_reg(target, ssp_base, SSP_SR, &value);
112  if ((retval == ERROR_OK) && (value & SSP_BSY) == 0)
113  return ERROR_OK;
114  else if (retval != ERROR_OK)
115  return retval;
116  } while (timeval_ms() < endtime);
117 
118  LOG_ERROR("Timeout while polling BSY");
120 }
121 
122 /* Un-initialize the ssp module and initialize the SPIFI module */
124 {
125  struct target *target = bank->target;
126  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
127  uint32_t ssp_base = lpcspifi_info->ssp_base;
128  struct armv7m_algorithm armv7m_info;
129  struct working_area *spifi_init_algorithm;
130  struct reg_param reg_params[2];
131  int retval = ERROR_OK;
132 
133  LOG_DEBUG("Uninitializing LPC43xx SSP");
134  /* Turn off the SSP module */
135  retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);
136  if (retval != ERROR_OK)
137  return retval;
138 
139  /* see contrib/loaders/flash/lpcspifi_init.S for src */
140  static const uint8_t spifi_init_code[] = {
141  0x4f, 0xea, 0x00, 0x08, 0xa1, 0xb0, 0x00, 0xaf,
142  0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
143  0x4f, 0xf0, 0xf3, 0x02, 0xc3, 0xf8, 0x8c, 0x21,
144  0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
145  0x4f, 0xf4, 0xc0, 0x42, 0xc4, 0xf2, 0x08, 0x02,
146  0x4f, 0xf4, 0xc0, 0x41, 0xc4, 0xf2, 0x08, 0x01,
147  0x4f, 0xf4, 0xc0, 0x40, 0xc4, 0xf2, 0x08, 0x00,
148  0x4f, 0xf0, 0xd3, 0x04, 0xc0, 0xf8, 0x9c, 0x41,
149  0x20, 0x46, 0xc1, 0xf8, 0x98, 0x01, 0x01, 0x46,
150  0xc2, 0xf8, 0x94, 0x11, 0xc3, 0xf8, 0x90, 0x11,
151  0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
152  0x4f, 0xf0, 0x13, 0x02, 0xc3, 0xf8, 0xa0, 0x21,
153  0x40, 0xf2, 0x18, 0x13, 0xc1, 0xf2, 0x40, 0x03,
154  0x1b, 0x68, 0x1c, 0x68, 0x40, 0xf2, 0xb4, 0x30,
155  0xc1, 0xf2, 0x00, 0x00, 0x4f, 0xf0, 0x03, 0x01,
156  0x4f, 0xf0, 0xc0, 0x02, 0x4f, 0xea, 0x08, 0x03,
157  0xa0, 0x47, 0x00, 0xf0, 0x00, 0xb8, 0x00, 0xbe
158  };
159 
160  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
161  armv7m_info.core_mode = ARM_MODE_THREAD;
162 
163 
164  LOG_DEBUG("Allocating working area for SPIFI init algorithm");
165  /* Get memory for spifi initialization algorithm */
166  retval = target_alloc_working_area(target, sizeof(spifi_init_code)
167  + SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm);
168  if (retval != ERROR_OK) {
169  LOG_ERROR("Insufficient working area to initialize SPIFI "
170  "module. You must allocate at least %zdB of working "
171  "area in order to use this driver.",
172  sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE
173  );
174 
175  return retval;
176  }
177 
178  LOG_DEBUG("Writing algorithm to working area at " TARGET_ADDR_FMT,
179  spifi_init_algorithm->address);
180  /* Write algorithm to working area */
181  retval = target_write_buffer(target,
182  spifi_init_algorithm->address,
183  sizeof(spifi_init_code),
184  spifi_init_code
185  );
186 
187  if (retval != ERROR_OK) {
188  target_free_working_area(target, spifi_init_algorithm);
189  return retval;
190  }
191 
192  init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* spifi clk speed */
193  /* the spifi_init() rom API makes use of the stack */
194  init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
195 
196  /* For now, the algorithm will set up the SPIFI module
197  * @ the IRC clock speed. In the future, it could be made
198  * a bit smarter to use other clock sources if the user has
199  * already configured them in order to speed up memory-
200  * mapped reads. */
201  buf_set_u32(reg_params[0].value, 0, 32, 12);
202  /* valid stack pointer */
203  buf_set_u32(reg_params[1].value, 0, 32, (spifi_init_algorithm->address +
204  sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE) & ~7UL);
205 
206  /* Run the algorithm */
207  LOG_DEBUG("Running SPIFI init algorithm");
208  retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
209  spifi_init_algorithm->address,
210  spifi_init_algorithm->address + sizeof(spifi_init_code) - 2,
211  1000, &armv7m_info);
212 
213  if (retval != ERROR_OK)
214  LOG_ERROR("Error executing SPIFI init algorithm");
215 
216  target_free_working_area(target, spifi_init_algorithm);
217 
218  destroy_reg_param(&reg_params[0]);
219  destroy_reg_param(&reg_params[1]);
220 
221  return retval;
222 }
223 
224 /* Initialize the ssp module */
226 {
227  struct target *target = bank->target;
228  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
229  uint32_t ssp_base = lpcspifi_info->ssp_base;
230  uint32_t io_base = lpcspifi_info->io_base;
231  uint32_t ioconfig_base = lpcspifi_info->ioconfig_base;
232  int retval = ERROR_OK;
233 
234  /* Re-initialize SPIFI. There are a couple of errata on this, so this makes
235  sure that nothing's in an unhappy state. */
236  retval = lpcspifi_set_hw_mode(bank);
237 
238  /* If we couldn't initialize hardware mode, don't even bother continuing */
239  if (retval != ERROR_OK)
240  return retval;
241 
242  /* Initialize the pins */
243  retval = ioconfig_write_reg(target, ioconfig_base, 0x194, 0x00000040);
244  if (retval == ERROR_OK)
245  retval = ioconfig_write_reg(target, ioconfig_base, 0x1a0, 0x00000044);
246  if (retval == ERROR_OK)
247  retval = ioconfig_write_reg(target, ioconfig_base, 0x190, 0x00000040);
248  if (retval == ERROR_OK)
249  retval = ioconfig_write_reg(target, ioconfig_base, 0x19c, 0x000000ed);
250  if (retval == ERROR_OK)
251  retval = ioconfig_write_reg(target, ioconfig_base, 0x198, 0x000000ed);
252  if (retval == ERROR_OK)
253  retval = ioconfig_write_reg(target, ioconfig_base, 0x18c, 0x000000ea);
254 
255  /* Set CS high & as an output */
256  if (retval == ERROR_OK)
257  retval = io_write_reg(target, io_base, 0x12ac, 0xffffffff);
258  if (retval == ERROR_OK)
259  retval = io_write_reg(target, io_base, 0x2014, 0x00000800);
260 
261  /* Initialize the module */
262  if (retval == ERROR_OK)
263  retval = ssp_write_reg(target, ssp_base, SSP_CR0, 0x00000007);
264  if (retval == ERROR_OK)
265  retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);
266  if (retval == ERROR_OK)
267  retval = ssp_write_reg(target, ssp_base, SSP_CPSR, 0x00000008);
268  if (retval == ERROR_OK)
269  retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000002);
270 
271  /* If something didn't work out, attempt to return SPIFI to HW mode */
272  if (retval != ERROR_OK)
274 
275  return retval;
276 }
277 
278 /* Read the status register of the external SPI flash chip. */
279 static int read_status_reg(struct flash_bank *bank, uint32_t *status)
280 {
281  struct target *target = bank->target;
282  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
283  uint32_t ssp_base = lpcspifi_info->ssp_base;
284  uint32_t io_base = lpcspifi_info->io_base;
285  uint32_t value;
286  int retval = ERROR_OK;
287 
288  retval = ssp_setcs(target, io_base, 0);
289  if (retval == ERROR_OK)
291  if (retval == ERROR_OK)
293  if (retval == ERROR_OK)
294  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
295  /* Dummy write to clock in the register */
296  if (retval == ERROR_OK)
297  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
298  if (retval == ERROR_OK)
300  if (retval == ERROR_OK)
301  retval = ssp_setcs(target, io_base, 1);
302 
303  if (retval == ERROR_OK)
304  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
305  if (retval == ERROR_OK)
306  *status = value;
307 
308  return retval;
309 }
310 
311 /* check for BSY bit in flash status register */
312 /* timeout in ms */
313 static int wait_till_ready(struct flash_bank *bank, int timeout)
314 {
315  uint32_t status;
316  int retval;
317  int64_t endtime;
318 
319  endtime = timeval_ms() + timeout;
320  do {
321  /* read flash status register */
322  retval = read_status_reg(bank, &status);
323  if (retval != ERROR_OK)
324  return retval;
325 
326  if ((status & SPIFLASH_BSY_BIT) == 0)
327  return ERROR_OK;
328  alive_sleep(1);
329  } while (timeval_ms() < endtime);
330 
331  LOG_ERROR("timeout waiting for flash to finish write/erase operation");
332  return ERROR_FAIL;
333 }
334 
335 /* Send "write enable" command to SPI flash chip. */
337 {
338  struct target *target = bank->target;
339  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
340  uint32_t ssp_base = lpcspifi_info->ssp_base;
341  uint32_t io_base = lpcspifi_info->io_base;
342  uint32_t status, value;
343  int retval = ERROR_OK;
344 
345  retval = ssp_setcs(target, io_base, 0);
346  if (retval == ERROR_OK)
348  if (retval == ERROR_OK)
350  if (retval == ERROR_OK)
351  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
352  if (retval == ERROR_OK)
353  retval = ssp_setcs(target, io_base, 1);
354 
355  /* read flash status register */
356  if (retval == ERROR_OK)
357  retval = read_status_reg(bank, &status);
358  if (retval != ERROR_OK)
359  return retval;
360 
361  /* Check write enabled */
362  if ((status & SPIFLASH_WE_BIT) == 0) {
363  LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status);
364  return ERROR_FAIL;
365  }
366 
367  return retval;
368 }
369 
371 {
372  struct target *target = bank->target;
373  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
374  uint32_t ssp_base = lpcspifi_info->ssp_base;
375  uint32_t io_base = lpcspifi_info->io_base;
376  uint32_t value;
377  int retval = ERROR_OK;
378 
379  if (lpcspifi_info->dev->chip_erase_cmd == 0x00)
381 
382  retval = lpcspifi_set_sw_mode(bank);
383 
384  if (retval == ERROR_OK)
385  retval = lpcspifi_write_enable(bank);
386 
387  /* send SPI command "bulk erase" */
388  if (retval == ERROR_OK)
389  ssp_setcs(target, io_base, 0);
390  if (retval == ERROR_OK)
391  retval = ssp_write_reg(target, ssp_base, SSP_DATA, lpcspifi_info->dev->chip_erase_cmd);
392  if (retval == ERROR_OK)
394  if (retval == ERROR_OK)
395  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
396  if (retval == ERROR_OK)
397  retval = ssp_setcs(target, io_base, 1);
398 
399  /* poll flash BSY for self-timed bulk erase */
400  if (retval == ERROR_OK)
401  retval = wait_till_ready(bank, bank->num_sectors*SSP_MAX_TIMEOUT);
402 
403  return retval;
404 }
405 
406 static int lpcspifi_erase(struct flash_bank *bank, unsigned int first,
407  unsigned int last)
408 {
409  struct target *target = bank->target;
410  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
411  struct reg_param reg_params[4];
412  struct armv7m_algorithm armv7m_info;
413  struct working_area *erase_algorithm;
414  int retval = ERROR_OK;
415 
416  LOG_DEBUG("erase from sector %u to sector %u", first, last);
417 
418  if (target->state != TARGET_HALTED) {
419  LOG_ERROR("Target not halted");
421  }
422 
423  if ((last < first) || (last >= bank->num_sectors)) {
424  LOG_ERROR("Flash sector invalid");
426  }
427 
428  if (!(lpcspifi_info->probed)) {
429  LOG_ERROR("Flash bank not probed");
431  }
432 
433  for (unsigned int sector = first; sector <= last; sector++) {
434  if (bank->sectors[sector].is_protected) {
435  LOG_ERROR("Flash sector %u protected", sector);
436  return ERROR_FAIL;
437  }
438  }
439 
440  /* If we're erasing the entire chip and the flash supports
441  * it, use a bulk erase instead of going sector-by-sector. */
442  if (first == 0 && last == (bank->num_sectors - 1)
443  && lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) {
444  LOG_DEBUG("Chip supports the bulk erase command."
445  " Will use bulk erase instead of sector-by-sector erase.");
446  retval = lpcspifi_bulk_erase(bank);
447 
448  if (retval == ERROR_OK) {
449  retval = lpcspifi_set_hw_mode(bank);
450  return retval;
451  } else
452  LOG_WARNING("Bulk flash erase failed. Falling back to sector-by-sector erase.");
453  }
454 
455  if (lpcspifi_info->dev->erase_cmd == 0x00)
457 
458  retval = lpcspifi_set_hw_mode(bank);
459  if (retval != ERROR_OK)
460  return retval;
461 
462  /* see contrib/loaders/flash/lpcspifi_erase.S for src */
463  static const uint8_t lpcspifi_flash_erase_code[] = {
464  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
465  0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
466  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
467  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
468  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
469  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
470  0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
471  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
472  0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
473  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
474  0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
475  0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
476  0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
477  0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
478  0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
479  0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
480  0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
481  0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
482  0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
483  0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09,
484  0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8,
485  0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
486  0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
487  0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8,
488  0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80,
489  0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09,
490  0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49,
491  0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29,
492  0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09,
493  0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8,
494  0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
495  0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
496  0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8,
497  0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf,
498  0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7,
499  0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2,
500  0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8,
501  0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4,
502  0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47,
503  0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8,
504  0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a,
505  0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80,
506  0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff
507  };
508 
509  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
510  armv7m_info.core_mode = ARM_MODE_THREAD;
511 
512 
513  /* Get memory for spifi initialization algorithm */
514  retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code),
515  &erase_algorithm);
516  if (retval != ERROR_OK) {
517  LOG_ERROR("Insufficient working area. You must configure a working"
518  " area of at least %zdB in order to erase SPIFI flash.",
519  sizeof(lpcspifi_flash_erase_code));
520  return retval;
521  }
522 
523  /* Write algorithm to working area */
524  retval = target_write_buffer(target, erase_algorithm->address,
525  sizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code);
526  if (retval != ERROR_OK) {
527  target_free_working_area(target, erase_algorithm);
528  return retval;
529  }
530 
531  init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* Start address */
532  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* Sector count */
533  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* Erase command */
534  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* Sector size */
535 
536  buf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset);
537  buf_set_u32(reg_params[1].value, 0, 32, last - first + 1);
538  buf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd);
539  buf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size);
540 
541  /* Run the algorithm */
542  retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
543  erase_algorithm->address,
544  erase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4,
545  3000*(last - first + 1), &armv7m_info);
546 
547  if (retval != ERROR_OK)
548  LOG_ERROR("Error executing flash erase algorithm");
549 
550  target_free_working_area(target, erase_algorithm);
551 
552  destroy_reg_param(&reg_params[0]);
553  destroy_reg_param(&reg_params[1]);
554  destroy_reg_param(&reg_params[2]);
555  destroy_reg_param(&reg_params[3]);
556 
557  retval = lpcspifi_set_hw_mode(bank);
558 
559  return retval;
560 }
561 
562 static int lpcspifi_protect(struct flash_bank *bank, int set,
563  unsigned int first, unsigned int last)
564 {
565  for (unsigned int sector = first; sector <= last; sector++)
566  bank->sectors[sector].is_protected = set;
567  return ERROR_OK;
568 }
569 
570 static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
571  uint32_t offset, uint32_t count)
572 {
573  struct target *target = bank->target;
574  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
575  uint32_t page_size, fifo_size;
576  struct working_area *fifo;
577  struct reg_param reg_params[5];
578  struct armv7m_algorithm armv7m_info;
579  struct working_area *write_algorithm;
580  int retval = ERROR_OK;
581 
582  LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
583  offset, count);
584 
585  if (target->state != TARGET_HALTED) {
586  LOG_ERROR("Target not halted");
588  }
589 
590  if (offset + count > lpcspifi_info->dev->size_in_bytes) {
591  LOG_WARNING("Writes past end of flash. Extra data discarded.");
592  count = lpcspifi_info->dev->size_in_bytes - offset;
593  }
594 
595  /* Check sector protection */
596  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
597  /* Start offset in or before this sector? */
598  /* End offset in or behind this sector? */
599  if ((offset <
600  (bank->sectors[sector].offset + bank->sectors[sector].size))
601  && ((offset + count - 1) >= bank->sectors[sector].offset)
602  && bank->sectors[sector].is_protected) {
603  LOG_ERROR("Flash sector %u protected", sector);
604  return ERROR_FAIL;
605  }
606  }
607 
608  /* if no valid page_size, use reasonable default */
609  page_size = lpcspifi_info->dev->pagesize ?
610  lpcspifi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
611 
612  retval = lpcspifi_set_hw_mode(bank);
613  if (retval != ERROR_OK)
614  return retval;
615 
616  /* see contrib/loaders/flash/lpcspifi_write.S for src */
617  static const uint8_t lpcspifi_flash_write_code[] = {
618  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
619  0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
620  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
621  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
622  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
623  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
624  0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
625  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
626  0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
627  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
628  0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
629  0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
630  0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
631  0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
632  0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
633  0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
634  0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
635  0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
636  0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
637  0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45,
638  0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8,
639  0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8,
640  0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8,
641  0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8,
642  0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8,
643  0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f,
644  0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8,
645  0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8,
646  0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8,
647  0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8,
648  0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8,
649  0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f,
650  0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45,
651  0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b,
652  0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf,
653  0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,
654  0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45,
655  0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8,
656  0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0,
657  0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0,
658  0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0,
659  0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4,
660  0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4,
661  0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8,
662  0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0,
663  0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8,
664  0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08,
665  0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08,
666  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
667  0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20,
668  0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46,
669  0x00, 0xbe, 0xff, 0xff
670  };
671 
672  if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code),
673  &write_algorithm) != ERROR_OK) {
674  LOG_ERROR("Insufficient working area. You must configure"
675  " a working area > %zdB in order to write to SPIFI flash.",
676  sizeof(lpcspifi_flash_write_code));
678  }
679 
680  retval = target_write_buffer(target, write_algorithm->address,
681  sizeof(lpcspifi_flash_write_code),
682  lpcspifi_flash_write_code);
683  if (retval != ERROR_OK) {
684  target_free_working_area(target, write_algorithm);
685  return retval;
686  }
687 
688  /* FIFO allocation */
690 
691  if (fifo_size == 0) {
692  /* if we already allocated the writing code but failed to get fifo
693  * space, free the algorithm */
694  target_free_working_area(target, write_algorithm);
695 
696  LOG_ERROR("Insufficient working area. Please allocate at least"
697  " %zdB of working area to enable flash writes.",
698  sizeof(lpcspifi_flash_write_code) + 1
699  );
700 
702  } else if (fifo_size < page_size)
703  LOG_WARNING("Working area size is limited; flash writes may be"
704  " slow. Increase working area size to at least %zdB"
705  " to reduce write times.",
706  (size_t)(sizeof(lpcspifi_flash_write_code) + page_size)
707  );
708  else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */
709  fifo_size = 0x2000;
710 
711  if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
712  target_free_working_area(target, write_algorithm);
714  }
715 
716  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
717  armv7m_info.core_mode = ARM_MODE_THREAD;
718 
719  init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
720  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer end */
721  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* target address */
722  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */
723  init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* page size */
724 
725  buf_set_u32(reg_params[0].value, 0, 32, fifo->address);
726  buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);
727  buf_set_u32(reg_params[2].value, 0, 32, offset);
728  buf_set_u32(reg_params[3].value, 0, 32, count);
729  buf_set_u32(reg_params[4].value, 0, 32, page_size);
730 
732  0, NULL,
733  5, reg_params,
734  fifo->address, fifo->size,
735  write_algorithm->address, 0,
736  &armv7m_info
737  );
738 
739  if (retval != ERROR_OK)
740  LOG_ERROR("Error executing flash write algorithm");
741 
743  target_free_working_area(target, write_algorithm);
744 
745  destroy_reg_param(&reg_params[0]);
746  destroy_reg_param(&reg_params[1]);
747  destroy_reg_param(&reg_params[2]);
748  destroy_reg_param(&reg_params[3]);
749  destroy_reg_param(&reg_params[4]);
750 
751  /* Switch to HW mode before return to prompt */
752  retval = lpcspifi_set_hw_mode(bank);
753  return retval;
754 }
755 
756 /* Return ID of flash device */
757 /* On exit, SW mode is kept */
758 static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
759 {
760  struct target *target = bank->target;
761  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
762  uint32_t ssp_base = lpcspifi_info->ssp_base;
763  uint32_t io_base = lpcspifi_info->io_base;
764  uint32_t value;
765  uint8_t id_buf[3] = {0, 0, 0};
766  int retval;
767 
768  if (target->state != TARGET_HALTED) {
769  LOG_ERROR("Target not halted");
771  }
772 
773  LOG_DEBUG("Getting ID");
774  retval = lpcspifi_set_sw_mode(bank);
775  if (retval != ERROR_OK)
776  return retval;
777 
778  /* poll WIP */
779  if (retval == ERROR_OK)
781 
782  /* Send SPI command "read ID" */
783  if (retval == ERROR_OK)
784  retval = ssp_setcs(target, io_base, 0);
785  if (retval == ERROR_OK)
787  if (retval == ERROR_OK)
789  if (retval == ERROR_OK)
790  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
791 
792  /* Dummy write to clock in data */
793  if (retval == ERROR_OK)
794  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
795  if (retval == ERROR_OK)
797  if (retval == ERROR_OK)
798  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
799  if (retval == ERROR_OK)
800  id_buf[0] = value;
801 
802  /* Dummy write to clock in data */
803  if (retval == ERROR_OK)
804  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
805  if (retval == ERROR_OK)
807  if (retval == ERROR_OK)
808  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
809  if (retval == ERROR_OK)
810  id_buf[1] = value;
811 
812  /* Dummy write to clock in data */
813  if (retval == ERROR_OK)
814  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
815  if (retval == ERROR_OK)
817  if (retval == ERROR_OK)
818  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
819  if (retval == ERROR_OK)
820  id_buf[2] = value;
821 
822  if (retval == ERROR_OK)
823  retval = ssp_setcs(target, io_base, 1);
824  if (retval == ERROR_OK)
825  *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];
826 
827  return retval;
828 }
829 
830 static int lpcspifi_probe(struct flash_bank *bank)
831 {
832  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
833  struct flash_sector *sectors;
834  uint32_t id = 0; /* silence uninitialized warning */
835  int retval;
836  uint32_t sectorsize;
837 
838  /* If we've already probed, we should be fine to skip this time. */
839  if (lpcspifi_info->probed)
840  return ERROR_OK;
841  lpcspifi_info->probed = false;
842 
843  lpcspifi_info->ssp_base = 0x40083000;
844  lpcspifi_info->io_base = 0x400F4000;
845  lpcspifi_info->ioconfig_base = 0x40086000;
846  lpcspifi_info->bank_num = bank->bank_number;
847 
848  /* read and decode flash ID; returns in SW mode */
849  retval = lpcspifi_read_flash_id(bank, &id);
850  if (retval != ERROR_OK)
851  return retval;
852 
853  retval = lpcspifi_set_hw_mode(bank);
854  if (retval != ERROR_OK)
855  return retval;
856 
857  lpcspifi_info->dev = NULL;
858  for (const struct flash_device *p = flash_devices; p->name ; p++)
859  if (p->device_id == id) {
860  lpcspifi_info->dev = p;
861  break;
862  }
863 
864  if (!lpcspifi_info->dev) {
865  LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
866  return ERROR_FAIL;
867  }
868 
869  LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
870  lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
871 
872  /* Set correct size value */
873  bank->size = lpcspifi_info->dev->size_in_bytes;
874  if (bank->size <= (1UL << 16))
875  LOG_WARNING("device needs 2-byte addresses - not implemented");
876  if (bank->size > (1UL << 24))
877  LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
878 
879  /* if no sectors, treat whole bank as single sector */
880  sectorsize = lpcspifi_info->dev->sectorsize ?
881  lpcspifi_info->dev->sectorsize : lpcspifi_info->dev->size_in_bytes;
882 
883  /* create and fill sectors array */
884  bank->num_sectors = lpcspifi_info->dev->size_in_bytes / sectorsize;
885  sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
886  if (!sectors) {
887  LOG_ERROR("not enough memory");
888  return ERROR_FAIL;
889  }
890 
891  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
892  sectors[sector].offset = sector * sectorsize;
893  sectors[sector].size = sectorsize;
894  sectors[sector].is_erased = -1;
895  sectors[sector].is_protected = 0;
896  }
897 
898  bank->sectors = sectors;
899 
900  lpcspifi_info->probed = true;
901  return ERROR_OK;
902 }
903 
905 {
906  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
907  if (lpcspifi_info->probed)
908  return ERROR_OK;
909  return lpcspifi_probe(bank);
910 }
911 
913 {
914  /* Nothing to do. Protection is only handled in SW. */
915  return ERROR_OK;
916 }
917 
919 {
920  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
921 
922  if (!(lpcspifi_info->probed)) {
923  command_print_sameline(cmd, "\nSPIFI flash bank not probed yet\n");
924  return ERROR_OK;
925  }
926 
927  command_print_sameline(cmd, "\nSPIFI flash information:\n"
928  " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
929  lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
930 
931  return ERROR_OK;
932 }
933 
934 const struct flash_driver lpcspifi_flash = {
935  .name = "lpcspifi",
936  .flash_bank_command = lpcspifi_flash_bank_command,
937  .erase = lpcspifi_erase,
938  .protect = lpcspifi_protect,
939  .write = lpcspifi_write,
940  .read = default_flash_read,
941  .probe = lpcspifi_probe,
942  .auto_probe = lpcspifi_auto_probe,
943  .erase_check = default_flash_blank_check,
944  .protect_check = lpcspifi_protect_check,
945  .info = get_lpcspifi_info,
946  .free_driver_priv = default_flash_free_driver_priv,
947 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ PARAM_IN_OUT
Definition: algorithm.h:17
@ ARM_MODE_THREAD
Definition: arm.h:94
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:220
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
uint8_t bank
Definition: esirisc.c:135
#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
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:30
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:456
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define SSP_PROBE_TIMEOUT
Definition: lpcspifi.c:31
#define SSP_MAX_TIMEOUT
Definition: lpcspifi.c:32
static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: lpcspifi.c:570
static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value)
Definition: lpcspifi.c:89
static int get_lpcspifi_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: lpcspifi.c:918
static int lpcspifi_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: lpcspifi.c:562
#define SSP_CR0
Definition: lpcspifi.c:20
FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)
Definition: lpcspifi.c:50
#define SSP_BSY
Definition: lpcspifi.c:27
#define SSP_CMD_TIMEOUT
Definition: lpcspifi.c:30
static int lpcspifi_auto_probe(struct flash_bank *bank)
Definition: lpcspifi.c:904
static int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout)
Definition: lpcspifi.c:96
static int read_status_reg(struct flash_bank *bank, uint32_t *status)
Definition: lpcspifi.c:279
static int lpcspifi_protect_check(struct flash_bank *bank)
Definition: lpcspifi.c:912
#define SSP_CR1
Definition: lpcspifi.c:21
static int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value)
Definition: lpcspifi.c:84
static int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value)
Definition: lpcspifi.c:69
static int lpcspifi_write_enable(struct flash_bank *bank)
Definition: lpcspifi.c:336
static int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value)
Definition: lpcspifi.c:79
#define SPIFI_INIT_STACK_SIZE
Definition: lpcspifi.c:36
static int wait_till_ready(struct flash_bank *bank, int timeout)
Definition: lpcspifi.c:313
const struct flash_driver lpcspifi_flash
Definition: lpcspifi.c:934
static int lpcspifi_set_sw_mode(struct flash_bank *bank)
Definition: lpcspifi.c:225
#define SSP_CPSR
Definition: lpcspifi.c:24
static int lpcspifi_bulk_erase(struct flash_bank *bank)
Definition: lpcspifi.c:370
static int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value)
Definition: lpcspifi.c:74
static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
Definition: lpcspifi.c:758
static int lpcspifi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: lpcspifi.c:406
#define SSP_SR
Definition: lpcspifi.c:23
#define SSP_DATA
Definition: lpcspifi.c:22
static int lpcspifi_probe(struct flash_bank *bank)
Definition: lpcspifi.c:830
static int lpcspifi_set_hw_mode(struct flash_bank *bank)
Definition: lpcspifi.c:123
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_WE_BIT
Definition: spi.h:69
#define SPIFLASH_DEF_PAGESIZE
Definition: spi.h:82
#define SPIFLASH_BSY_BIT
Definition: spi.h:67
unsigned int common_magic
Definition: armv7m.h:295
enum arm_mode core_mode
Definition: armv7m.h:297
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
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
uint8_t chip_erase_cmd
Definition: spi.h:26
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 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 ssp_base
Definition: lpcspifi.c:40
const struct flash_device * dev
Definition: lpcspifi.c:45
uint32_t bank_num
Definition: lpcspifi.c:43
uint32_t max_spi_clock_mhz
Definition: lpcspifi.c:44
uint32_t io_base
Definition: lpcspifi.c:41
uint32_t ioconfig_base
Definition: lpcspifi.c:42
uint8_t * value
Definition: algorithm.h:30
Definition: target.h:116
enum target_state state
Definition: target.h:157
Definition: psoc6.c:83
uint32_t size
Definition: target.h:87
target_addr_t address
Definition: target.h:86
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
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, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:773
uint32_t target_get_working_area_avail(struct target *target)
Definition: target.c:2164
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2060
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2118
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Streams data to a circular buffer on target intended for consumption by code running asynchronously o...
Definition: target.c:930
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
int64_t timeval_ms(void)
#define TARGET_ADDR_FMT
Definition: types.h:342
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22