target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / flash / nor / esirisc_flash.c
blob938d0f6afabac5847b219c94aa6a1402e3b2d20c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Square, Inc. *
5 * Steven Stallion <stallion@squareup.com> *
6 * James Zhao <hjz@squareup.com> *
7 ***************************************************************************/
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
13 #include <flash/common.h>
14 #include <flash/nor/imp.h>
15 #include <helper/command.h>
16 #include <helper/log.h>
17 #include <helper/time_support.h>
18 #include <helper/types.h>
19 #include <target/esirisc.h>
20 #include <target/target.h>
22 /* eSi-TSMC Flash Registers */
23 #define CONTROL 0x00 /* Control Register */
24 #define TIMING0 0x04 /* Timing Register 0 */
25 #define TIMING1 0x08 /* Timing Register 1 */
26 #define TIMING2 0x0c /* Timing Register 2 */
27 #define UNLOCK1 0x18 /* Unlock 1 */
28 #define UNLOCK2 0x1c /* Unlock 2 */
29 #define ADDRESS 0x20 /* Erase/Program Address */
30 #define PB_DATA 0x24 /* Program Buffer Data */
31 #define PB_INDEX 0x28 /* Program Buffer Index */
32 #define STATUS 0x2c /* Status Register */
33 #define REDUN_0 0x30 /* Redundant Address 0 */
34 #define REDUN_1 0x34 /* Redundant Address 1 */
36 /* Control Fields */
37 #define CONTROL_SLM (1<<0) /* Sleep Mode */
38 #define CONTROL_WP (1<<1) /* Register Write Protect */
39 #define CONTROL_E (1<<3) /* Erase */
40 #define CONTROL_EP (1<<4) /* Erase Page */
41 #define CONTROL_P (1<<5) /* Program Flash */
42 #define CONTROL_ERC (1<<6) /* Erase Reference Cell */
43 #define CONTROL_R (1<<7) /* Recall Trim Code */
44 #define CONTROL_AP (1<<8) /* Auto-Program */
46 /* Timing Fields */
47 #define TIMING0_R(x) (((x) << 0) & 0x3f) /* Read Wait States */
48 #define TIMING0_F(x) (((x) << 16) & 0xffff0000) /* Tnvh Clock Cycles */
49 #define TIMING1_E(x) (((x) << 0) & 0xffffff) /* Tme/Terase/Tre Clock Cycles */
50 #define TIMING2_P(x) (((x) << 0) & 0xffff) /* Tprog Clock Cycles */
51 #define TIMING2_H(x) (((x) << 16) & 0xff0000) /* Clock Cycles in 100ns */
52 #define TIMING2_T(x) (((x) << 24) & 0xf000000) /* Clock Cycles in 10ns */
54 /* Status Fields */
55 #define STATUS_BUSY (1<<0) /* Busy (Erase/Program) */
56 #define STATUS_WER (1<<1) /* Write Protect Error */
57 #define STATUS_DR (1<<2) /* Disable Redundancy */
58 #define STATUS_DIS (1<<3) /* Discharged */
59 #define STATUS_BO (1<<4) /* Brown Out */
61 /* Redundant Address Fields */
62 #define REDUN_R (1<<0) /* Used */
63 #define REDUN_P(x) (((x) << 12) & 0x7f000) /* Redundant Page Address */
66 * The eSi-TSMC Flash manual provides two sets of timings based on the
67 * underlying flash process. By default, 90nm is assumed.
69 #if 0 /* 55nm */
70 #define TNVH 5000 /* 5us */
71 #define TME 80000000 /* 80ms */
72 #define TERASE 160000000 /* 160ms */
73 #define TRE 100000000 /* 100ms */
74 #define TPROG 8000 /* 8us */
75 #else /* 90nm */
76 #define TNVH 5000 /* 5us */
77 #define TME 20000000 /* 20ms */
78 #define TERASE 40000000 /* 40ms */
79 #define TRE 40000000 /* 40ms */
80 #define TPROG 40000 /* 40us */
81 #endif
83 #define CONTROL_TIMEOUT 5000 /* 5s */
84 #define FLASH_PAGE_SIZE 4096
85 #define PB_MAX 32
87 #define NUM_NS_PER_S 1000000000ULL
89 struct esirisc_flash_bank {
90 bool probed;
91 uint32_t cfg;
92 uint32_t clock;
93 uint32_t wait_states;
96 static const struct command_registration esirisc_flash_command_handlers[];
98 FLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)
100 struct esirisc_flash_bank *esirisc_info;
102 if (CMD_ARGC < 9)
103 return ERROR_COMMAND_SYNTAX_ERROR;
105 esirisc_info = calloc(1, sizeof(struct esirisc_flash_bank));
107 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], esirisc_info->cfg);
108 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], esirisc_info->clock);
109 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[8], esirisc_info->wait_states);
111 bank->driver_priv = esirisc_info;
113 /* register commands using existing esirisc context */
114 register_commands(CMD_CTX, "esirisc", esirisc_flash_command_handlers);
116 return ERROR_OK;
120 * Register writes are ignored if the control.WP flag is set; the
121 * following sequence is required to modify this flag even when
122 * protection is disabled.
124 static int esirisc_flash_unlock(struct flash_bank *bank)
126 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
127 struct target *target = bank->target;
129 target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0x7123);
130 target_write_u32(target, esirisc_info->cfg + UNLOCK2, 0x812a);
131 target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0xbee1);
133 return ERROR_OK;
136 static int esirisc_flash_disable_protect(struct flash_bank *bank)
138 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
139 struct target *target = bank->target;
140 uint32_t control;
142 target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
143 if (!(control & CONTROL_WP))
144 return ERROR_OK;
146 (void)esirisc_flash_unlock(bank);
148 control &= ~CONTROL_WP;
150 target_write_u32(target, esirisc_info->cfg + CONTROL, control);
152 return ERROR_OK;
155 static int esirisc_flash_enable_protect(struct flash_bank *bank)
157 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
158 struct target *target = bank->target;
159 uint32_t control;
161 target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
162 if (control & CONTROL_WP)
163 return ERROR_OK;
165 (void)esirisc_flash_unlock(bank);
167 control |= CONTROL_WP;
169 target_write_u32(target, esirisc_info->cfg + CONTROL, control);
171 return ERROR_OK;
174 static int esirisc_flash_check_status(struct flash_bank *bank)
176 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
177 struct target *target = bank->target;
178 uint32_t status;
180 target_read_u32(target, esirisc_info->cfg + STATUS, &status);
181 if (status & STATUS_WER) {
182 LOG_ERROR("%s: bad status: 0x%" PRIx32, bank->name, status);
183 return ERROR_FLASH_OPERATION_FAILED;
186 return ERROR_OK;
189 static int esirisc_flash_clear_status(struct flash_bank *bank)
191 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
192 struct target *target = bank->target;
194 target_write_u32(target, esirisc_info->cfg + STATUS, STATUS_WER);
196 return ERROR_OK;
199 static int esirisc_flash_wait(struct flash_bank *bank, int ms)
201 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
202 struct target *target = bank->target;
203 uint32_t status;
204 int64_t t;
206 t = timeval_ms();
207 for (;;) {
208 target_read_u32(target, esirisc_info->cfg + STATUS, &status);
209 if (!(status & STATUS_BUSY))
210 return ERROR_OK;
212 if ((timeval_ms() - t) > ms)
213 return ERROR_TARGET_TIMEOUT;
215 keep_alive();
219 static int esirisc_flash_control(struct flash_bank *bank, uint32_t control)
221 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
222 struct target *target = bank->target;
224 esirisc_flash_clear_status(bank);
226 target_write_u32(target, esirisc_info->cfg + CONTROL, control);
228 int retval = esirisc_flash_wait(bank, CONTROL_TIMEOUT);
229 if (retval != ERROR_OK) {
230 LOG_ERROR("%s: control timed out: 0x%" PRIx32, bank->name, control);
231 return retval;
234 return esirisc_flash_check_status(bank);
237 static int esirisc_flash_recall(struct flash_bank *bank)
239 return esirisc_flash_control(bank, CONTROL_R);
242 static int esirisc_flash_erase(struct flash_bank *bank, unsigned int first,
243 unsigned int last)
245 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
246 struct target *target = bank->target;
247 int retval = ERROR_OK;
249 if (target->state != TARGET_HALTED)
250 return ERROR_TARGET_NOT_HALTED;
252 (void)esirisc_flash_disable_protect(bank);
254 for (unsigned int page = first; page < last; ++page) {
255 uint32_t address = page * FLASH_PAGE_SIZE;
257 target_write_u32(target, esirisc_info->cfg + ADDRESS, address);
259 retval = esirisc_flash_control(bank, CONTROL_EP);
260 if (retval != ERROR_OK) {
261 LOG_ERROR("%s: failed to erase address: 0x%" PRIx32, bank->name, address);
262 break;
266 (void)esirisc_flash_enable_protect(bank);
268 return retval;
271 static int esirisc_flash_mass_erase(struct flash_bank *bank)
273 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
274 struct target *target = bank->target;
275 int retval;
277 if (target->state != TARGET_HALTED)
278 return ERROR_TARGET_NOT_HALTED;
280 (void)esirisc_flash_disable_protect(bank);
282 target_write_u32(target, esirisc_info->cfg + ADDRESS, 0);
284 retval = esirisc_flash_control(bank, CONTROL_E);
285 if (retval != ERROR_OK)
286 LOG_ERROR("%s: failed to mass erase", bank->name);
288 (void)esirisc_flash_enable_protect(bank);
290 return retval;
294 * Per TSMC, the reference cell should be erased once per sample. This
295 * is typically done during wafer sort, however we include support for
296 * those that may need to calibrate flash at a later time.
298 static int esirisc_flash_ref_erase(struct flash_bank *bank)
300 struct target *target = bank->target;
301 int retval;
303 if (target->state != TARGET_HALTED)
304 return ERROR_TARGET_NOT_HALTED;
306 (void)esirisc_flash_disable_protect(bank);
308 retval = esirisc_flash_control(bank, CONTROL_ERC);
309 if (retval != ERROR_OK)
310 LOG_ERROR("%s: failed to erase reference cell", bank->name);
312 (void)esirisc_flash_enable_protect(bank);
314 return retval;
317 static int esirisc_flash_fill_pb(struct flash_bank *bank,
318 const uint8_t *buffer, uint32_t count)
320 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
321 struct target *target = bank->target;
322 struct esirisc_common *esirisc = target_to_esirisc(target);
325 * The pb_index register is auto-incremented when pb_data is written
326 * and should be cleared before each operation.
328 target_write_u32(target, esirisc_info->cfg + PB_INDEX, 0);
331 * The width of the pb_data register depends on the underlying
332 * target; writing one byte at a time incurs a significant
333 * performance penalty and should be avoided.
335 while (count > 0) {
336 uint32_t max_bytes = DIV_ROUND_UP(esirisc->num_bits, 8);
337 uint32_t num_bytes = MIN(count, max_bytes);
339 target_write_buffer(target, esirisc_info->cfg + PB_DATA, num_bytes, buffer);
341 buffer += num_bytes;
342 count -= num_bytes;
345 return ERROR_OK;
348 static int esirisc_flash_write(struct flash_bank *bank,
349 const uint8_t *buffer, uint32_t offset, uint32_t count)
351 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
352 struct target *target = bank->target;
353 int retval = ERROR_OK;
355 if (target->state != TARGET_HALTED)
356 return ERROR_TARGET_NOT_HALTED;
358 (void)esirisc_flash_disable_protect(bank);
361 * The address register is auto-incremented based on the contents of
362 * the pb_index register after each operation completes. It can be
363 * set once provided pb_index is cleared before each operation.
365 target_write_u32(target, esirisc_info->cfg + ADDRESS, offset);
368 * Care must be taken when filling the program buffer; a maximum of
369 * 32 bytes may be written at a time and may not cross a 32-byte
370 * boundary based on the current offset.
372 while (count > 0) {
373 uint32_t max_bytes = PB_MAX - (offset & 0x1f);
374 uint32_t num_bytes = MIN(count, max_bytes);
376 esirisc_flash_fill_pb(bank, buffer, num_bytes);
378 retval = esirisc_flash_control(bank, CONTROL_P);
379 if (retval != ERROR_OK) {
380 LOG_ERROR("%s: failed to program address: 0x%" PRIx32, bank->name, offset);
381 break;
384 buffer += num_bytes;
385 offset += num_bytes;
386 count -= num_bytes;
389 (void)esirisc_flash_enable_protect(bank);
391 return retval;
394 static uint32_t esirisc_flash_num_cycles(struct flash_bank *bank, uint64_t ns)
396 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
398 /* apply scaling factor to avoid truncation */
399 uint64_t hz = (uint64_t)esirisc_info->clock * 1000;
400 uint64_t num_cycles = ((hz / NUM_NS_PER_S) * ns) / 1000;
402 if (hz % NUM_NS_PER_S > 0)
403 num_cycles++;
405 return num_cycles;
408 static int esirisc_flash_init(struct flash_bank *bank)
410 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
411 struct target *target = bank->target;
412 uint32_t value;
413 int retval;
415 (void)esirisc_flash_disable_protect(bank);
417 /* initialize timing registers */
418 value = TIMING0_F(esirisc_flash_num_cycles(bank, TNVH))
419 | TIMING0_R(esirisc_info->wait_states);
421 LOG_DEBUG("TIMING0: 0x%" PRIx32, value);
422 target_write_u32(target, esirisc_info->cfg + TIMING0, value);
424 value = TIMING1_E(esirisc_flash_num_cycles(bank, TERASE));
426 LOG_DEBUG("TIMING1: 0x%" PRIx32, value);
427 target_write_u32(target, esirisc_info->cfg + TIMING1, value);
429 value = TIMING2_T(esirisc_flash_num_cycles(bank, 10))
430 | TIMING2_H(esirisc_flash_num_cycles(bank, 100))
431 | TIMING2_P(esirisc_flash_num_cycles(bank, TPROG));
433 LOG_DEBUG("TIMING2: 0x%" PRIx32, value);
434 target_write_u32(target, esirisc_info->cfg + TIMING2, value);
436 /* recall trim code */
437 retval = esirisc_flash_recall(bank);
438 if (retval != ERROR_OK)
439 LOG_ERROR("%s: failed to recall trim code", bank->name);
441 (void)esirisc_flash_enable_protect(bank);
443 return retval;
446 static int esirisc_flash_probe(struct flash_bank *bank)
448 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
449 struct target *target = bank->target;
450 int retval;
452 if (target->state != TARGET_HALTED)
453 return ERROR_TARGET_NOT_HALTED;
455 bank->num_sectors = bank->size / FLASH_PAGE_SIZE;
456 bank->sectors = alloc_block_array(0, FLASH_PAGE_SIZE, bank->num_sectors);
458 retval = esirisc_flash_init(bank);
459 if (retval != ERROR_OK) {
460 LOG_ERROR("%s: failed to initialize bank", bank->name);
461 return retval;
464 esirisc_info->probed = true;
466 return ERROR_OK;
469 static int esirisc_flash_auto_probe(struct flash_bank *bank)
471 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
473 if (esirisc_info->probed)
474 return ERROR_OK;
476 return esirisc_flash_probe(bank);
479 static int esirisc_flash_info(struct flash_bank *bank, struct command_invocation *cmd)
481 struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
483 command_print_sameline(cmd,
484 "%4s cfg at 0x%" PRIx32 ", clock %" PRIu32 ", wait_states %" PRIu32,
485 "", /* align with first line */
486 esirisc_info->cfg,
487 esirisc_info->clock,
488 esirisc_info->wait_states);
490 return ERROR_OK;
493 COMMAND_HANDLER(handle_esirisc_flash_mass_erase_command)
495 struct flash_bank *bank;
496 int retval;
498 if (CMD_ARGC < 1)
499 return ERROR_COMMAND_SYNTAX_ERROR;
501 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
502 if (retval != ERROR_OK)
503 return retval;
505 retval = esirisc_flash_mass_erase(bank);
507 command_print(CMD, "mass erase %s",
508 (retval == ERROR_OK) ? "successful" : "failed");
510 return retval;
513 COMMAND_HANDLER(handle_esirisc_flash_ref_erase_command)
515 struct flash_bank *bank;
516 int retval;
518 if (CMD_ARGC < 1)
519 return ERROR_COMMAND_SYNTAX_ERROR;
521 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
522 if (retval != ERROR_OK)
523 return retval;
525 retval = esirisc_flash_ref_erase(bank);
527 command_print(CMD, "erase reference cell %s",
528 (retval == ERROR_OK) ? "successful" : "failed");
530 return retval;
533 static const struct command_registration esirisc_flash_exec_command_handlers[] = {
535 .name = "mass_erase",
536 .handler = handle_esirisc_flash_mass_erase_command,
537 .mode = COMMAND_EXEC,
538 .help = "erase all pages in data memory",
539 .usage = "bank_id",
542 .name = "ref_erase",
543 .handler = handle_esirisc_flash_ref_erase_command,
544 .mode = COMMAND_EXEC,
545 .help = "erase reference cell (uncommon)",
546 .usage = "bank_id",
548 COMMAND_REGISTRATION_DONE
551 static const struct command_registration esirisc_flash_command_handlers[] = {
553 .name = "flash",
554 .mode = COMMAND_EXEC,
555 .help = "eSi-TSMC Flash command group",
556 .usage = "",
557 .chain = esirisc_flash_exec_command_handlers,
559 COMMAND_REGISTRATION_DONE
562 const struct flash_driver esirisc_flash = {
563 .name = "esirisc",
564 .usage = "flash bank bank_id 'esirisc' base_address size_bytes 0 0 target "
565 "cfg_address clock_hz wait_states",
566 .flash_bank_command = esirisc_flash_bank_command,
567 .erase = esirisc_flash_erase,
568 .write = esirisc_flash_write,
569 .read = default_flash_read,
570 .probe = esirisc_flash_probe,
571 .auto_probe = esirisc_flash_auto_probe,
572 .erase_check = default_flash_blank_check,
573 .info = esirisc_flash_info,
574 .free_driver_priv = default_flash_free_driver_priv,