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,