1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2007 by Pavel Chromy *
6 ***************************************************************************/
14 #include <target/embeddedice.h>
17 struct arm_jtag
*jtag_info
;
19 unsigned int bufalign
;
22 /* flash_bank ocl 0 0 0 0 <target#> */
23 FLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command
)
25 struct arm7_9_common
*arm7_9
;
29 return ERROR_COMMAND_SYNTAX_ERROR
;
31 arm7_9
= target_to_arm7_9(bank
->target
);
32 if (!is_arm7_9(arm7_9
))
33 return ERROR_TARGET_INVALID
;
35 ocl
= bank
->driver_priv
= malloc(sizeof(struct ocl_priv
));
36 ocl
->jtag_info
= &arm7_9
->jtag_info
;
43 static int ocl_erase(struct flash_bank
*bank
, unsigned int first
,
46 struct ocl_priv
*ocl
= bank
->driver_priv
;
48 uint32_t dcc_buffer
[3];
50 /* check preconditions */
51 if (bank
->num_sectors
== 0)
52 return ERROR_FLASH_BANK_NOT_PROBED
;
54 if (bank
->target
->state
!= TARGET_RUNNING
) {
55 LOG_ERROR("target has to be running to communicate with the loader");
56 return ERROR_TARGET_NOT_RUNNING
;
59 if ((first
== 0) && (last
== bank
->num_sectors
- 1)) {
60 dcc_buffer
[0] = OCL_ERASE_ALL
;
61 retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 1);
62 if (retval
!= ERROR_OK
)
65 dcc_buffer
[0] = OCL_ERASE_BLOCK
;
66 dcc_buffer
[1] = first
;
68 retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 3);
69 if (retval
!= ERROR_OK
)
73 /* wait for response, fixed timeout of 1 s */
74 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000);
75 if (retval
!= ERROR_OK
)
78 /* receive response */
79 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
+ 1, 1);
80 if (retval
!= ERROR_OK
)
83 if (dcc_buffer
[1] != OCL_CMD_DONE
) {
84 if (dcc_buffer
[0] == OCL_ERASE_ALL
)
85 LOG_ERROR("loader response to OCL_ERASE_ALL 0x%08" PRIx32
"", dcc_buffer
[1]);
87 LOG_ERROR("loader response to OCL_ERASE_BLOCK 0x%08" PRIx32
"", dcc_buffer
[1]);
88 return ERROR_FLASH_OPERATION_FAILED
;
94 static int ocl_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
96 struct ocl_priv
*ocl
= bank
->driver_priv
;
106 /* check preconditions */
107 if (ocl
->buflen
== 0 || ocl
->bufalign
== 0)
108 return ERROR_FLASH_BANK_NOT_PROBED
;
110 if (bank
->target
->state
!= TARGET_RUNNING
) {
111 LOG_ERROR("target has to be running to communicate with the loader");
112 return ERROR_TARGET_NOT_RUNNING
;
115 /* allocate buffer for max. ocl buffer + overhead */
116 dcc_buffer
= malloc(sizeof(uint32_t)*(ocl
->buflen
/4 + 3));
119 if (count
+ (offset
% ocl
->bufalign
) > ocl
->buflen
)
120 runlen
= ocl
->buflen
- (offset
% ocl
->bufalign
);
124 dcc_buffer
[0] = OCL_FLASH_BLOCK
| runlen
;
125 dcc_buffer
[1] = offset
;
126 dcc_bufptr
= &dcc_buffer
[2];
128 *dcc_bufptr
= 0xffffffff;
129 byteofs
= (offset
% ocl
->bufalign
) % 4;
130 chksum
= OCL_CHKS_INIT
;
132 /* copy data to DCC buffer in proper byte order and properly aligned */
133 for (i
= 0; i
< runlen
; i
++) {
136 *dcc_bufptr
&= *(buffer
++) | 0xffffff00;
139 *dcc_bufptr
&= ((*(buffer
++)) << 8) | 0xffff00ff;
142 *dcc_bufptr
&= ((*(buffer
++)) << 16) | 0xff00ffff;
145 *dcc_bufptr
&= ((*(buffer
++)) << 24) | 0x00ffffff;
146 chksum
^= *(dcc_bufptr
++);
147 *dcc_bufptr
= 0xffffffff;
153 /* add the remaining word to checksum */
155 chksum
^= *(dcc_bufptr
++);
157 *(dcc_bufptr
++) = chksum
;
160 retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, dcc_bufptr
-dcc_buffer
);
161 if (retval
!= ERROR_OK
) {
166 /* wait for response, fixed timeout of 1 s */
167 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000);
168 if (retval
!= ERROR_OK
) {
173 /* receive response */
174 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
175 if (retval
!= ERROR_OK
) {
180 if (dcc_buffer
[0] != OCL_CMD_DONE
) {
181 LOG_ERROR("loader response to OCL_FLASH_BLOCK 0x%08" PRIx32
"", dcc_buffer
[0]);
183 return ERROR_FLASH_OPERATION_FAILED
;
194 static int ocl_probe(struct flash_bank
*bank
)
196 struct ocl_priv
*ocl
= bank
->driver_priv
;
198 uint32_t dcc_buffer
[1];
201 /* purge pending data in DCC */
202 embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
204 dcc_buffer
[0] = OCL_PROBE
;
205 retval
= embeddedice_send(ocl
->jtag_info
, dcc_buffer
, 1);
206 if (retval
!= ERROR_OK
)
209 /* wait for response, fixed timeout of 1 s */
210 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 1000);
211 if (retval
!= ERROR_OK
)
214 /* receive response */
215 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
216 if (retval
!= ERROR_OK
)
219 if (dcc_buffer
[0] != OCL_CMD_DONE
) {
220 LOG_ERROR("loader response to OCL_PROBE 0x%08" PRIx32
"", dcc_buffer
[0]);
221 return ERROR_FLASH_OPERATION_FAILED
;
224 /* receive and fill in parameters, detection of loader is important, receive it one by one */
225 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0);
226 if (retval
!= ERROR_OK
)
228 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
229 if (retval
!= ERROR_OK
)
231 bank
->base
= dcc_buffer
[0];
233 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0);
234 if (retval
!= ERROR_OK
)
236 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
237 if (retval
!= ERROR_OK
)
239 bank
->size
= dcc_buffer
[0];
241 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0);
242 if (retval
!= ERROR_OK
)
244 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
245 if (retval
!= ERROR_OK
)
247 bank
->num_sectors
= dcc_buffer
[0];
249 retval
= embeddedice_handshake(ocl
->jtag_info
, EICE_COMM_CTRL_WBIT
, 0);
250 if (retval
!= ERROR_OK
)
252 retval
= embeddedice_receive(ocl
->jtag_info
, dcc_buffer
, 1);
253 if (retval
!= ERROR_OK
)
255 ocl
->buflen
= dcc_buffer
[0] & 0xffff;
256 ocl
->bufalign
= dcc_buffer
[0] >> 16;
258 bank
->sectors
= realloc(bank
->sectors
, sizeof(struct flash_sector
)*bank
->num_sectors
);
259 if (bank
->num_sectors
== 0) {
260 LOG_ERROR("number of sectors shall be non zero value");
261 return ERROR_FLASH_BANK_INVALID
;
263 if (bank
->size
% bank
->num_sectors
) {
264 LOG_ERROR("bank size not divisible by number of sectors");
265 return ERROR_FLASH_BANK_INVALID
;
267 sectsize
= bank
->size
/ bank
->num_sectors
;
268 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
269 bank
->sectors
[i
].offset
= i
* sectsize
;
270 bank
->sectors
[i
].size
= sectsize
;
271 bank
->sectors
[i
].is_erased
= -1;
272 bank
->sectors
[i
].is_protected
= -1;
275 if (ocl
->bufalign
== 0)
278 if (ocl
->buflen
== 0) {
279 LOG_ERROR("buflen shall be non zero value");
280 return ERROR_FLASH_BANK_INVALID
;
283 if ((ocl
->bufalign
> ocl
->buflen
) || (ocl
->buflen
% ocl
->bufalign
)) {
284 LOG_ERROR("buflen is not multiple of bufalign");
285 return ERROR_FLASH_BANK_INVALID
;
288 if (ocl
->buflen
% 4) {
289 LOG_ERROR("buflen shall be divisible by 4");
290 return ERROR_FLASH_BANK_INVALID
;
296 static int ocl_auto_probe(struct flash_bank
*bank
)
298 struct ocl_priv
*ocl
= bank
->driver_priv
;
300 if (ocl
->buflen
== 0 || ocl
->bufalign
== 0)
301 return ERROR_FLASH_BANK_NOT_PROBED
;
306 const struct flash_driver ocl_flash
= {
308 .flash_bank_command
= ocl_flash_bank_command
,
311 .read
= default_flash_read
,
313 .erase_check
= default_flash_blank_check
,
314 .auto_probe
= ocl_auto_probe
,
315 .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)