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
;
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
;
203 /* create and fill sectors array */
205 info
->dev
->size_in_bytes
/ info
->dev
->sectorsize
;
206 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
207 if (sectors
== NULL
) {
208 LOG_ERROR("not enough memory");
212 for (int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
213 sectors
[sector
].offset
= sector
* info
->dev
->sectorsize
;
214 sectors
[sector
].size
= info
->dev
->sectorsize
;
215 sectors
[sector
].is_erased
= -1;
216 sectors
[sector
].is_protected
= 0;
219 bank
->sectors
= sectors
;
224 static void jtagspi_read_status(struct flash_bank
*bank
, uint32_t *status
)
227 if (jtagspi_cmd(bank
, SPIFLASH_READ_STATUS
, NULL
, &buf
, -8) == ERROR_OK
) {
229 /* LOG_DEBUG("status=0x%08" PRIx32, *status); */
233 static int jtagspi_wait(struct flash_bank
*bank
, int timeout_ms
)
236 int64_t t0
= timeval_ms();
240 dt
= timeval_ms() - t0
;
241 jtagspi_read_status(bank
, &status
);
242 if ((status
& SPIFLASH_BSY_BIT
) == 0) {
243 LOG_DEBUG("waited %" PRId64
" ms", dt
);
247 } while (dt
<= timeout_ms
);
249 LOG_ERROR("timeout, device still busy");
253 static int jtagspi_write_enable(struct flash_bank
*bank
)
257 jtagspi_cmd(bank
, SPIFLASH_WRITE_ENABLE
, NULL
, NULL
, 0);
258 jtagspi_read_status(bank
, &status
);
259 if ((status
& SPIFLASH_WE_BIT
) == 0) {
260 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32
, status
);
266 static int jtagspi_bulk_erase(struct flash_bank
*bank
)
268 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
270 int64_t t0
= timeval_ms();
272 retval
= jtagspi_write_enable(bank
);
273 if (retval
!= ERROR_OK
)
275 jtagspi_cmd(bank
, info
->dev
->chip_erase_cmd
, NULL
, NULL
, 0);
276 retval
= jtagspi_wait(bank
, bank
->num_sectors
*JTAGSPI_MAX_TIMEOUT
);
277 LOG_INFO("took %" PRId64
" ms", timeval_ms() - t0
);
281 static int jtagspi_sector_erase(struct flash_bank
*bank
, int sector
)
283 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
285 int64_t t0
= timeval_ms();
287 retval
= jtagspi_write_enable(bank
);
288 if (retval
!= ERROR_OK
)
290 jtagspi_cmd(bank
, info
->dev
->erase_cmd
, &bank
->sectors
[sector
].offset
, NULL
, 0);
291 retval
= jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
292 LOG_INFO("sector %d took %" PRId64
" ms", sector
, timeval_ms() - t0
);
296 static int jtagspi_erase(struct flash_bank
*bank
, int first
, int last
)
299 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
300 int retval
= ERROR_OK
;
302 LOG_DEBUG("erase from sector %d to sector %d", first
, last
);
304 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
305 LOG_ERROR("Flash sector invalid");
306 return ERROR_FLASH_SECTOR_INVALID
;
309 if (!(info
->probed
)) {
310 LOG_ERROR("Flash bank not probed");
311 return ERROR_FLASH_BANK_NOT_PROBED
;
314 for (sector
= first
; sector
<= last
; sector
++) {
315 if (bank
->sectors
[sector
].is_protected
) {
316 LOG_ERROR("Flash sector %d protected", sector
);
321 if (first
== 0 && last
== (bank
->num_sectors
- 1)
322 && info
->dev
->chip_erase_cmd
!= info
->dev
->erase_cmd
) {
323 LOG_DEBUG("Trying bulk erase.");
324 retval
= jtagspi_bulk_erase(bank
);
325 if (retval
== ERROR_OK
)
328 LOG_WARNING("Bulk flash erase failed. Falling back to sector erase.");
331 for (sector
= first
; sector
<= last
; sector
++) {
332 retval
= jtagspi_sector_erase(bank
, sector
);
333 if (retval
!= ERROR_OK
) {
334 LOG_ERROR("Sector erase failed.");
342 static int jtagspi_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
346 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
347 LOG_ERROR("Flash sector invalid");
348 return ERROR_FLASH_SECTOR_INVALID
;
351 for (sector
= first
; sector
<= last
; sector
++)
352 bank
->sectors
[sector
].is_protected
= set
;
356 static int jtagspi_protect_check(struct flash_bank
*bank
)
361 static int jtagspi_read(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
363 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
365 if (!(info
->probed
)) {
366 LOG_ERROR("Flash bank not yet probed.");
367 return ERROR_FLASH_BANK_NOT_PROBED
;
370 jtagspi_cmd(bank
, SPIFLASH_READ
, &offset
, buffer
, -count
*8);
374 static int jtagspi_page_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
378 retval
= jtagspi_write_enable(bank
);
379 if (retval
!= ERROR_OK
)
381 jtagspi_cmd(bank
, SPIFLASH_PAGE_PROGRAM
, &offset
, (uint8_t *) buffer
, count
*8);
382 return jtagspi_wait(bank
, JTAGSPI_MAX_TIMEOUT
);
385 static int jtagspi_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
387 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
391 if (!(info
->probed
)) {
392 LOG_ERROR("Flash bank not yet probed.");
393 return ERROR_FLASH_BANK_NOT_PROBED
;
396 for (n
= 0; n
< count
; n
+= info
->dev
->pagesize
) {
397 retval
= jtagspi_page_write(bank
, buffer
+ n
, offset
+ n
,
398 MIN(count
- n
, info
->dev
->pagesize
));
399 if (retval
!= ERROR_OK
) {
400 LOG_ERROR("page write error");
403 LOG_DEBUG("wrote page at 0x%08" PRIx32
, offset
+ n
);
408 static int jtagspi_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
410 struct jtagspi_flash_bank
*info
= bank
->driver_priv
;
412 if (!(info
->probed
)) {
413 snprintf(buf
, buf_size
, "\nJTAGSPI flash bank not probed yet\n");
417 snprintf(buf
, buf_size
, "\nSPIFI flash information:\n"
418 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
419 info
->dev
->name
, info
->dev
->device_id
);
424 struct flash_driver jtagspi_flash
= {
426 .flash_bank_command
= jtagspi_flash_bank_command
,
427 .erase
= jtagspi_erase
,
428 .protect
= jtagspi_protect
,
429 .write
= jtagspi_write
,
430 .read
= jtagspi_read
,
431 .probe
= jtagspi_probe
,
432 .auto_probe
= jtagspi_probe
,
433 .erase_check
= default_flash_blank_check
,
434 .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)