1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
26 #include "embeddedice.h"
29 typedef struct ocl_priv_s
31 arm_jtag_t
*jtag_info
;
33 unsigned int bufalign
;
36 static int ocl_erase_check(struct flash_bank_s
*bank
)
41 static int ocl_protect_check(struct flash_bank_s
*bank
)
46 /* flash_bank ocl 0 0 0 0 <target#> */
47 FLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command
)
50 armv4_5_common_t
*armv4_5
;
51 arm7_9_common_t
*arm7_9
;
56 LOG_WARNING("incomplete flash_bank ocl configuration");
57 return ERROR_FLASH_BANK_INVALID
;
60 if ((retval
= arm7_9_get_arch_pointers(bank
->target
, &armv4_5
, &arm7_9
)) != ERROR_OK
)
63 ocl
= bank
->driver_priv
= malloc(sizeof(ocl_priv_t
));
64 ocl
->jtag_info
= &arm7_9
->jtag_info
;
71 static int ocl_erase(struct flash_bank_s
*bank
, int first
, int last
)
73 ocl_priv_t
*ocl
= bank
->driver_priv
;
75 uint32_t dcc_buffer
[3];
77 /* check preconditions */
78 if (bank
->num_sectors
== 0)
79 return ERROR_FLASH_BANK_NOT_PROBED
;
81 if (bank
->target
->state
!= TARGET_RUNNING
)
83 LOG_ERROR("target has to be running to communicate with the loader");
84 return ERROR_TARGET_NOT_RUNNING
;
87 if ((first
== 0) && (last
== bank
->num_sectors
- 1))
89 dcc_buffer
[0] = OCL_ERASE_ALL
;
90 if ((retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
95 dcc_buffer
[0] = OCL_ERASE_BLOCK
;
96 dcc_buffer
[1] = first
;
98 if ((retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 3) != ERROR_OK
))
102 /* wait for response, fixed timeout of 1 s */
103 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000) != ERROR_OK
))
105 if (retval
== ERROR_TARGET_TIMEOUT
)
106 LOG_ERROR("loader not responding");
110 /* receive response */
111 if ((retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
+ 1, 1) != ERROR_OK
))
114 if (dcc_buffer
[1] != OCL_CMD_DONE
)
116 if (dcc_buffer
[0] == OCL_ERASE_ALL
)
117 LOG_ERROR("loader response to OCL_ERASE_ALL 0x%08" PRIx32
"", dcc_buffer
[1]);
119 LOG_ERROR("loader response to OCL_ERASE_BLOCK 0x%08" PRIx32
"", dcc_buffer
[1]);
120 return ERROR_FLASH_OPERATION_FAILED
;
126 static int ocl_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
131 static int ocl_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
133 ocl_priv_t
*ocl
= bank
->driver_priv
;
135 uint32_t *dcc_buffer
;
136 uint32_t *dcc_bufptr
;
143 /* check preconditions */
144 if (ocl
->buflen
== 0 || ocl
->bufalign
== 0)
145 return ERROR_FLASH_BANK_NOT_PROBED
;
147 if (bank
->target
->state
!= TARGET_RUNNING
)
149 LOG_ERROR("target has to be running to communicate with the loader");
150 return ERROR_TARGET_NOT_RUNNING
;
153 /* allocate buffer for max. ocl buffer + overhead */
154 dcc_buffer
= malloc(sizeof(uint32_t)*(ocl
->buflen
/4 + 3));
158 if (count
+ (offset
% ocl
->bufalign
) > ocl
->buflen
)
159 runlen
= ocl
->buflen
- (offset
% ocl
->bufalign
);
163 dcc_buffer
[0] = OCL_FLASH_BLOCK
| runlen
;
164 dcc_buffer
[1] = offset
;
165 dcc_bufptr
= &dcc_buffer
[2];
167 *dcc_bufptr
= 0xffffffff;
168 byteofs
= (offset
% ocl
->bufalign
) % 4;
169 chksum
= OCL_CHKS_INIT
;
171 /* copy data to DCC buffer in proper byte order and properly aligned */
172 for (i
= 0; i
< runlen
; i
++)
177 *dcc_bufptr
&= *(buffer
++) | 0xffffff00;
180 *dcc_bufptr
&= ((*(buffer
++)) << 8) | 0xffff00ff;
183 *dcc_bufptr
&= ((*(buffer
++)) << 16) | 0xff00ffff;
186 *dcc_bufptr
&= ((*(buffer
++)) << 24) | 0x00ffffff;
187 chksum
^= *(dcc_bufptr
++);
188 *dcc_bufptr
= 0xffffffff;
194 /* add the remaining word to checksum */
196 chksum
^= *(dcc_bufptr
++);
198 *(dcc_bufptr
++) = chksum
;
201 if ((retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, dcc_bufptr
-dcc_buffer
)) != ERROR_OK
)
207 /* wait for response, fixed timeout of 1 s */
208 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000) != ERROR_OK
))
210 if (retval
== ERROR_TARGET_TIMEOUT
)
211 LOG_ERROR("loader not responding");
216 /* receive response */
217 if ((retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
223 if (dcc_buffer
[0] != OCL_CMD_DONE
)
225 LOG_ERROR("loader response to OCL_FLASH_BLOCK 0x%08" PRIx32
"", dcc_buffer
[0]);
227 return ERROR_FLASH_OPERATION_FAILED
;
238 static int ocl_probe(struct flash_bank_s
*bank
)
240 ocl_priv_t
*ocl
= bank
->driver_priv
;
242 uint32_t dcc_buffer
[1];
246 /* purge pending data in DCC */
247 embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
249 dcc_buffer
[0] = OCL_PROBE
;
250 if ((retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
253 /* wait for response, fixed timeout of 1 s */
254 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000) != ERROR_OK
))
256 if (retval
== ERROR_TARGET_TIMEOUT
)
257 LOG_ERROR("loader not responding");
261 /* receive response */
262 if ((retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
265 if (dcc_buffer
[0] != OCL_CMD_DONE
)
267 LOG_ERROR("loader response to OCL_PROBE 0x%08" PRIx32
"", dcc_buffer
[0]);
268 return ERROR_FLASH_OPERATION_FAILED
;
271 /* receive and fill in parameters, detection of loader is important, receive it one by one */
272 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0) != ERROR_OK
)
273 || (retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
275 bank
->base
= dcc_buffer
[0];
277 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0) != ERROR_OK
)
278 || (retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
280 bank
->size
= dcc_buffer
[0];
282 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0) != ERROR_OK
)
283 || (retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
285 bank
->num_sectors
= dcc_buffer
[0];
287 if ((retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0) != ERROR_OK
)
288 || (retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1) != ERROR_OK
))
290 ocl
->buflen
= dcc_buffer
[0] & 0xffff;
291 ocl
->bufalign
= dcc_buffer
[0] >> 16;
293 bank
->sectors
= realloc(bank
->sectors
, sizeof(struct flash_sector
)*bank
->num_sectors
);
294 if (bank
->num_sectors
== 0)
296 LOG_ERROR("number of sectors shall be non zero value");
297 return ERROR_FLASH_BANK_INVALID
;
299 if (bank
->size
% bank
->num_sectors
) {
300 LOG_ERROR("bank size not divisible by number of sectors");
301 return ERROR_FLASH_BANK_INVALID
;
303 sectsize
= bank
->size
/ bank
->num_sectors
;
304 for (i
= 0; i
< bank
->num_sectors
; i
++)
306 bank
->sectors
[i
].offset
= i
* sectsize
;
307 bank
->sectors
[i
].size
= sectsize
;
308 bank
->sectors
[i
].is_erased
= -1;
309 bank
->sectors
[i
].is_protected
= -1;
312 if (ocl
->bufalign
== 0)
315 if (ocl
->buflen
== 0)
317 LOG_ERROR("buflen shall be non zero value");
318 return ERROR_FLASH_BANK_INVALID
;
321 if ((ocl
->bufalign
> ocl
->buflen
) || (ocl
->buflen
% ocl
->bufalign
))
323 LOG_ERROR("buflen is not multiple of bufalign");
324 return ERROR_FLASH_BANK_INVALID
;
329 LOG_ERROR("buflen shall be divisible by 4");
330 return ERROR_FLASH_BANK_INVALID
;
336 static int ocl_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
341 static int ocl_auto_probe(struct flash_bank_s
*bank
)
343 ocl_priv_t
*ocl
= bank
->driver_priv
;
345 if (ocl
->buflen
== 0 || ocl
->bufalign
== 0)
346 return ERROR_FLASH_BANK_NOT_PROBED
;
351 flash_driver_t ocl_flash
= {
353 .flash_bank_command
= &ocl_flash_bank_command
,
355 .protect
= &ocl_protect
,
358 .erase_check
= &ocl_erase_check
,
359 .protect_check
= &ocl_protect_check
,
361 .auto_probe
= &ocl_auto_probe
,
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)