1 /***************************************************************************
2 * Copyright (C) 2015 Robert Jordens <jordens@gmail.com> *
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. *
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. *
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 ***************************************************************************/
23 #include <jtag/jtag.h>
24 #include <flash/nor/spi.h>
25 #include <helper/time_support.h>
27 #define JTAGSPI_MAX_TIMEOUT 3000
30 struct jtagspi_flash_bank
{
32 const struct flash_device
*dev
;
37 FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command
)
39 struct jtagspi_flash_bank
*info
;
42 return ERROR_COMMAND_SYNTAX_ERROR
;
44 info
= malloc(sizeof(struct jtagspi_flash_bank
));
46 LOG_ERROR("no memory for flash bank info");
49 bank
->driver_priv
= info
;
53 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], info
->ir
);
58 static void jtagspi_set_ir(struct flash_bank
*bank
)
60 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
61 struct scan_field field
;
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
);
72 static void flip_u8(uint8_t *in
, uint8_t *out
, int len
)
74 for (int i
= 0; i
< len
; i
++)
75 out
[i
] = flip_u32(in
[i
], 8);
78 static int jtagspi_cmd(struct flash_bank
*bank
, uint8_t cmd
,
79 uint32_t *addr
, uint8_t *data
, int len
)
81 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
82 struct scan_field fields
[6];
84 uint8_t xfer_bits_buf
[4];
90 /* LOG_DEBUG("cmd=0x%02x len=%i", cmd, len); */
98 fields
[n
].num_bits
= 1;
99 fields
[n
].out_value
= &marker
;
100 fields
[n
].in_value
= NULL
;
103 xfer_bits
= 8 + len
- 1;
104 /* cmd + read/write - 1 due to the counter implementation */
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
;
114 cmd
= flip_u32(cmd
, 8);
115 fields
[n
].num_bits
= 8;
116 fields
[n
].out_value
= &cmd
;
117 fields
[n
].in_value
= NULL
;
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
;
129 lenb
= DIV_ROUND_UP(len
, 8);
130 data_buf
= malloc(lenb
);
132 if (data_buf
== NULL
) {
133 LOG_ERROR("no memory for spi buffer");
137 fields
[n
].num_bits
= jtag_tap_count_enabled();
138 fields
[n
].out_value
= NULL
;
139 fields
[n
].in_value
= NULL
;
142 fields
[n
].out_value
= NULL
;
143 fields
[n
].in_value
= data_buf
;
145 flip_u8(data
, data_buf
, lenb
);
146 fields
[n
].out_value
= data_buf
;
147 fields
[n
].in_value
= NULL
;
149 fields
[n
].num_bits
= len
;
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 jtag_execute_queue();
159 flip_u8(data_buf
, data
, lenb
);
164 static int jtagspi_probe(struct flash_bank
*bank
)
166 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
167 struct flash_sector
*sectors
;
169 uint32_t id
, sectorsize
;
175 if (bank
->target
->tap
== NULL
) {
176 LOG_ERROR("Target has no JTAG tap");
179 info
->tap
= bank
->target
->tap
;
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
);
186 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
187 if (p
->device_id
== id
) {
193 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
197 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
198 info
->dev
->name
, info
->dev
->device_id
);
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");
207 /* if no sectors, treat whole bank as single sector */
208 sectorsize
= info
->dev
->sectorsize
?
209 info
->dev
->sectorsize
: info
->dev
->size_in_bytes
;
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
== NULL
) {
215 LOG_ERROR("not enough memory");
219 for (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;
226 bank
->sectors
= sectors
;
231 static void jtagspi_read_status(struct flash_bank
*bank
, uint32_t *status
)
234 if (jtagspi_cmd(bank
, SPIFLASH_READ_STATUS
, NULL
, &buf
, -8) == ERROR_OK
) {
236 /* LOG_DEBUG("status=0x%08" PRIx32, *status); */
240 static int jtagspi_wait(struct flash_bank
*bank
, int timeout_ms
)
243 int64_t t0
= timeval_ms();
247 dt
= timeval_ms() - t0
;
248 jtagspi_read_status(bank
, &status
);
249 if ((status
& SPIFLASH_BSY_BIT
) == 0) {
250 LOG_DEBUG("waited %" PRId64
" ms", dt
);
254 } while (dt
<= timeout_ms
);
256 LOG_ERROR("timeout, device still busy");
260 static int jtagspi_write_enable(struct flash_bank
*bank
)
264 jtagspi_cmd(bank
, SPIFLASH_WRITE_ENABLE
, NULL
, NULL
, 0);
265 jtagspi_read_status(bank
, &status
);
266 if ((status
& SPIFLASH_WE_BIT
) == 0) {
267 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32
, status
);
273 static int jtagspi_bulk_erase(struct flash_bank
*bank
)
275 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
277 int64_t t0
= timeval_ms();
279 if (info
->dev
->chip_erase_cmd
== 0x00)
280 return ERROR_FLASH_OPER_UNSUPPORTED
;
282 retval
= jtagspi_write_enable(bank
);
283 if (retval
!= ERROR_OK
)
285 jtagspi_cmd(bank
, info
->dev
->chip_erase_cmd
, NULL
, NULL
, 0);
286 retval
= jtagspi_wait(bank
, bank
->num_sectors
*JTAGSPI_MAX_TIMEOUT
);
287 LOG_INFO("took %" PRId64
" ms", timeval_ms() - t0
);
291 static int jtagspi_sector_erase(struct flash_bank
*bank
, int sector
)
293 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
295 int64_t t0
= timeval_ms();
297 retval
= jtagspi_write_enable(bank
);
298 if (retval
!= ERROR_OK
)
300 jtagspi_cmd(bank
, info
->dev
->erase_cmd
, &bank
->sectors
[sector
].offset
, NULL
, 0);
301 retval
= jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
302 LOG_INFO("sector %d took %" PRId64
" ms", sector
, timeval_ms() - t0
);
306 static int jtagspi_erase(struct flash_bank
*bank
, int first
, int last
)
309 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
310 int retval
= ERROR_OK
;
312 LOG_DEBUG("erase from sector %d to sector %d", first
, last
);
314 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
315 LOG_ERROR("Flash sector invalid");
316 return ERROR_FLASH_SECTOR_INVALID
;
319 if (!(info
->probed
)) {
320 LOG_ERROR("Flash bank not probed");
321 return ERROR_FLASH_BANK_NOT_PROBED
;
324 for (sector
= first
; sector
<= last
; sector
++) {
325 if (bank
->sectors
[sector
].is_protected
) {
326 LOG_ERROR("Flash sector %d protected", sector
);
331 if (first
== 0 && last
== (bank
->num_sectors
- 1)
332 && info
->dev
->chip_erase_cmd
!= info
->dev
->erase_cmd
) {
333 LOG_DEBUG("Trying bulk erase.");
334 retval
= jtagspi_bulk_erase(bank
);
335 if (retval
== ERROR_OK
)
338 LOG_WARNING("Bulk flash erase failed. Falling back to sector erase.");
341 if (info
->dev
->erase_cmd
== 0x00)
342 return ERROR_FLASH_OPER_UNSUPPORTED
;
344 for (sector
= first
; sector
<= last
; sector
++) {
345 retval
= jtagspi_sector_erase(bank
, sector
);
346 if (retval
!= ERROR_OK
) {
347 LOG_ERROR("Sector erase failed.");
355 static int jtagspi_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
359 for (sector
= first
; sector
<= last
; sector
++)
360 bank
->sectors
[sector
].is_protected
= set
;
364 static int jtagspi_read(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
366 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
368 if (!(info
->probed
)) {
369 LOG_ERROR("Flash bank not yet probed.");
370 return ERROR_FLASH_BANK_NOT_PROBED
;
373 jtagspi_cmd(bank
, SPIFLASH_READ
, &offset
, buffer
, -count
*8);
377 static int jtagspi_page_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
381 retval
= jtagspi_write_enable(bank
);
382 if (retval
!= ERROR_OK
)
384 jtagspi_cmd(bank
, SPIFLASH_PAGE_PROGRAM
, &offset
, (uint8_t *) buffer
, count
*8);
385 return jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
388 static int jtagspi_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
390 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
392 uint32_t n
, pagesize
;
394 if (!(info
->probed
)) {
395 LOG_ERROR("Flash bank not yet probed.");
396 return ERROR_FLASH_BANK_NOT_PROBED
;
399 /* if no write pagesize, use reasonable default */
400 pagesize
= info
->dev
->pagesize
? info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
402 for (n
= 0; n
< count
; n
+= pagesize
) {
403 retval
= jtagspi_page_write(bank
, buffer
+ n
, offset
+ n
,
404 MIN(count
- n
, pagesize
));
405 if (retval
!= ERROR_OK
) {
406 LOG_ERROR("page write error");
409 LOG_DEBUG("wrote page at 0x%08" PRIx32
, offset
+ n
);
414 static int jtagspi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
416 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
418 if (!(info
->probed
)) {
419 snprintf(buf
, buf_size
, "\nJTAGSPI flash bank not probed yet\n");
423 snprintf(buf
, buf_size
, "\nSPIFI flash information:\n"
424 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
425 info
->dev
->name
, info
->dev
->device_id
);
430 const struct flash_driver jtagspi_flash
= {
432 .flash_bank_command
= jtagspi_flash_bank_command
,
433 .erase
= jtagspi_erase
,
434 .protect
= jtagspi_protect
,
435 .write
= jtagspi_write
,
436 .read
= jtagspi_read
,
437 .probe
= jtagspi_probe
,
438 .auto_probe
= jtagspi_probe
,
439 .erase_check
= default_flash_blank_check
,
440 .info
= jtagspi_info
,
441 .free_driver_priv
= default_flash_free_driver_priv
,
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)