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  return lpcspifi_set_hw_mode(bank);
450 
451  LOG_WARNING("Bulk flash erase failed. Falling back to sector-by-sector erase.");
452  }
453 
454  if (lpcspifi_info->dev->erase_cmd == 0x00)
456 
457  retval = lpcspifi_set_hw_mode(bank);
458  if (retval != ERROR_OK)
459  return retval;
460 
461  /* see contrib/loaders/flash/lpcspifi_erase.S for src */
462  static const uint8_t lpcspifi_flash_erase_code[] = {
463  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
464  0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
465  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
466  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
467  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
468  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
469  0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
470  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
471  0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
472  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
473  0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
474  0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
475  0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
476  0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
477  0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
478  0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
479  0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
480  0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
481  0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
482  0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09,
483  0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8,
484  0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
485  0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
486  0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8,
487  0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80,
488  0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09,
489  0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49,
490  0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29,
491  0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09,
492  0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8,
493  0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
494  0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
495  0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8,
496  0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf,
497  0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7,
498  0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2,
499  0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8,
500  0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4,
501  0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47,
502  0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8,
503  0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a,
504  0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80,
505  0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff
506  };
507 
508  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
509  armv7m_info.core_mode = ARM_MODE_THREAD;
510 
511 
512  /* Get memory for spifi initialization algorithm */
513  retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code),
514  &erase_algorithm);
515  if (retval != ERROR_OK) {
516  LOG_ERROR("Insufficient working area. You must configure a working"
517  " area of at least %zdB in order to erase SPIFI flash.",
518  sizeof(lpcspifi_flash_erase_code));
519  return retval;
520  }
521 
522  /* Write algorithm to working area */
523  retval = target_write_buffer(target, erase_algorithm->address,
524  sizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code);
525  if (retval != ERROR_OK) {
526  target_free_working_area(target, erase_algorithm);
527  return retval;
528  }
529 
530  init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* Start address */
531  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* Sector count */
532  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* Erase command */
533  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* Sector size */
534 
535  buf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset);
536  buf_set_u32(reg_params[1].value, 0, 32, last - first + 1);
537  buf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd);
538  buf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size);
539 
540  /* Run the algorithm */
541  retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
542  erase_algorithm->address,
543  erase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4,
544  3000*(last - first + 1), &armv7m_info);
545 
546  if (retval != ERROR_OK)
547  LOG_ERROR("Error executing flash erase algorithm");
548 
549  target_free_working_area(target, erase_algorithm);
550 
551  destroy_reg_param(&reg_params[0]);
552  destroy_reg_param(&reg_params[1]);
553  destroy_reg_param(&reg_params[2]);
554  destroy_reg_param(&reg_params[3]);
555 
556  return lpcspifi_set_hw_mode(bank);
557 }
558 
559 static int lpcspifi_protect(struct flash_bank *bank, int set,
560  unsigned int first, unsigned int last)
561 {
562  for (unsigned int sector = first; sector <= last; sector++)
563  bank->sectors[sector].is_protected = set;
564  return ERROR_OK;
565 }
566 
567 static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
568  uint32_t offset, uint32_t count)
569 {
570  struct target *target = bank->target;
571  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
572  uint32_t page_size, fifo_size;
573  struct working_area *fifo;
574  struct reg_param reg_params[5];
575  struct armv7m_algorithm armv7m_info;
576  struct working_area *write_algorithm;
577  int retval = ERROR_OK;
578 
579  LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
580  offset, count);
581 
582  if (target->state != TARGET_HALTED) {
583  LOG_ERROR("Target not halted");
585  }
586 
587  if (offset + count > lpcspifi_info->dev->size_in_bytes) {
588  LOG_WARNING("Writes past end of flash. Extra data discarded.");
589  count = lpcspifi_info->dev->size_in_bytes - offset;
590  }
591 
592  /* Check sector protection */
593  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
594  /* Start offset in or before this sector? */
595  /* End offset in or behind this sector? */
596  if ((offset <
597  (bank->sectors[sector].offset + bank->sectors[sector].size))
598  && ((offset + count - 1) >= bank->sectors[sector].offset)
599  && bank->sectors[sector].is_protected) {
600  LOG_ERROR("Flash sector %u protected", sector);
601  return ERROR_FAIL;
602  }
603  }
604 
605  /* if no valid page_size, use reasonable default */
606  page_size = lpcspifi_info->dev->pagesize ?
607  lpcspifi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
608 
609  retval = lpcspifi_set_hw_mode(bank);
610  if (retval != ERROR_OK)
611  return retval;
612 
613  /* see contrib/loaders/flash/lpcspifi_write.S for src */
614  static const uint8_t lpcspifi_flash_write_code[] = {
615  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
616  0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
617  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
618  0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
619  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
620  0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
621  0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
622  0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
623  0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
624  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
625  0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
626  0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
627  0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
628  0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
629  0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
630  0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
631  0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
632  0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
633  0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
634  0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45,
635  0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8,
636  0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8,
637  0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8,
638  0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8,
639  0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8,
640  0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f,
641  0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8,
642  0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8,
643  0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8,
644  0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8,
645  0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8,
646  0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f,
647  0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45,
648  0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b,
649  0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf,
650  0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,
651  0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45,
652  0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8,
653  0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0,
654  0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0,
655  0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0,
656  0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4,
657  0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4,
658  0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8,
659  0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0,
660  0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8,
661  0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08,
662  0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08,
663  0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
664  0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20,
665  0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46,
666  0x00, 0xbe, 0xff, 0xff
667  };
668 
669  if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code),
670  &write_algorithm) != ERROR_OK) {
671  LOG_ERROR("Insufficient working area. You must configure"
672  " a working area > %zdB in order to write to SPIFI flash.",
673  sizeof(lpcspifi_flash_write_code));
675  }
676 
677  retval = target_write_buffer(target, write_algorithm->address,
678  sizeof(lpcspifi_flash_write_code),
679  lpcspifi_flash_write_code);
680  if (retval != ERROR_OK) {
681  target_free_working_area(target, write_algorithm);
682  return retval;
683  }
684 
685  /* FIFO allocation */
687 
688  if (fifo_size == 0) {
689  /* if we already allocated the writing code but failed to get fifo
690  * space, free the algorithm */
691  target_free_working_area(target, write_algorithm);
692 
693  LOG_ERROR("Insufficient working area. Please allocate at least"
694  " %zdB of working area to enable flash writes.",
695  sizeof(lpcspifi_flash_write_code) + 1
696  );
697 
699  } else if (fifo_size < page_size)
700  LOG_WARNING("Working area size is limited; flash writes may be"
701  " slow. Increase working area size to at least %zdB"
702  " to reduce write times.",
703  (size_t)(sizeof(lpcspifi_flash_write_code) + page_size)
704  );
705  else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */
706  fifo_size = 0x2000;
707 
708  if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
709  target_free_working_area(target, write_algorithm);
711  }
712 
713  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
714  armv7m_info.core_mode = ARM_MODE_THREAD;
715 
716  init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
717  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer end */
718  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* target address */
719  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */
720  init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* page size */
721 
722  buf_set_u32(reg_params[0].value, 0, 32, fifo->address);
723  buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);
724  buf_set_u32(reg_params[2].value, 0, 32, offset);
725  buf_set_u32(reg_params[3].value, 0, 32, count);
726  buf_set_u32(reg_params[4].value, 0, 32, page_size);
727 
729  0, NULL,
730  5, reg_params,
731  fifo->address, fifo->size,
732  write_algorithm->address, 0,
733  &armv7m_info
734  );
735 
736  if (retval != ERROR_OK)
737  LOG_ERROR("Error executing flash write algorithm");
738 
740  target_free_working_area(target, write_algorithm);
741 
742  destroy_reg_param(&reg_params[0]);
743  destroy_reg_param(&reg_params[1]);
744  destroy_reg_param(&reg_params[2]);
745  destroy_reg_param(&reg_params[3]);
746  destroy_reg_param(&reg_params[4]);
747 
748  /* Switch to HW mode before return to prompt */
749  return lpcspifi_set_hw_mode(bank);
750 }
751 
752 /* Return ID of flash device */
753 /* On exit, SW mode is kept */
754 static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
755 {
756  struct target *target = bank->target;
757  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
758  uint32_t ssp_base = lpcspifi_info->ssp_base;
759  uint32_t io_base = lpcspifi_info->io_base;
760  uint32_t value;
761  uint8_t id_buf[3] = {0, 0, 0};
762  int retval;
763 
764  if (target->state != TARGET_HALTED) {
765  LOG_ERROR("Target not halted");
767  }
768 
769  LOG_DEBUG("Getting ID");
770  retval = lpcspifi_set_sw_mode(bank);
771  if (retval != ERROR_OK)
772  return retval;
773 
774  /* poll WIP */
775  if (retval == ERROR_OK)
777 
778  /* Send SPI command "read ID" */
779  if (retval == ERROR_OK)
780  retval = ssp_setcs(target, io_base, 0);
781  if (retval == ERROR_OK)
783  if (retval == ERROR_OK)
785  if (retval == ERROR_OK)
786  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
787 
788  /* Dummy write to clock in data */
789  if (retval == ERROR_OK)
790  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
791  if (retval == ERROR_OK)
793  if (retval == ERROR_OK)
794  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
795  if (retval == ERROR_OK)
796  id_buf[0] = value;
797 
798  /* Dummy write to clock in data */
799  if (retval == ERROR_OK)
800  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
801  if (retval == ERROR_OK)
803  if (retval == ERROR_OK)
804  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
805  if (retval == ERROR_OK)
806  id_buf[1] = value;
807 
808  /* Dummy write to clock in data */
809  if (retval == ERROR_OK)
810  retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
811  if (retval == ERROR_OK)
813  if (retval == ERROR_OK)
814  retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
815  if (retval == ERROR_OK)
816  id_buf[2] = value;
817 
818  if (retval == ERROR_OK)
819  retval = ssp_setcs(target, io_base, 1);
820  if (retval == ERROR_OK)
821  *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];
822 
823  return retval;
824 }
825 
826 static int lpcspifi_probe(struct flash_bank *bank)
827 {
828  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
829  struct flash_sector *sectors;
830  uint32_t id = 0; /* silence uninitialized warning */
831  int retval;
832  uint32_t sectorsize;
833 
834  /* If we've already probed, we should be fine to skip this time. */
835  if (lpcspifi_info->probed)
836  return ERROR_OK;
837  lpcspifi_info->probed = false;
838 
839  lpcspifi_info->ssp_base = 0x40083000;
840  lpcspifi_info->io_base = 0x400F4000;
841  lpcspifi_info->ioconfig_base = 0x40086000;
842  lpcspifi_info->bank_num = bank->bank_number;
843 
844  /* read and decode flash ID; returns in SW mode */
845  retval = lpcspifi_read_flash_id(bank, &id);
846  if (retval != ERROR_OK)
847  return retval;
848 
849  retval = lpcspifi_set_hw_mode(bank);
850  if (retval != ERROR_OK)
851  return retval;
852 
853  lpcspifi_info->dev = NULL;
854  for (const struct flash_device *p = flash_devices; p->name ; p++)
855  if (p->device_id == id) {
856  lpcspifi_info->dev = p;
857  break;
858  }
859 
860  if (!lpcspifi_info->dev) {
861  LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
862  return ERROR_FAIL;
863  }
864 
865  LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
866  lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
867 
868  /* Set correct size value */
869  bank->size = lpcspifi_info->dev->size_in_bytes;
870  if (bank->size <= (1UL << 16))
871  LOG_WARNING("device needs 2-byte addresses - not implemented");
872  if (bank->size > (1UL << 24))
873  LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
874 
875  /* if no sectors, treat whole bank as single sector */
876  sectorsize = lpcspifi_info->dev->sectorsize ?
877  lpcspifi_info->dev->sectorsize : lpcspifi_info->dev->size_in_bytes;
878 
879  /* create and fill sectors array */
880  bank->num_sectors = lpcspifi_info->dev->size_in_bytes / sectorsize;
881  sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
882  if (!sectors) {
883  LOG_ERROR("not enough memory");
884  return ERROR_FAIL;
885  }
886 
887  for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
888  sectors[sector].offset = sector * sectorsize;
889  sectors[sector].size = sectorsize;
890  sectors[sector].is_erased = -1;
891  sectors[sector].is_protected = 0;
892  }
893 
894  bank->sectors = sectors;
895 
896  lpcspifi_info->probed = true;
897  return ERROR_OK;
898 }
899 
901 {
902  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
903  if (lpcspifi_info->probed)
904  return ERROR_OK;
905  return lpcspifi_probe(bank);
906 }
907 
909 {
910  /* Nothing to do. Protection is only handled in SW. */
911  return ERROR_OK;
912 }
913 
915 {
916  struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
917 
918  if (!(lpcspifi_info->probed)) {
919  command_print_sameline(cmd, "\nSPIFI flash bank not probed yet\n");
920  return ERROR_OK;
921  }
922 
923  command_print_sameline(cmd, "\nSPIFI flash information:\n"
924  " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
925  lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
926 
927  return ERROR_OK;
928 }
929 
930 const struct flash_driver lpcspifi_flash = {
931  .name = "lpcspifi",
932  .flash_bank_command = lpcspifi_flash_bank_command,
933  .erase = lpcspifi_erase,
934  .protect = lpcspifi_protect,
935  .write = lpcspifi_write,
936  .read = default_flash_read,
937  .probe = lpcspifi_probe,
938  .auto_probe = lpcspifi_auto_probe,
939  .erase_check = default_flash_blank_check,
940  .protect_check = lpcspifi_protect_check,
941  .info = get_lpcspifi_info,
942  .free_driver_priv = default_flash_free_driver_priv,
943 };
void init_reg_param(struct reg_param *param, const 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:38
@ 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:229
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:378
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t page_size
Page size.
Definition: dw-spi-helper.h:3
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:478
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
#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:567
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:914
static int lpcspifi_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: lpcspifi.c:559
#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:900
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:908
#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:930
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:754
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:826
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:306
enum arm_mode core_mode
Definition: armv7m.h:308
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:119
enum target_state state
Definition: target.h:167
Definition: psoc6.c:83
uint32_t size
Definition: target.h:90
target_addr_t address
Definition: target.h:89
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2369
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:786
uint32_t target_get_working_area_avail(struct target *target)
Definition: target.c:2194
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2090
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2635
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2148
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:945
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2561
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:817
@ TARGET_HALTED
Definition: target.h:58
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:821
int64_t timeval_ms(void)
#define TARGET_ADDR_FMT
Definition: types.h:286
#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