flash/nor: improved API of flash_driver.info & fixed buffer overruns
[fw/openocd] / src / flash / nor / esirisc_flash.c
1 /***************************************************************************
2  *   Copyright (C) 2018 by Square, Inc.                                    *
3  *   Steven Stallion <stallion@squareup.com>                               *
4  *   James Zhao <hjz@squareup.com>                                         *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
18  ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <flash/common.h>
25 #include <flash/nor/imp.h>
26 #include <helper/command.h>
27 #include <helper/log.h>
28 #include <helper/time_support.h>
29 #include <helper/types.h>
30 #include <target/esirisc.h>
31 #include <target/target.h>
32
33 /* eSi-TSMC Flash Registers */
34 #define CONTROL                         0x00    /* Control Register */
35 #define TIMING0                         0x04    /* Timing Register 0 */
36 #define TIMING1                         0x08    /* Timing Register 1 */
37 #define TIMING2                         0x0c    /* Timing Register 2 */
38 #define UNLOCK1                         0x18    /* Unlock 1 */
39 #define UNLOCK2                         0x1c    /* Unlock 2 */
40 #define ADDRESS                         0x20    /* Erase/Program Address */
41 #define PB_DATA                         0x24    /* Program Buffer Data */
42 #define PB_INDEX                        0x28    /* Program Buffer Index */
43 #define STATUS                          0x2c    /* Status Register */
44 #define REDUN_0                         0x30    /* Redundant Address 0 */
45 #define REDUN_1                         0x34    /* Redundant Address 1 */
46
47 /* Control Fields */
48 #define CONTROL_SLM                     (1<<0)  /* Sleep Mode */
49 #define CONTROL_WP                      (1<<1)  /* Register Write Protect */
50 #define CONTROL_E                       (1<<3)  /* Erase */
51 #define CONTROL_EP                      (1<<4)  /* Erase Page */
52 #define CONTROL_P                       (1<<5)  /* Program Flash */
53 #define CONTROL_ERC                     (1<<6)  /* Erase Reference Cell */
54 #define CONTROL_R                       (1<<7)  /* Recall Trim Code */
55 #define CONTROL_AP                      (1<<8)  /* Auto-Program */
56
57 /* Timing Fields */
58 #define TIMING0_R(x)            (((x) <<  0) & 0x3f)            /* Read Wait States */
59 #define TIMING0_F(x)            (((x) << 16) & 0xffff0000)      /* Tnvh Clock Cycles */
60 #define TIMING1_E(x)            (((x) <<  0) & 0xffffff)        /* Tme/Terase/Tre Clock Cycles */
61 #define TIMING2_P(x)            (((x) <<  0) & 0xffff)          /* Tprog Clock Cycles */
62 #define TIMING2_H(x)            (((x) << 16) & 0xff0000)        /* Clock Cycles in 100ns */
63 #define TIMING2_T(x)            (((x) << 24) & 0xf000000)       /* Clock Cycles in 10ns */
64
65 /* Status Fields */
66 #define STATUS_BUSY                     (1<<0)  /* Busy (Erase/Program) */
67 #define STATUS_WER                      (1<<1)  /* Write Protect Error */
68 #define STATUS_DR                       (1<<2)  /* Disable Redundancy */
69 #define STATUS_DIS                      (1<<3)  /* Discharged */
70 #define STATUS_BO                       (1<<4)  /* Brown Out */
71
72 /* Redundant Address Fields */
73 #define REDUN_R                         (1<<0)                                          /* Used */
74 #define REDUN_P(x)                      (((x) << 12) & 0x7f000)         /* Redundant Page Address */
75
76 /*
77  * The eSi-TSMC Flash manual provides two sets of timings based on the
78  * underlying flash process. By default, 90nm is assumed.
79  */
80 #if 0 /* 55nm */
81 #define TNVH                            5000            /* 5us   */
82 #define TME                                     80000000        /* 80ms  */
83 #define TERASE                          160000000       /* 160ms */
84 #define TRE                                     100000000       /* 100ms */
85 #define TPROG                           8000            /* 8us   */
86 #else /* 90nm */
87 #define TNVH                            5000            /* 5us   */
88 #define TME                                     20000000        /* 20ms  */
89 #define TERASE                          40000000        /* 40ms  */
90 #define TRE                                     40000000        /* 40ms  */
91 #define TPROG                           40000           /* 40us  */
92 #endif
93
94 #define CONTROL_TIMEOUT         5000            /* 5s    */
95 #define FLASH_PAGE_SIZE         4096
96 #define PB_MAX                          32
97
98 #define NUM_NS_PER_S            1000000000ULL
99
100 struct esirisc_flash_bank {
101         bool probed;
102         uint32_t cfg;
103         uint32_t clock;
104         uint32_t wait_states;
105 };
106
107 static const struct command_registration esirisc_flash_command_handlers[];
108
109 FLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)
110 {
111         struct esirisc_flash_bank *esirisc_info;
112
113         if (CMD_ARGC < 9)
114                 return ERROR_COMMAND_SYNTAX_ERROR;
115
116         esirisc_info = calloc(1, sizeof(struct esirisc_flash_bank));
117
118         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], esirisc_info->cfg);
119         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], esirisc_info->clock);
120         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[8], esirisc_info->wait_states);
121
122         bank->driver_priv = esirisc_info;
123
124         /* register commands using existing esirisc context */
125         register_commands(CMD_CTX, "esirisc", esirisc_flash_command_handlers);
126
127         return ERROR_OK;
128 }
129
130 /*
131  * Register writes are ignored if the control.WP flag is set; the
132  * following sequence is required to modify this flag even when
133  * protection is disabled.
134  */
135 static int esirisc_flash_unlock(struct flash_bank *bank)
136 {
137         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
138         struct target *target = bank->target;
139
140         target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0x7123);
141         target_write_u32(target, esirisc_info->cfg + UNLOCK2, 0x812a);
142         target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0xbee1);
143
144         return ERROR_OK;
145 }
146
147 static int esirisc_flash_disable_protect(struct flash_bank *bank)
148 {
149         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
150         struct target *target = bank->target;
151         uint32_t control;
152
153         target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
154         if (!(control & CONTROL_WP))
155                 return ERROR_OK;
156
157         (void)esirisc_flash_unlock(bank);
158
159         control &= ~CONTROL_WP;
160
161         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
162
163         return ERROR_OK;
164 }
165
166 static int esirisc_flash_enable_protect(struct flash_bank *bank)
167 {
168         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
169         struct target *target = bank->target;
170         uint32_t control;
171
172         target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
173         if (control & CONTROL_WP)
174                 return ERROR_OK;
175
176         (void)esirisc_flash_unlock(bank);
177
178         control |= CONTROL_WP;
179
180         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
181
182         return ERROR_OK;
183 }
184
185 static int esirisc_flash_check_status(struct flash_bank *bank)
186 {
187         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
188         struct target *target = bank->target;
189         uint32_t status;
190
191         target_read_u32(target, esirisc_info->cfg + STATUS, &status);
192         if (status & STATUS_WER) {
193                 LOG_ERROR("%s: bad status: 0x%" PRIx32, bank->name, status);
194                 return ERROR_FLASH_OPERATION_FAILED;
195         }
196
197         return ERROR_OK;
198 }
199
200 static int esirisc_flash_clear_status(struct flash_bank *bank)
201 {
202         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
203         struct target *target = bank->target;
204
205         target_write_u32(target, esirisc_info->cfg + STATUS, STATUS_WER);
206
207         return ERROR_OK;
208 }
209
210 static int esirisc_flash_wait(struct flash_bank *bank, int ms)
211 {
212         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
213         struct target *target = bank->target;
214         uint32_t status;
215         int64_t t;
216
217         t = timeval_ms();
218         for (;;) {
219                 target_read_u32(target, esirisc_info->cfg + STATUS, &status);
220                 if (!(status & STATUS_BUSY))
221                         return ERROR_OK;
222
223                 if ((timeval_ms() - t) > ms)
224                         return ERROR_TARGET_TIMEOUT;
225
226                 keep_alive();
227         }
228 }
229
230 static int esirisc_flash_control(struct flash_bank *bank, uint32_t control)
231 {
232         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
233         struct target *target = bank->target;
234
235         esirisc_flash_clear_status(bank);
236
237         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
238
239         int retval = esirisc_flash_wait(bank, CONTROL_TIMEOUT);
240         if (retval != ERROR_OK) {
241                 LOG_ERROR("%s: control timed out: 0x%" PRIx32, bank->name, control);
242                 return retval;
243         }
244
245         return esirisc_flash_check_status(bank);
246 }
247
248 static int esirisc_flash_recall(struct flash_bank *bank)
249 {
250         return esirisc_flash_control(bank, CONTROL_R);
251 }
252
253 static int esirisc_flash_erase(struct flash_bank *bank, unsigned int first,
254                 unsigned int last)
255 {
256         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
257         struct target *target = bank->target;
258         int retval = ERROR_OK;
259
260         if (target->state != TARGET_HALTED)
261                 return ERROR_TARGET_NOT_HALTED;
262
263         (void)esirisc_flash_disable_protect(bank);
264
265         for (unsigned int page = first; page < last; ++page) {
266                 uint32_t address = page * FLASH_PAGE_SIZE;
267
268                 target_write_u32(target, esirisc_info->cfg + ADDRESS, address);
269
270                 retval = esirisc_flash_control(bank, CONTROL_EP);
271                 if (retval != ERROR_OK) {
272                         LOG_ERROR("%s: failed to erase address: 0x%" PRIx32, bank->name, address);
273                         break;
274                 }
275         }
276
277         (void)esirisc_flash_enable_protect(bank);
278
279         return retval;
280 }
281
282 static int esirisc_flash_mass_erase(struct flash_bank *bank)
283 {
284         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
285         struct target *target = bank->target;
286         int retval;
287
288         if (target->state != TARGET_HALTED)
289                 return ERROR_TARGET_NOT_HALTED;
290
291         (void)esirisc_flash_disable_protect(bank);
292
293         target_write_u32(target, esirisc_info->cfg + ADDRESS, 0);
294
295         retval = esirisc_flash_control(bank, CONTROL_E);
296         if (retval != ERROR_OK)
297                 LOG_ERROR("%s: failed to mass erase", bank->name);
298
299         (void)esirisc_flash_enable_protect(bank);
300
301         return retval;
302 }
303
304 /*
305  * Per TSMC, the reference cell should be erased once per sample. This
306  * is typically done during wafer sort, however we include support for
307  * those that may need to calibrate flash at a later time.
308  */
309 static int esirisc_flash_ref_erase(struct flash_bank *bank)
310 {
311         struct target *target = bank->target;
312         int retval;
313
314         if (target->state != TARGET_HALTED)
315                 return ERROR_TARGET_NOT_HALTED;
316
317         (void)esirisc_flash_disable_protect(bank);
318
319         retval = esirisc_flash_control(bank, CONTROL_ERC);
320         if (retval != ERROR_OK)
321                 LOG_ERROR("%s: failed to erase reference cell", bank->name);
322
323         (void)esirisc_flash_enable_protect(bank);
324
325         return retval;
326 }
327
328 static int esirisc_flash_fill_pb(struct flash_bank *bank,
329                 const uint8_t *buffer, uint32_t count)
330 {
331         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
332         struct target *target = bank->target;
333         struct esirisc_common *esirisc = target_to_esirisc(target);
334
335         /*
336          * The pb_index register is auto-incremented when pb_data is written
337          * and should be cleared before each operation.
338          */
339         target_write_u32(target, esirisc_info->cfg + PB_INDEX, 0);
340
341         /*
342          * The width of the pb_data register depends on the underlying
343          * target; writing one byte at a time incurs a significant
344          * performance penalty and should be avoided.
345          */
346         while (count > 0) {
347                 uint32_t max_bytes = DIV_ROUND_UP(esirisc->num_bits, 8);
348                 uint32_t num_bytes = MIN(count, max_bytes);
349
350                 target_write_buffer(target, esirisc_info->cfg + PB_DATA, num_bytes, buffer);
351
352                 buffer += num_bytes;
353                 count -= num_bytes;
354         }
355
356         return ERROR_OK;
357 }
358
359 static int esirisc_flash_write(struct flash_bank *bank,
360                 const uint8_t *buffer, uint32_t offset, uint32_t count)
361 {
362         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
363         struct target *target = bank->target;
364         int retval = ERROR_OK;
365
366         if (target->state != TARGET_HALTED)
367                 return ERROR_TARGET_NOT_HALTED;
368
369         (void)esirisc_flash_disable_protect(bank);
370
371         /*
372          * The address register is auto-incremented based on the contents of
373          * the pb_index register after each operation completes. It can be
374          * set once provided pb_index is cleared before each operation.
375          */
376         target_write_u32(target, esirisc_info->cfg + ADDRESS, offset);
377
378         /*
379          * Care must be taken when filling the program buffer; a maximum of
380          * 32 bytes may be written at a time and may not cross a 32-byte
381          * boundary based on the current offset.
382          */
383         while (count > 0) {
384                 uint32_t max_bytes = PB_MAX - (offset & 0x1f);
385                 uint32_t num_bytes = MIN(count, max_bytes);
386
387                 esirisc_flash_fill_pb(bank, buffer, num_bytes);
388
389                 retval = esirisc_flash_control(bank, CONTROL_P);
390                 if (retval != ERROR_OK) {
391                         LOG_ERROR("%s: failed to program address: 0x%" PRIx32, bank->name, offset);
392                         break;
393                 }
394
395                 buffer += num_bytes;
396                 offset += num_bytes;
397                 count -= num_bytes;
398         }
399
400         (void)esirisc_flash_enable_protect(bank);
401
402         return retval;
403 }
404
405 static uint32_t esirisc_flash_num_cycles(struct flash_bank *bank, uint64_t ns)
406 {
407         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
408
409         /* apply scaling factor to avoid truncation */
410         uint64_t hz = (uint64_t)esirisc_info->clock * 1000;
411         uint64_t num_cycles = ((hz / NUM_NS_PER_S) * ns) / 1000;
412
413         if (hz % NUM_NS_PER_S > 0)
414                 num_cycles++;
415
416         return num_cycles;
417 }
418
419 static int esirisc_flash_init(struct flash_bank *bank)
420 {
421         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
422         struct target *target = bank->target;
423         uint32_t value;
424         int retval;
425
426         (void)esirisc_flash_disable_protect(bank);
427
428         /* initialize timing registers */
429         value = TIMING0_F(esirisc_flash_num_cycles(bank, TNVH))
430                         | TIMING0_R(esirisc_info->wait_states);
431
432         LOG_DEBUG("TIMING0: 0x%" PRIx32, value);
433         target_write_u32(target, esirisc_info->cfg + TIMING0, value);
434
435         value = TIMING1_E(esirisc_flash_num_cycles(bank, TERASE));
436
437         LOG_DEBUG("TIMING1: 0x%" PRIx32, value);
438         target_write_u32(target, esirisc_info->cfg + TIMING1, value);
439
440         value = TIMING2_T(esirisc_flash_num_cycles(bank, 10))
441                         | TIMING2_H(esirisc_flash_num_cycles(bank, 100))
442                         | TIMING2_P(esirisc_flash_num_cycles(bank, TPROG));
443
444         LOG_DEBUG("TIMING2: 0x%" PRIx32, value);
445         target_write_u32(target, esirisc_info->cfg + TIMING2, value);
446
447         /* recall trim code */
448         retval = esirisc_flash_recall(bank);
449         if (retval != ERROR_OK)
450                 LOG_ERROR("%s: failed to recall trim code", bank->name);
451
452         (void)esirisc_flash_enable_protect(bank);
453
454         return retval;
455 }
456
457 static int esirisc_flash_probe(struct flash_bank *bank)
458 {
459         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
460         struct target *target = bank->target;
461         int retval;
462
463         if (target->state != TARGET_HALTED)
464                 return ERROR_TARGET_NOT_HALTED;
465
466         bank->num_sectors = bank->size / FLASH_PAGE_SIZE;
467         bank->sectors = alloc_block_array(0, FLASH_PAGE_SIZE, bank->num_sectors);
468
469         retval = esirisc_flash_init(bank);
470         if (retval != ERROR_OK) {
471                 LOG_ERROR("%s: failed to initialize bank", bank->name);
472                 return retval;
473         }
474
475         esirisc_info->probed = true;
476
477         return ERROR_OK;
478 }
479
480 static int esirisc_flash_auto_probe(struct flash_bank *bank)
481 {
482         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
483
484         if (esirisc_info->probed)
485                 return ERROR_OK;
486
487         return esirisc_flash_probe(bank);
488 }
489
490 static int esirisc_flash_info(struct flash_bank *bank, struct command_invocation *cmd)
491 {
492         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
493
494         command_print_sameline(cmd,
495                         "%4s cfg at 0x%" PRIx32 ", clock %" PRIu32 ", wait_states %" PRIu32,
496                         "",     /* align with first line */
497                         esirisc_info->cfg,
498                         esirisc_info->clock,
499                         esirisc_info->wait_states);
500
501         return ERROR_OK;
502 }
503
504 COMMAND_HANDLER(handle_esirisc_flash_mass_erase_command)
505 {
506         struct flash_bank *bank;
507         int retval;
508
509         if (CMD_ARGC < 1)
510                 return ERROR_COMMAND_SYNTAX_ERROR;
511
512         retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
513         if (retval != ERROR_OK)
514                 return retval;
515
516         retval = esirisc_flash_mass_erase(bank);
517
518         command_print(CMD, "mass erase %s",
519                         (retval == ERROR_OK) ? "successful" : "failed");
520
521         return retval;
522 }
523
524 COMMAND_HANDLER(handle_esirisc_flash_ref_erase_command)
525 {
526         struct flash_bank *bank;
527         int retval;
528
529         if (CMD_ARGC < 1)
530                 return ERROR_COMMAND_SYNTAX_ERROR;
531
532         retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
533         if (retval != ERROR_OK)
534                 return retval;
535
536         retval = esirisc_flash_ref_erase(bank);
537
538         command_print(CMD, "erase reference cell %s",
539                         (retval == ERROR_OK) ? "successful" : "failed");
540
541         return retval;
542 }
543
544 static const struct command_registration esirisc_flash_exec_command_handlers[] = {
545         {
546                 .name = "mass_erase",
547                 .handler = handle_esirisc_flash_mass_erase_command,
548                 .mode = COMMAND_EXEC,
549                 .help = "erase all pages in data memory",
550                 .usage = "bank_id",
551         },
552         {
553                 .name = "ref_erase",
554                 .handler = handle_esirisc_flash_ref_erase_command,
555                 .mode = COMMAND_EXEC,
556                 .help = "erase reference cell (uncommon)",
557                 .usage = "bank_id",
558         },
559         COMMAND_REGISTRATION_DONE
560 };
561
562 static const struct command_registration esirisc_flash_command_handlers[] = {
563         {
564                 .name = "flash",
565                 .mode = COMMAND_EXEC,
566                 .help = "eSi-TSMC Flash command group",
567                 .usage = "",
568                 .chain = esirisc_flash_exec_command_handlers,
569         },
570         COMMAND_REGISTRATION_DONE
571 };
572
573 const struct flash_driver esirisc_flash = {
574         .name = "esirisc",
575         .usage = "flash bank bank_id 'esirisc' base_address size_bytes 0 0 target "
576                         "cfg_address clock_hz wait_states",
577         .flash_bank_command = esirisc_flash_bank_command,
578         .erase = esirisc_flash_erase,
579         .write = esirisc_flash_write,
580         .read = default_flash_read,
581         .probe = esirisc_flash_probe,
582         .auto_probe = esirisc_flash_auto_probe,
583         .erase_check = default_flash_blank_check,
584         .info = esirisc_flash_info,
585         .free_driver_priv = default_flash_free_driver_priv,
586 };