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
,