dc49fda6153ddf31e2b97c820cc58d5c42e48c7d
[openocd.git] / src / flash / nor / jtagspi.c
1 /***************************************************************************
2 * Copyright (C) 2015 Robert Jordens <jordens@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "imp.h"
23 #include <jtag/jtag.h>
24 #include <flash/nor/spi.h>
25 #include <helper/time_support.h>
26
27 #define JTAGSPI_MAX_TIMEOUT 3000
28
29
30 struct jtagspi_flash_bank {
31 struct jtag_tap *tap;
32 const struct flash_device *dev;
33 bool probed;
34 uint32_t ir;
35 };
36
37 FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command)
38 {
39 struct jtagspi_flash_bank *info;
40
41 if (CMD_ARGC < 7)
42 return ERROR_COMMAND_SYNTAX_ERROR;
43
44 info = malloc(sizeof(struct jtagspi_flash_bank));
45 if (!info) {
46 LOG_ERROR("no memory for flash bank info");
47 return ERROR_FAIL;
48 }
49 bank->driver_priv = info;
50
51 info->tap = NULL;
52 info->probed = false;
53 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], info->ir);
54
55 return ERROR_OK;
56 }
57
58 static void jtagspi_set_ir(struct flash_bank *bank)
59 {
60 struct jtagspi_flash_bank *info = bank->driver_priv;
61 struct scan_field field;
62 uint8_t buf[4] = { 0 };
63
64 LOG_DEBUG("loading jtagspi ir");
65 buf_set_u32(buf, 0, info->tap->ir_length, info->ir);
66 field.num_bits = info->tap->ir_length;
67 field.out_value = buf;
68 field.in_value = NULL;
69 jtag_add_ir_scan(info->tap, &field, TAP_IDLE);
70 }
71
72 static void flip_u8(uint8_t *in, uint8_t *out, int len)
73 {
74 for (int i = 0; i < len; i++)
75 out[i] = flip_u32(in[i], 8);
76 }
77
78 static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,
79 uint32_t *addr, uint8_t *data, int len)
80 {
81 struct jtagspi_flash_bank *info = bank->driver_priv;
82 struct scan_field fields[6];
83 uint8_t marker = 1;
84 uint8_t xfer_bits_buf[4];
85 uint8_t addr_buf[3];
86 uint8_t *data_buf;
87 uint32_t xfer_bits;
88 int is_read, lenb, n;
89
90 /* LOG_DEBUG("cmd=0x%02x len=%i", cmd, len); */
91
92 is_read = (len < 0);
93 if (is_read)
94 len = -len;
95
96 n = 0;
97
98 fields[n].num_bits = 1;
99 fields[n].out_value = &marker;
100 fields[n].in_value = NULL;
101 n++;
102
103 xfer_bits = 8 + len - 1;
104 /* cmd + read/write - 1 due to the counter implementation */
105 if (addr)
106 xfer_bits += 24;
107 h_u32_to_be(xfer_bits_buf, xfer_bits);
108 flip_u8(xfer_bits_buf, xfer_bits_buf, 4);
109 fields[n].num_bits = 32;
110 fields[n].out_value = xfer_bits_buf;
111 fields[n].in_value = NULL;
112 n++;
113
114 cmd = flip_u32(cmd, 8);
115 fields[n].num_bits = 8;
116 fields[n].out_value = &cmd;
117 fields[n].in_value = NULL;
118 n++;
119
120 if (addr) {
121 h_u24_to_be(addr_buf, *addr);
122 flip_u8(addr_buf, addr_buf, 3);
123 fields[n].num_bits = 24;
124 fields[n].out_value = addr_buf;
125 fields[n].in_value = NULL;
126 n++;
127 }
128
129 lenb = DIV_ROUND_UP(len, 8);
130 data_buf = malloc(lenb);
131 if (lenb > 0) {
132 if (!data_buf) {
133 LOG_ERROR("no memory for spi buffer");
134 return ERROR_FAIL;
135 }
136 if (is_read) {
137 fields[n].num_bits = jtag_tap_count_enabled();
138 fields[n].out_value = NULL;
139 fields[n].in_value = NULL;
140 n++;
141
142 fields[n].out_value = NULL;
143 fields[n].in_value = data_buf;
144 } else {
145 flip_u8(data, data_buf, lenb);
146 fields[n].out_value = data_buf;
147 fields[n].in_value = NULL;
148 }
149 fields[n].num_bits = len;
150 n++;
151 }
152
153 jtagspi_set_ir(bank);
154 /* passing from an IR scan to SHIFT-DR clears BYPASS registers */
155 jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE);
156 int retval = jtag_execute_queue();
157
158 if (is_read)
159 flip_u8(data_buf, data, lenb);
160 free(data_buf);
161 return retval;
162 }
163
164 static int jtagspi_probe(struct flash_bank *bank)
165 {
166 struct jtagspi_flash_bank *info = bank->driver_priv;
167 struct flash_sector *sectors;
168 uint8_t in_buf[3];
169 uint32_t id, sectorsize;
170
171 if (info->probed)
172 free(bank->sectors);
173 info->probed = false;
174
175 if (!bank->target->tap) {
176 LOG_ERROR("Target has no JTAG tap");
177 return ERROR_FAIL;
178 }
179 info->tap = bank->target->tap;
180
181 jtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, in_buf, -24);
182 /* the table in spi.c has the manufacturer byte (first) as the lsb */
183 id = le_to_h_u24(in_buf);
184
185 info->dev = NULL;
186 for (const struct flash_device *p = flash_devices; p->name ; p++)
187 if (p->device_id == id) {
188 info->dev = p;
189 break;
190 }
191
192 if (!(info->dev)) {
193 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
194 return ERROR_FAIL;
195 }
196
197 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
198 info->dev->name, info->dev->device_id);
199
200 /* Set correct size value */
201 bank->size = info->dev->size_in_bytes;
202 if (bank->size <= (1UL << 16))
203 LOG_WARNING("device needs 2-byte addresses - not implemented");
204 if (bank->size > (1UL << 24))
205 LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
206
207 /* if no sectors, treat whole bank as single sector */
208 sectorsize = info->dev->sectorsize ?
209 info->dev->sectorsize : info->dev->size_in_bytes;
210
211 /* create and fill sectors array */
212 bank->num_sectors = info->dev->size_in_bytes / sectorsize;
213 sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
214 if (!sectors) {
215 LOG_ERROR("not enough memory");
216 return ERROR_FAIL;
217 }
218
219 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
220 sectors[sector].offset = sector * sectorsize;
221 sectors[sector].size = sectorsize;
222 sectors[sector].is_erased = -1;
223 sectors[sector].is_protected = 0;
224 }
225
226 bank->sectors = sectors;
227 info->probed = true;
228 return ERROR_OK;
229 }
230
231 static int jtagspi_read_status(struct flash_bank *bank, uint32_t *status)
232 {
233 uint8_t buf;
234 int err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, &buf, -8);
235 if (err == ERROR_OK) {
236 *status = buf;
237 /* LOG_DEBUG("status=0x%08" PRIx32, *status); */
238 }
239
240 return err;
241 }
242
243 static int jtagspi_wait(struct flash_bank *bank, int timeout_ms)
244 {
245 uint32_t status;
246 int64_t t0 = timeval_ms();
247 int64_t dt;
248
249 do {
250 dt = timeval_ms() - t0;
251
252 int retval = jtagspi_read_status(bank, &status);
253 if (retval != ERROR_OK)
254 return retval;
255
256 if ((status & SPIFLASH_BSY_BIT) == 0) {
257 LOG_DEBUG("waited %" PRId64 " ms", dt);
258 return ERROR_OK;
259 }
260 alive_sleep(1);
261 } while (dt <= timeout_ms);
262
263 LOG_ERROR("timeout, device still busy");
264 return ERROR_FAIL;
265 }
266
267 static int jtagspi_write_enable(struct flash_bank *bank)
268 {
269 uint32_t status;
270
271 jtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, NULL, 0);
272
273 int retval = jtagspi_read_status(bank, &status);
274 if (retval != ERROR_OK)
275 return retval;
276
277 if ((status & SPIFLASH_WE_BIT) == 0) {
278 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status);
279 return ERROR_FAIL;
280 }
281 return ERROR_OK;
282 }
283
284 static int jtagspi_bulk_erase(struct flash_bank *bank)
285 {
286 struct jtagspi_flash_bank *info = bank->driver_priv;
287 int retval;
288 int64_t t0 = timeval_ms();
289
290 if (info->dev->chip_erase_cmd == 0x00)
291 return ERROR_FLASH_OPER_UNSUPPORTED;
292
293 retval = jtagspi_write_enable(bank);
294 if (retval != ERROR_OK)
295 return retval;
296 jtagspi_cmd(bank, info->dev->chip_erase_cmd, NULL, NULL, 0);
297 retval = jtagspi_wait(bank, bank->num_sectors*JTAGSPI_MAX_TIMEOUT);
298 LOG_INFO("took %" PRId64 " ms", timeval_ms() - t0);
299 return retval;
300 }
301
302 static int jtagspi_sector_erase(struct flash_bank *bank, unsigned int sector)
303 {
304 struct jtagspi_flash_bank *info = bank->driver_priv;
305 int retval;
306 int64_t t0 = timeval_ms();
307
308 retval = jtagspi_write_enable(bank);
309 if (retval != ERROR_OK)
310 return retval;
311 jtagspi_cmd(bank, info->dev->erase_cmd, &bank->sectors[sector].offset, NULL, 0);
312 retval = jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT);
313 LOG_INFO("sector %u took %" PRId64 " ms", sector, timeval_ms() - t0);
314 return retval;
315 }
316
317 static int jtagspi_erase(struct flash_bank *bank, unsigned int first,
318 unsigned int last)
319 {
320 struct jtagspi_flash_bank *info = bank->driver_priv;
321 int retval = ERROR_OK;
322
323 LOG_DEBUG("erase from sector %u to sector %u", first, last);
324
325 if ((last < first) || (last >= bank->num_sectors)) {
326 LOG_ERROR("Flash sector invalid");
327 return ERROR_FLASH_SECTOR_INVALID;
328 }
329
330 if (!(info->probed)) {
331 LOG_ERROR("Flash bank not probed");
332 return ERROR_FLASH_BANK_NOT_PROBED;
333 }
334
335 for (unsigned int sector = first; sector <= last; sector++) {
336 if (bank->sectors[sector].is_protected) {
337 LOG_ERROR("Flash sector %u protected", sector);
338 return ERROR_FAIL;
339 }
340 }
341
342 if (first == 0 && last == (bank->num_sectors - 1)
343 && info->dev->chip_erase_cmd != info->dev->erase_cmd) {
344 LOG_DEBUG("Trying bulk erase.");
345 retval = jtagspi_bulk_erase(bank);
346 if (retval == ERROR_OK)
347 return retval;
348 else
349 LOG_WARNING("Bulk flash erase failed. Falling back to sector erase.");
350 }
351
352 if (info->dev->erase_cmd == 0x00)
353 return ERROR_FLASH_OPER_UNSUPPORTED;
354
355 for (unsigned int sector = first; sector <= last; sector++) {
356 retval = jtagspi_sector_erase(bank, sector);
357 if (retval != ERROR_OK) {
358 LOG_ERROR("Sector erase failed.");
359 break;
360 }
361 }
362
363 return retval;
364 }
365
366 static int jtagspi_protect(struct flash_bank *bank, int set, unsigned int first,
367 unsigned int last)
368 {
369 for (unsigned int sector = first; sector <= last; sector++)
370 bank->sectors[sector].is_protected = set;
371 return ERROR_OK;
372 }
373
374 static int jtagspi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
375 {
376 struct jtagspi_flash_bank *info = bank->driver_priv;
377
378 if (!(info->probed)) {
379 LOG_ERROR("Flash bank not yet probed.");
380 return ERROR_FLASH_BANK_NOT_PROBED;
381 }
382
383 jtagspi_cmd(bank, SPIFLASH_READ, &offset, buffer, -count*8);
384 return ERROR_OK;
385 }
386
387 static int jtagspi_page_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
388 {
389 int retval;
390
391 retval = jtagspi_write_enable(bank);
392 if (retval != ERROR_OK)
393 return retval;
394 jtagspi_cmd(bank, SPIFLASH_PAGE_PROGRAM, &offset, (uint8_t *) buffer, count*8);
395 return jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT);
396 }
397
398 static int jtagspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
399 {
400 struct jtagspi_flash_bank *info = bank->driver_priv;
401 int retval;
402 uint32_t n, pagesize;
403
404 if (!(info->probed)) {
405 LOG_ERROR("Flash bank not yet probed.");
406 return ERROR_FLASH_BANK_NOT_PROBED;
407 }
408
409 /* if no write pagesize, use reasonable default */
410 pagesize = info->dev->pagesize ? info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
411
412 for (n = 0; n < count; n += pagesize) {
413 retval = jtagspi_page_write(bank, buffer + n, offset + n,
414 MIN(count - n, pagesize));
415 if (retval != ERROR_OK) {
416 LOG_ERROR("page write error");
417 return retval;
418 }
419 LOG_DEBUG("wrote page at 0x%08" PRIx32, offset + n);
420 }
421 return ERROR_OK;
422 }
423
424 static int jtagspi_info(struct flash_bank *bank, struct command_invocation *cmd)
425 {
426 struct jtagspi_flash_bank *info = bank->driver_priv;
427
428 if (!(info->probed)) {
429 command_print_sameline(cmd, "\nJTAGSPI flash bank not probed yet\n");
430 return ERROR_OK;
431 }
432
433 command_print_sameline(cmd, "\nSPIFI flash information:\n"
434 " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
435 info->dev->name, info->dev->device_id);
436
437 return ERROR_OK;
438 }
439
440 const struct flash_driver jtagspi_flash = {
441 .name = "jtagspi",
442 .flash_bank_command = jtagspi_flash_bank_command,
443 .erase = jtagspi_erase,
444 .protect = jtagspi_protect,
445 .write = jtagspi_write,
446 .read = jtagspi_read,
447 .probe = jtagspi_probe,
448 .auto_probe = jtagspi_probe,
449 .erase_check = default_flash_blank_check,
450 .info = jtagspi_info,
451 .free_driver_priv = default_flash_free_driver_priv,
452 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)