coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
fast_spi_flash.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <commonlib/helpers.h>
5 #include <console/console.h>
6 #include <fast_spi_def.h>
7 #include <intelblocks/fast_spi.h>
8 #include <soc/pci_devs.h>
9 #include <spi_flash.h>
10 #include <string.h>
11 #include <timer.h>
12 
13 /* Helper to create a FAST_SPI context on API entry. */
14 #define BOILERPLATE_CREATE_CTX(ctx) \
15  struct fast_spi_flash_ctx real_ctx; \
16  struct fast_spi_flash_ctx *ctx = &real_ctx; \
17  _fast_spi_flash_get_ctx(ctx)
18 
19 /*
20  * Anything that's not success is <0. Provided solely for readability, as these
21  * constants are not used outside this file.
22  */
23 enum errors {
24  SUCCESS = 0,
25  E_TIMEOUT = -1,
26  E_HW_ERROR = -2,
27  E_ARGUMENT = -3,
28 };
29 
30 /* Reduce data-passing burden by grouping transaction data in a context. */
33 };
34 
36 {
38 }
39 
40 /* Read register from the FAST_SPI flash controller. */
42  uint16_t reg)
43 {
44  uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, sizeof(uint32_t));
45  return read32((void *)addr);
46 }
47 
48 /* Write to register in FAST_SPI flash controller. */
50  uint16_t reg, uint32_t val)
51 {
52  uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, sizeof(uint32_t));
53  write32((void *)addr, val);
54 }
55 
56 /*
57  * The hardware datasheet is not clear on what HORD values actually do. It
58  * seems that HORD_SFDP provides access to the first 8 bytes of the SFDP, which
59  * is the signature and revision fields. HORD_JEDEC provides access to the
60  * actual flash parameters, and is most likely what you want to use when
61  * probing the flash from software.
62  * It's okay to rely on SFDP, since the SPI flash controller requires an SFDP
63  * 1.5 or newer compliant FAST_SPI flash chip.
64  * NOTE: Due to the register layout of the hardware, all accesses will be
65  * aligned to a 4 byte boundary.
66  */
68  uint16_t sfdp_reg)
69 {
70  uint32_t ptinx_index = sfdp_reg & SPIBAR_PTINX_IDX_MASK;
72  ptinx_index | SPIBAR_PTINX_HORD_JEDEC);
74 }
75 
76 /* Fill FDATAn FIFO in preparation for a write transaction. */
77 static void fill_xfer_fifo(struct fast_spi_flash_ctx *ctx, const void *data,
78  size_t len)
79 {
80  /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */
81  memcpy((void *)(ctx->mmio_base + SPIBAR_FDATA(0)), data, len);
82 }
83 
84 /* Drain FDATAn FIFO after a read transaction populates data. */
85 static void drain_xfer_fifo(struct fast_spi_flash_ctx *ctx, void *dest,
86  size_t len)
87 {
88  /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */
89  memcpy(dest, (void *)(ctx->mmio_base + SPIBAR_FDATA(0)), len);
90 }
91 
92 /* Fire up a transfer using the hardware sequencer. */
93 static void start_hwseq_xfer(struct fast_spi_flash_ctx *ctx,
94  uint32_t hsfsts_cycle, uint32_t flash_addr, size_t len)
95 {
96  /* Make sure all W1C status bits get cleared. */
98  /* Set up transaction parameters. */
99  hsfsts |= hsfsts_cycle & SPIBAR_HSFSTS_FCYCLE_MASK;
100  hsfsts |= SPIBAR_HSFSTS_FDBC(len - 1);
101 
104  hsfsts | SPIBAR_HSFSTS_FGO);
105 }
106 
108  uint32_t flash_addr)
109 {
110  struct stopwatch sw;
111  uint32_t hsfsts;
112 
114  do {
116 
117  if (hsfsts & SPIBAR_HSFSTS_FCERR) {
118  printk(BIOS_ERR, "SPI Transaction Error at Flash Offset %x HSFSTS = 0x%08x\n",
119  flash_addr, hsfsts);
120  return E_HW_ERROR;
121  }
122 
123  if (hsfsts & SPIBAR_HSFSTS_FDONE)
124  return SUCCESS;
125  } while (!(stopwatch_expired(&sw)));
126 
127  printk(BIOS_ERR, "SPI Transaction Timeout (Exceeded %d ms) at Flash Offset %x HSFSTS = 0x%08x\n",
128  SPIBAR_HWSEQ_XFER_TIMEOUT_MS, flash_addr, hsfsts);
129  return E_TIMEOUT;
130 }
131 
133 {
134  struct stopwatch sw;
135  uint32_t hsfsts;
136 
138  do {
140 
141  if (!(hsfsts & SPIBAR_HSFSTS_SCIP))
142  return SUCCESS;
143  } while (!(stopwatch_expired(&sw)));
144 
145  return E_TIMEOUT;
146 }
147 
148 /* Execute FAST_SPI flash transfer. This is a blocking call. */
150  uint32_t hsfsts_cycle, uint32_t flash_addr,
151  size_t len)
152 {
154  printk(BIOS_ERR, "SPI Transaction Timeout (Exceeded %d ms) due to prior"
155  " operation at Flash Offset %x\n",
156  SPIBAR_HWSEQ_XFER_TIMEOUT_MS, flash_addr);
157  return E_TIMEOUT;
158  }
159 
160  start_hwseq_xfer(ctx, hsfsts_cycle, flash_addr, len);
161  return wait_for_hwseq_xfer(ctx, flash_addr);
162 }
163 
165 {
167 
168  int ret = wait_for_hwseq_spi_cycle_complete(ctx);
169  if (ret != SUCCESS)
170  printk(BIOS_ERR, "SPI Transaction Timeout (Exceeded %d ms) due to prior"
171  " operation is pending\n", SPIBAR_HWSEQ_XFER_TIMEOUT_MS);
172 
173  return ret;
174 }
175 
176 /*
177  * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and
178  * that the operation does not cross page boundary.
179  */
180 static size_t get_xfer_len(const struct spi_flash *flash, uint32_t addr,
181  size_t len)
182 {
183  size_t xfer_len = MIN(len, SPIBAR_FDATA_FIFO_SIZE);
184  size_t bytes_left = ALIGN_UP(addr, flash->page_size) - addr;
185 
186  if (bytes_left)
187  xfer_len = MIN(xfer_len, bytes_left);
188 
189  return xfer_len;
190 }
191 
192 static int fast_spi_flash_erase(const struct spi_flash *flash,
193  uint32_t offset, size_t len)
194 {
195  int ret;
196  size_t erase_size;
197  uint32_t erase_cycle;
198 
200 
201  if (!IS_ALIGNED(offset, 4 * KiB) || !IS_ALIGNED(len, 4 * KiB)) {
202  printk(BIOS_ERR, "BUG! SPI erase region not sector aligned\n");
203  return E_ARGUMENT;
204  }
205 
206  while (len) {
207  if (IS_ALIGNED(offset, 64 * KiB) && (len >= 64 * KiB)) {
208  erase_size = 64 * KiB;
209  erase_cycle = SPIBAR_HSFSTS_CYCLE_64K_ERASE;
210  } else {
211  erase_size = 4 * KiB;
212  erase_cycle = SPIBAR_HSFSTS_CYCLE_4K_ERASE;
213  }
214  printk(BIOS_SPEW, "Erasing flash addr %x + %zu KiB\n",
215  offset, erase_size / KiB);
216 
217  ret = exec_sync_hwseq_xfer(ctx, erase_cycle, offset, 0);
218  if (ret != SUCCESS)
219  return ret;
220 
221  offset += erase_size;
222  len -= erase_size;
223  }
224 
225  return SUCCESS;
226 }
227 
228 static int fast_spi_flash_read(const struct spi_flash *flash,
229  uint32_t addr, size_t len, void *buf)
230 {
231  int ret;
232  size_t xfer_len;
233  uint8_t *data = buf;
234 
236 
237  while (len) {
238  xfer_len = get_xfer_len(flash, addr, len);
239 
241  addr, xfer_len);
242  if (ret != SUCCESS)
243  return ret;
244 
245  drain_xfer_fifo(ctx, data, xfer_len);
246 
247  addr += xfer_len;
248  data += xfer_len;
249  len -= xfer_len;
250  }
251 
252  return SUCCESS;
253 }
254 
255 static int fast_spi_flash_write(const struct spi_flash *flash,
256  uint32_t addr, size_t len, const void *buf)
257 {
258  int ret;
259  size_t xfer_len;
260  const uint8_t *data = buf;
261 
263 
264  while (len) {
265  xfer_len = get_xfer_len(flash, addr, len);
266  fill_xfer_fifo(ctx, data, xfer_len);
267 
269  addr, xfer_len);
270  if (ret != SUCCESS)
271  return ret;
272 
273  addr += xfer_len;
274  data += xfer_len;
275  len -= xfer_len;
276  }
277 
278  return SUCCESS;
279 }
280 
281 static int fast_spi_flash_status(const struct spi_flash *flash,
282  uint8_t *reg)
283 {
284  int ret;
286 
288  sizeof(*reg));
289  if (ret != SUCCESS)
290  return ret;
291 
292  drain_xfer_fifo(ctx, reg, sizeof(*reg));
293  return ret;
294 }
295 
296 const struct spi_flash_ops fast_spi_flash_ops = {
298  .write = fast_spi_flash_write,
299  .erase = fast_spi_flash_erase,
300  .status = fast_spi_flash_status,
301 };
302 
303 /*
304  * We can't use FDOC and FDOD to read FLCOMP, as previous platforms did.
305  * For details see:
306  * Ch 31, SPI: p. 194
307  * The size of the flash component is always taken from density field in the
308  * SFDP table. FLCOMP.C0DEN is no longer used by the Flash Controller.
309  */
310 static int fast_spi_flash_probe(const struct spi_slave *dev,
311  struct spi_flash *flash)
312 {
314  uint32_t flash_bits;
315 
316  /*
317  * bytes = (bits + 1) / 8;
318  * But we need to do the addition in a way which doesn't overflow for
319  * 4 Gbit devices (flash_bits == 0xffffffff).
320  */
321  flash_bits = fast_spi_flash_read_sfdp_param(ctx, 0x04);
322  flash->size = (flash_bits >> 3) + 1;
323 
324  memcpy(&flash->spi, dev, sizeof(*dev));
325 
326  /* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */
327  flash->sector_size = 4 * KiB;
328  flash->page_size = 256;
329  /*
330  * FIXME: Get erase+cmd, and status_cmd from SFDP.
331  *
332  * flash->erase_cmd = ???
333  * flash->status_cmd = ???
334  */
335 
336  flash->ops = &fast_spi_flash_ops;
337  return 0;
338 }
339 
340 static int fast_spi_flash_ctrlr_setup(const struct spi_slave *dev)
341 {
342  if (dev->cs != 0) {
343  printk(BIOS_ERR, "%s: Invalid CS for fast SPI bus=0x%x,cs=0x%x!\n",
344  __func__, dev->bus, dev->cs);
345  return -1;
346  }
347 
348  return 0;
349 }
350 
351 #define SPI_FPR_SHIFT 12
352 #define SPI_FPR_MASK 0x7fff
353 #define SPI_FPR_BASE_SHIFT 0
354 #define SPI_FPR_LIMIT_SHIFT 16
355 #define SPI_FPR_RPE (1 << 15) /* Read Protect */
356 #define SPI_FPR_WPE (1 << 31) /* Write Protect */
357 #define SPI_FPR(base, limit) \
358  (((((limit) >> SPI_FPR_SHIFT) & SPI_FPR_MASK) << SPI_FPR_LIMIT_SHIFT) |\
359  ((((base) >> SPI_FPR_SHIFT) & SPI_FPR_MASK) << SPI_FPR_BASE_SHIFT))
360 
361 /*
362  * Protect range of SPI flash defined by [start, start+size-1] using Flash
363  * Protected Range (FPR) register if available.
364  */
365 static int fast_spi_flash_protect(const struct spi_flash *flash,
366  const struct region *region,
367  const enum ctrlr_prot_type type)
368 {
369  u32 start = region_offset(region);
370  u32 end = start + region_sz(region) - 1;
371  u32 reg;
372  u32 protect_mask = 0;
373  int fpr;
374  uintptr_t fpr_base;
376 
377  fpr_base = ctx->mmio_base + SPIBAR_FPR_BASE;
378 
379  /* Find first empty FPR */
380  for (fpr = 0; fpr < SPIBAR_FPR_MAX; fpr++) {
381  reg = read32((void *)fpr_base);
382  if (reg == 0)
383  break;
384  fpr_base += sizeof(uint32_t);
385  }
386 
387  if (fpr >= SPIBAR_FPR_MAX) {
388  printk(BIOS_ERR, "No SPI FPR free!\n");
389  return -1;
390  }
391 
392  switch (type) {
393  case WRITE_PROTECT:
394  protect_mask |= SPI_FPR_WPE;
395  break;
396  case READ_PROTECT:
397  protect_mask |= SPI_FPR_RPE;
398  break;
399  case READ_WRITE_PROTECT:
400  protect_mask |= (SPI_FPR_RPE | SPI_FPR_WPE);
401  break;
402  default:
403  printk(BIOS_ERR, "Seeking invalid protection!\n");
404  return -1;
405  }
406 
407  /* Set protected range base and limit */
408  reg = SPI_FPR(start, end) | protect_mask;
409 
410  /* Set the FPR register and verify it is protected */
411  write32((void *)fpr_base, reg);
412  reg = read32((void *)fpr_base);
413  if (!(reg & protect_mask)) {
414  printk(BIOS_ERR, "Unable to set SPI FPR %d\n", fpr);
415  return -1;
416  }
417 
418  printk(BIOS_INFO, "%s: FPR %d is enabled for range 0x%08x-0x%08x\n",
419  __func__, fpr, start, end);
420  return 0;
421 }
422 
423 const struct spi_ctrlr fast_spi_flash_ctrlr = {
425  .max_xfer_size = SPI_CTRLR_DEFAULT_MAX_XFER_SIZE,
426  .flash_probe = fast_spi_flash_probe,
427  .flash_protect = fast_spi_flash_protect,
428 };
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define IS_ALIGNED(x, a)
Definition: helpers.h:19
#define MIN(a, b)
Definition: helpers.h:37
#define ALIGN_DOWN(x, a)
Definition: helpers.h:18
#define KiB
Definition: helpers.h:75
#define ALIGN_UP(x, a)
Definition: helpers.h:17
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void * fast_spi_get_bar(void)
Definition: fast_spi.c:24
#define SPIBAR_HSFSTS_CYCLE_4K_ERASE
Definition: fast_spi_def.h:59
#define SPIBAR_FPR_BASE
Definition: fast_spi_def.h:32
#define SPIBAR_FDATA(n)
Definition: fast_spi_def.h:31
#define SPIBAR_PTINX_HORD_JEDEC
Definition: fast_spi_def.h:146
#define SPIBAR_HSFSTS_W1C_BITS
Definition: fast_spi_def.h:78
#define SPIBAR_FDATA_FIFO_SIZE
Definition: fast_spi_def.h:91
#define SPIBAR_PTINX_IDX_MASK
Definition: fast_spi_def.h:147
#define SPIBAR_FADDR
Definition: fast_spi_def.h:29
#define SPIBAR_PTDATA
Definition: fast_spi_def.h:41
#define SPIBAR_HSFSTS_CYCLE_RD_STATUS
Definition: fast_spi_def.h:61
#define SPIBAR_FPR_MAX
Definition: fast_spi_def.h:105
#define SPIBAR_HSFSTS_FDONE
Definition: fast_spi_def.h:77
#define SPIBAR_HSFSTS_CYCLE_64K_ERASE
Definition: fast_spi_def.h:60
#define SPIBAR_HSFSTS_FCYCLE_MASK
Definition: fast_spi_def.h:53
#define SPIBAR_HSFSTS_CTL
Definition: fast_spi_def.h:28
#define SPIBAR_PTINX
Definition: fast_spi_def.h:40
#define SPIBAR_HSFSTS_FCERR
Definition: fast_spi_def.h:76
#define SPIBAR_HWSEQ_XFER_TIMEOUT_MS
Definition: fast_spi_def.h:161
#define SPIBAR_HSFSTS_SCIP
Definition: fast_spi_def.h:72
#define SPIBAR_HSFSTS_FDBC(n)
Definition: fast_spi_def.h:51
#define SPIBAR_HSFSTS_CYCLE_WRITE
Definition: fast_spi_def.h:58
#define SPIBAR_HSFSTS_CYCLE_READ
Definition: fast_spi_def.h:57
#define SPIBAR_HSFSTS_FGO
Definition: fast_spi_def.h:63
static int wait_for_hwseq_spi_cycle_complete(struct fast_spi_flash_ctx *ctx)
static int fast_spi_flash_status(const struct spi_flash *flash, uint8_t *reg)
static int fast_spi_flash_ctrlr_setup(const struct spi_slave *dev)
static int fast_spi_flash_write(const struct spi_flash *flash, uint32_t addr, size_t len, const void *buf)
#define SPI_FPR_WPE
#define BOILERPLATE_CREATE_CTX(ctx)
static void drain_xfer_fifo(struct fast_spi_flash_ctx *ctx, void *dest, size_t len)
static size_t get_xfer_len(const struct spi_flash *flash, uint32_t addr, size_t len)
const struct spi_ctrlr fast_spi_flash_ctrlr
static void fast_spi_flash_ctrlr_reg_write(struct fast_spi_flash_ctx *ctx, uint16_t reg, uint32_t val)
static uint32_t fast_spi_flash_read_sfdp_param(struct fast_spi_flash_ctx *ctx, uint16_t sfdp_reg)
static int fast_spi_flash_probe(const struct spi_slave *dev, struct spi_flash *flash)
int fast_spi_cycle_in_progress(void)
static int fast_spi_flash_erase(const struct spi_flash *flash, uint32_t offset, size_t len)
static void _fast_spi_flash_get_ctx(struct fast_spi_flash_ctx *ctx)
static void start_hwseq_xfer(struct fast_spi_flash_ctx *ctx, uint32_t hsfsts_cycle, uint32_t flash_addr, size_t len)
static int exec_sync_hwseq_xfer(struct fast_spi_flash_ctx *ctx, uint32_t hsfsts_cycle, uint32_t flash_addr, size_t len)
errors
@ E_TIMEOUT
@ E_ARGUMENT
@ SUCCESS
@ E_HW_ERROR
#define SPI_FPR(base, limit)
static int fast_spi_flash_read(const struct spi_flash *flash, uint32_t addr, size_t len, void *buf)
static int fast_spi_flash_protect(const struct spi_flash *flash, const struct region *region, const enum ctrlr_prot_type type)
static uint32_t fast_spi_flash_ctrlr_reg_read(struct fast_spi_flash_ctx *ctx, uint16_t reg)
const struct spi_flash_ops fast_spi_flash_ops
static void fill_xfer_fifo(struct fast_spi_flash_ctx *ctx, const void *data, size_t len)
#define SPI_FPR_RPE
static int wait_for_hwseq_xfer(struct fast_spi_flash_ctx *ctx, uint32_t flash_addr)
static size_t offset
Definition: flashconsole.c:16
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
unsigned int type
Definition: edid.c:57
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
static uint8_t * buf
Definition: uart.c:7
static size_t region_sz(const struct region *r)
Definition: region.h:110
static size_t region_offset(const struct region *r)
Definition: region.h:105
#define SPI_CTRLR_DEFAULT_MAX_XFER_SIZE
Definition: spi-generic.h:102
ctrlr_prot_type
Definition: spi-generic.h:106
@ WRITE_PROTECT
Definition: spi-generic.h:108
@ READ_WRITE_PROTECT
Definition: spi-generic.h:109
@ READ_PROTECT
Definition: spi-generic.h:107
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
Definition: region.h:76
int(* setup)(const struct spi_slave *slave)
Definition: spi-generic.h:151
int(* read)(const struct spi_flash *flash, u32 offset, size_t len, void *buf)
Definition: spi_flash.h:44
u32 sector_size
Definition: spi_flash.h:96
const struct spi_flash_ops * ops
Definition: spi_flash.h:102
u32 page_size
Definition: spi_flash.h:97
u32 size
Definition: spi_flash.h:95
struct spi_slave spi
Definition: spi_flash.h:84
unsigned int bus
Definition: spi-generic.h:41
unsigned int cs
Definition: spi-generic.h:42
u8 val
Definition: sys.c:300