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 ***************************************************************************/
21 #include <jtag/jtag.h>
22 #include <flash/nor/spi.h>
23 #include <helper/time_support.h>
25 #define JTAGSPI_MAX_TIMEOUT 3000
28 struct jtagspi_flash_bank
{
30 const struct flash_device
*dev
;
36 FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command
)
38 struct jtagspi_flash_bank
*info
;
41 return ERROR_COMMAND_SYNTAX_ERROR
;
43 info
= malloc(sizeof(struct jtagspi_flash_bank
));
45 LOG_ERROR("no memory for flash bank info");
48 bank
->driver_priv
= info
;
52 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], info
->ir
);
53 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[7], info
->dr_len
);
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 if (buf_get_u32(info
->tap
->cur_instr
, 0, info
->tap
->ir_length
) == info
->ir
)
67 LOG_DEBUG("loading jtagspi ir");
68 buf_set_u32(buf
, 0, info
->tap
->ir_length
, info
->ir
);
69 field
.num_bits
= info
->tap
->ir_length
;
70 field
.out_value
= buf
;
71 field
.in_value
= NULL
;
72 jtag_add_ir_scan(info
->tap
, &field
, TAP_IDLE
);
75 static void flip_u8(uint8_t *in
, uint8_t *out
, int len
)
77 for (int i
= 0; i
< len
; i
++)
78 out
[i
] = flip_u32(in
[i
], 8);
81 static int jtagspi_cmd(struct flash_bank
*bank
, uint8_t cmd
,
82 uint32_t *addr
, uint8_t *data
, int len
)
84 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
85 struct scan_field fields
[3];
90 /* LOG_DEBUG("cmd=0x%02x len=%i", cmd, len); */
93 fields
[n
].num_bits
= 8;
96 h_u24_to_be(cmd_buf
+ 1, *addr
);
97 fields
[n
].num_bits
+= 24;
99 flip_u8(cmd_buf
, cmd_buf
, 4);
100 fields
[n
].out_value
= cmd_buf
;
101 fields
[n
].in_value
= NULL
;
107 lenb
= DIV_ROUND_UP(len
, 8);
108 data_buf
= malloc(lenb
);
110 if (data_buf
== NULL
) {
111 LOG_ERROR("no memory for spi buffer");
115 fields
[n
].num_bits
= info
->dr_len
;
116 fields
[n
].out_value
= NULL
;
117 fields
[n
].in_value
= NULL
;
119 fields
[n
].out_value
= NULL
;
120 fields
[n
].in_value
= data_buf
;
122 flip_u8(data
, data_buf
, lenb
);
123 fields
[n
].out_value
= data_buf
;
124 fields
[n
].in_value
= NULL
;
126 fields
[n
].num_bits
= len
;
130 jtagspi_set_ir(bank
);
131 jtag_add_dr_scan(info
->tap
, n
, fields
, TAP_IDLE
);
132 jtag_execute_queue();
135 flip_u8(data_buf
, data
, lenb
);
140 static int jtagspi_probe(struct flash_bank
*bank
)
142 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
143 struct flash_sector
*sectors
;
151 if (bank
->target
->tap
== NULL
) {
152 LOG_ERROR("Target has no JTAG tap");
155 info
->tap
= bank
->target
->tap
;
157 jtagspi_cmd(bank
, SPIFLASH_READ_ID
, NULL
, in_buf
, -24);
158 /* the table in spi.c has the manufacturer byte (first) as the lsb */
159 id
= le_to_h_u24(in_buf
);
162 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
163 if (p
->device_id
== id
) {
169 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
173 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
174 info
->dev
->name
, info
->dev
->device_id
);
176 /* Set correct size value */
177 bank
->size
= info
->dev
->size_in_bytes
;
179 /* create and fill sectors array */
181 info
->dev
->size_in_bytes
/ info
->dev
->sectorsize
;
182 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
183 if (sectors
== NULL
) {
184 LOG_ERROR("not enough memory");
188 for (int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
189 sectors
[sector
].offset
= sector
* info
->dev
->sectorsize
;
190 sectors
[sector
].size
= info
->dev
->sectorsize
;
191 sectors
[sector
].is_erased
= -1;
192 sectors
[sector
].is_protected
= 0;
195 bank
->sectors
= sectors
;
200 static void jtagspi_read_status(struct flash_bank
*bank
, uint32_t *status
)
203 jtagspi_cmd(bank
, SPIFLASH_READ_STATUS
, NULL
, &buf
, -8);
205 /* LOG_DEBUG("status=0x%08" PRIx32, *status); */
208 static int jtagspi_wait(struct flash_bank
*bank
, int timeout_ms
)
211 long long t0
= timeval_ms();
215 dt
= timeval_ms() - t0
;
216 jtagspi_read_status(bank
, &status
);
217 if ((status
& SPIFLASH_BSY_BIT
) == 0) {
218 LOG_DEBUG("waited %lld ms", dt
);
222 } while (dt
<= timeout_ms
);
224 LOG_ERROR("timeout, device still busy");
228 static int jtagspi_write_enable(struct flash_bank
*bank
)
232 jtagspi_cmd(bank
, SPIFLASH_WRITE_ENABLE
, NULL
, NULL
, 0);
233 jtagspi_read_status(bank
, &status
);
234 if ((status
& SPIFLASH_WE_BIT
) == 0) {
235 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32
, status
);
241 static int jtagspi_bulk_erase(struct flash_bank
*bank
)
243 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
245 long long t0
= timeval_ms();
247 retval
= jtagspi_write_enable(bank
);
248 if (retval
!= ERROR_OK
)
250 jtagspi_cmd(bank
, info
->dev
->chip_erase_cmd
, NULL
, NULL
, 0);
251 retval
= jtagspi_wait(bank
, bank
->num_sectors
*JTAGSPI_MAX_TIMEOUT
);
252 LOG_INFO("took %lld ms", timeval_ms() - t0
);
256 static int jtagspi_sector_erase(struct flash_bank
*bank
, int sector
)
258 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
260 long long t0
= timeval_ms();
262 retval
= jtagspi_write_enable(bank
);
263 if (retval
!= ERROR_OK
)
265 jtagspi_cmd(bank
, info
->dev
->erase_cmd
, &bank
->sectors
[sector
].offset
, NULL
, 0);
266 retval
= jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
267 LOG_INFO("sector %d took %lld ms", sector
, timeval_ms() - t0
);
271 static int jtagspi_erase(struct flash_bank
*bank
, int first
, int last
)
274 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
277 LOG_DEBUG("erase from sector %d to sector %d", first
, last
);
279 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
280 LOG_ERROR("Flash sector invalid");
281 return ERROR_FLASH_SECTOR_INVALID
;
284 if (!(info
->probed
)) {
285 LOG_ERROR("Flash bank not probed");
286 return ERROR_FLASH_BANK_NOT_PROBED
;
289 for (sector
= first
; sector
<= last
; sector
++) {
290 if (bank
->sectors
[sector
].is_protected
) {
291 LOG_ERROR("Flash sector %d protected", sector
);
296 if (first
== 0 && last
== (bank
->num_sectors
- 1)
297 && info
->dev
->chip_erase_cmd
!= info
->dev
->erase_cmd
) {
298 LOG_DEBUG("Trying bulk erase.");
299 retval
= jtagspi_bulk_erase(bank
);
300 if (retval
== ERROR_OK
)
303 LOG_WARNING("Bulk flash erase failed. Falling back to sector erase.");
306 for (sector
= first
; sector
<= last
; sector
++) {
307 retval
= jtagspi_sector_erase(bank
, sector
);
308 if (retval
!= ERROR_OK
) {
309 LOG_ERROR("Sector erase failed.");
317 static int jtagspi_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
321 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
322 LOG_ERROR("Flash sector invalid");
323 return ERROR_FLASH_SECTOR_INVALID
;
326 for (sector
= first
; sector
<= last
; sector
++)
327 bank
->sectors
[sector
].is_protected
= set
;
331 static int jtagspi_protect_check(struct flash_bank
*bank
)
336 static int jtagspi_read(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
338 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
340 if (!(info
->probed
)) {
341 LOG_ERROR("Flash bank not yet probed.");
342 return ERROR_FLASH_BANK_NOT_PROBED
;
345 jtagspi_cmd(bank
, SPIFLASH_READ
, &offset
, buffer
, -count
*8);
349 static int jtagspi_page_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
353 retval
= jtagspi_write_enable(bank
);
354 if (retval
!= ERROR_OK
)
356 jtagspi_cmd(bank
, SPIFLASH_PAGE_PROGRAM
, &offset
, (uint8_t *) buffer
, count
*8);
357 return jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
360 static int jtagspi_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
362 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
366 if (!(info
->probed
)) {
367 LOG_ERROR("Flash bank not yet probed.");
368 return ERROR_FLASH_BANK_NOT_PROBED
;
371 for (n
= 0; n
< count
; n
+= info
->dev
->pagesize
) {
372 retval
= jtagspi_page_write(bank
, buffer
+ n
, offset
+ n
,
373 MIN(count
- n
, info
->dev
->pagesize
));
374 if (retval
!= ERROR_OK
) {
375 LOG_ERROR("page write error");
378 LOG_DEBUG("wrote page at 0x%08" PRIx32
, offset
+ n
);
383 static int jtagspi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
385 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
387 if (!(info
->probed
)) {
388 snprintf(buf
, buf_size
, "\nJTAGSPI flash bank not probed yet\n");
392 snprintf(buf
, buf_size
, "\nSPIFI flash information:\n"
393 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
394 info
->dev
->name
, info
->dev
->device_id
);
399 struct flash_driver jtagspi_flash
= {
401 .flash_bank_command
= jtagspi_flash_bank_command
,
402 .erase
= jtagspi_erase
,
403 .protect
= jtagspi_protect
,
404 .write
= jtagspi_write
,
405 .read
= jtagspi_read
,
406 .probe
= jtagspi_probe
,
407 .auto_probe
= jtagspi_probe
,
408 .erase_check
= default_flash_blank_check
,
409 .protect_check
= jtagspi_protect_check
,
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)