openocd: fix SPDX tag format for files .c
[openocd.git] / src / flash / nor / renesas_rpchf.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4 * Renesas RCar Gen3 RPC Hyperflash driver
5 * Based on U-Boot RPC Hyperflash driver
6 *
7 * Copyright (C) 2016 Renesas Electronics Corporation
8 * Copyright (C) 2016 Cogent Embedded, Inc.
9 * Copyright (C) 2017-2019 Marek Vasut <marek.vasut@gmail.com>
10 */
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #include "imp.h"
17 #include "cfi.h"
18 #include "non_cfi.h"
19 #include <helper/binarybuffer.h>
20 #include <helper/bits.h>
21 #include <helper/time_support.h>
22
23 #define RPC_CMNCR 0x0000 /* R/W */
24 #define RPC_CMNCR_MD BIT(31)
25 #define RPC_CMNCR_MOIIO0(val) (((val) & 0x3) << 16)
26 #define RPC_CMNCR_MOIIO1(val) (((val) & 0x3) << 18)
27 #define RPC_CMNCR_MOIIO2(val) (((val) & 0x3) << 20)
28 #define RPC_CMNCR_MOIIO3(val) (((val) & 0x3) << 22)
29 #define RPC_CMNCR_MOIIO_HIZ (RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \
30 RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))
31 #define RPC_CMNCR_IO0FV(val) (((val) & 0x3) << 8)
32 #define RPC_CMNCR_IO2FV(val) (((val) & 0x3) << 12)
33 #define RPC_CMNCR_IO3FV(val) (((val) & 0x3) << 14)
34 #define RPC_CMNCR_IOFV_HIZ (RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \
35 RPC_CMNCR_IO3FV(3))
36 #define RPC_CMNCR_BSZ(val) (((val) & 0x3) << 0)
37
38 #define RPC_SSLDR 0x0004 /* R/W */
39 #define RPC_SSLDR_SPNDL(d) (((d) & 0x7) << 16)
40 #define RPC_SSLDR_SLNDL(d) (((d) & 0x7) << 8)
41 #define RPC_SSLDR_SCKDL(d) (((d) & 0x7) << 0)
42
43 #define RPC_DRCR 0x000C /* R/W */
44 #define RPC_DRCR_SSLN BIT(24)
45 #define RPC_DRCR_RBURST(v) (((v) & 0x1F) << 16)
46 #define RPC_DRCR_RCF BIT(9)
47 #define RPC_DRCR_RBE BIT(8)
48 #define RPC_DRCR_SSLE BIT(0)
49
50 #define RPC_DRCMR 0x0010 /* R/W */
51 #define RPC_DRCMR_CMD(c) (((c) & 0xFF) << 16)
52 #define RPC_DRCMR_OCMD(c) (((c) & 0xFF) << 0)
53
54 #define RPC_DREAR 0x0014 /* R/W */
55 #define RPC_DREAR_EAV(v) (((v) & 0xFF) << 16)
56 #define RPC_DREAR_EAC(v) (((v) & 0x7) << 0)
57
58 #define RPC_DROPR 0x0018 /* R/W */
59 #define RPC_DROPR_OPD3(o) (((o) & 0xFF) << 24)
60 #define RPC_DROPR_OPD2(o) (((o) & 0xFF) << 16)
61 #define RPC_DROPR_OPD1(o) (((o) & 0xFF) << 8)
62 #define RPC_DROPR_OPD0(o) (((o) & 0xFF) << 0)
63
64 #define RPC_DRENR 0x001C /* R/W */
65 #define RPC_DRENR_CDB(o) (uint32_t)((((o) & 0x3) << 30))
66 #define RPC_DRENR_OCDB(o) (((o) & 0x3) << 28)
67 #define RPC_DRENR_ADB(o) (((o) & 0x3) << 24)
68 #define RPC_DRENR_OPDB(o) (((o) & 0x3) << 20)
69 #define RPC_DRENR_SPIDB(o) (((o) & 0x3) << 16)
70 #define RPC_DRENR_DME BIT(15)
71 #define RPC_DRENR_CDE BIT(14)
72 #define RPC_DRENR_OCDE BIT(12)
73 #define RPC_DRENR_ADE(v) (((v) & 0xF) << 8)
74 #define RPC_DRENR_OPDE(v) (((v) & 0xF) << 4)
75
76 #define RPC_SMCR 0x0020 /* R/W */
77 #define RPC_SMCR_SSLKP BIT(8)
78 #define RPC_SMCR_SPIRE BIT(2)
79 #define RPC_SMCR_SPIWE BIT(1)
80 #define RPC_SMCR_SPIE BIT(0)
81
82 #define RPC_SMCMR 0x0024 /* R/W */
83 #define RPC_SMCMR_CMD(c) (((c) & 0xFF) << 16)
84 #define RPC_SMCMR_OCMD(c) (((c) & 0xFF) << 0)
85
86 #define RPC_SMADR 0x0028 /* R/W */
87 #define RPC_SMOPR 0x002C /* R/W */
88 #define RPC_SMOPR_OPD0(o) (((o) & 0xFF) << 0)
89 #define RPC_SMOPR_OPD1(o) (((o) & 0xFF) << 8)
90 #define RPC_SMOPR_OPD2(o) (((o) & 0xFF) << 16)
91 #define RPC_SMOPR_OPD3(o) (((o) & 0xFF) << 24)
92
93 #define RPC_SMENR 0x0030 /* R/W */
94 #define RPC_SMENR_CDB(o) (((o) & 0x3) << 30)
95 #define RPC_SMENR_OCDB(o) (((o) & 0x3) << 28)
96 #define RPC_SMENR_ADB(o) (((o) & 0x3) << 24)
97 #define RPC_SMENR_OPDB(o) (((o) & 0x3) << 20)
98 #define RPC_SMENR_SPIDB(o) (((o) & 0x3) << 16)
99 #define RPC_SMENR_DME BIT(15)
100 #define RPC_SMENR_CDE BIT(14)
101 #define RPC_SMENR_OCDE BIT(12)
102 #define RPC_SMENR_ADE(v) (((v) & 0xF) << 8)
103 #define RPC_SMENR_OPDE(v) (((v) & 0xF) << 4)
104 #define RPC_SMENR_SPIDE(v) (((v) & 0xF) << 0)
105
106 #define RPC_SMRDR0 0x0038 /* R */
107 #define RPC_SMRDR1 0x003C /* R */
108 #define RPC_SMWDR0 0x0040 /* R/W */
109 #define RPC_SMWDR1 0x0044 /* R/W */
110 #define RPC_CMNSR 0x0048 /* R */
111 #define RPC_CMNSR_SSLF BIT(1)
112 #define RPC_CMNSR_TEND BIT(0)
113
114 #define RPC_DRDMCR 0x0058 /* R/W */
115 #define RPC_DRDMCR_DMCYC(v) (((v) & 0xF) << 0)
116
117 #define RPC_DRDRENR 0x005C /* R/W */
118 #define RPC_DRDRENR_HYPE (0x5 << 12)
119 #define RPC_DRDRENR_ADDRE BIT(8)
120 #define RPC_DRDRENR_OPDRE BIT(4)
121 #define RPC_DRDRENR_DRDRE BIT(0)
122
123 #define RPC_SMDMCR 0x0060 /* R/W */
124 #define RPC_SMDMCR_DMCYC(v) (((v) & 0xF) << 0)
125
126 #define RPC_SMDRENR 0x0064 /* R/W */
127 #define RPC_SMDRENR_HYPE (0x5 << 12)
128 #define RPC_SMDRENR_ADDRE BIT(8)
129 #define RPC_SMDRENR_OPDRE BIT(4)
130 #define RPC_SMDRENR_SPIDRE BIT(0)
131
132 #define RPC_PHYCNT 0x007C /* R/W */
133 #define RPC_PHYCNT_CAL BIT(31)
134 #define PRC_PHYCNT_OCTA_AA BIT(22)
135 #define PRC_PHYCNT_OCTA_SA BIT(23)
136 #define PRC_PHYCNT_EXDS BIT(21)
137 #define RPC_PHYCNT_OCT BIT(20)
138 #define RPC_PHYCNT_WBUF2 BIT(4)
139 #define RPC_PHYCNT_WBUF BIT(2)
140 #define RPC_PHYCNT_MEM(v) (((v) & 0x3) << 0)
141
142 #define RPC_PHYINT 0x0088 /* R/W */
143 #define RPC_PHYINT_RSTEN BIT(18)
144 #define RPC_PHYINT_WPEN BIT(17)
145 #define RPC_PHYINT_INTEN BIT(16)
146 #define RPC_PHYINT_RST BIT(2)
147 #define RPC_PHYINT_WP BIT(1)
148 #define RPC_PHYINT_INT BIT(0)
149
150 #define RPC_WBUF 0x8000 /* R/W size=4/8/16/32/64Bytes */
151 #define RPC_WBUF_SIZE 0x100
152
153 static uint32_t rpc_base = 0xee200000;
154 static uint32_t mem_base = 0x08000000;
155
156 enum rpc_hf_size {
157 RPC_HF_SIZE_16BIT = RPC_SMENR_SPIDE(0x8),
158 RPC_HF_SIZE_32BIT = RPC_SMENR_SPIDE(0xC),
159 RPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF),
160 };
161
162 static int rpc_hf_wait_tend(struct target *target)
163 {
164 uint32_t reg = rpc_base + RPC_CMNSR;
165 uint32_t val;
166 unsigned long timeout = 1000;
167 long long endtime;
168 int ret;
169
170 endtime = timeval_ms() + timeout;
171 do {
172 ret = target_read_u32(target, reg, &val);
173 if (ret != ERROR_OK)
174 return ERROR_FAIL;
175
176 if (val & RPC_CMNSR_TEND)
177 return ERROR_OK;
178
179 alive_sleep(1);
180 } while (timeval_ms() < endtime);
181
182 LOG_ERROR("timeout");
183 return ERROR_TIMEOUT_REACHED;
184 }
185
186 static int clrsetbits_u32(struct target *target, uint32_t reg,
187 uint32_t clr, uint32_t set)
188 {
189 uint32_t val;
190 int ret;
191
192 ret = target_read_u32(target, reg, &val);
193 if (ret != ERROR_OK)
194 return ret;
195
196 val &= ~clr;
197 val |= set;
198
199 return target_write_u32(target, reg, val);
200 }
201
202 static int rpc_hf_mode(struct target *target, bool manual)
203 {
204 uint32_t val;
205 int ret;
206
207 ret = rpc_hf_wait_tend(target);
208 if (ret != ERROR_OK) {
209 LOG_ERROR("Mode TEND timeout");
210 return ret;
211 }
212
213 ret = clrsetbits_u32(target, rpc_base + RPC_PHYCNT,
214 RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |
215 RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3),
216 RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
217 if (ret != ERROR_OK)
218 return ret;
219
220 ret = clrsetbits_u32(target, rpc_base + RPC_CMNCR,
221 RPC_CMNCR_MD | RPC_CMNCR_BSZ(3),
222 RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
223 (manual ? RPC_CMNCR_MD : 0) | RPC_CMNCR_BSZ(1));
224 if (ret != ERROR_OK)
225 return ret;
226
227 if (manual)
228 return ERROR_OK;
229
230 ret = target_write_u32(target, rpc_base + RPC_DRCR,
231 RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF |
232 RPC_DRCR_RBE);
233 if (ret != ERROR_OK)
234 return ret;
235
236 ret = target_write_u32(target, rpc_base + RPC_DRCMR,
237 RPC_DRCMR_CMD(0xA0));
238 if (ret != ERROR_OK)
239 return ret;
240 ret = target_write_u32(target, rpc_base + RPC_DRENR,
241 RPC_DRENR_CDB(2) | RPC_DRENR_OCDB(2) |
242 RPC_DRENR_ADB(2) | RPC_DRENR_SPIDB(2) |
243 RPC_DRENR_CDE | RPC_DRENR_OCDE |
244 RPC_DRENR_ADE(4));
245 if (ret != ERROR_OK)
246 return ret;
247
248 ret = target_write_u32(target, rpc_base + RPC_DRDMCR,
249 RPC_DRDMCR_DMCYC(0xE));
250 if (ret != ERROR_OK)
251 return ret;
252
253 ret = target_write_u32(target, rpc_base + RPC_DRDRENR,
254 RPC_DRDRENR_HYPE | RPC_DRDRENR_ADDRE |
255 RPC_DRDRENR_DRDRE);
256 if (ret != ERROR_OK)
257 return ret;
258
259 /* Dummy read */
260 return target_read_u32(target, rpc_base + RPC_DRCR, &val);
261 }
262
263 static int rpc_hf_xfer(struct target *target, target_addr_t addr,
264 uint32_t wdata, uint32_t *rdata, enum rpc_hf_size size,
265 bool write, const uint8_t *wbuf, unsigned int wbuf_size)
266 {
267 int ret;
268 uint32_t val;
269
270 if (wbuf_size != 0) {
271 ret = rpc_hf_wait_tend(target);
272 if (ret != ERROR_OK) {
273 LOG_ERROR("Xfer TEND timeout");
274 return ret;
275 }
276
277 /* Write calibration magic */
278 ret = target_write_u32(target, rpc_base + RPC_DRCR, 0x01FF0301);
279 if (ret != ERROR_OK)
280 return ret;
281
282 ret = target_write_u32(target, rpc_base + RPC_PHYCNT, 0x80030277);
283 if (ret != ERROR_OK)
284 return ret;
285
286 ret = target_write_memory(target, rpc_base | RPC_WBUF, 4,
287 wbuf_size / 4, wbuf);
288 if (ret != ERROR_OK)
289 return ret;
290
291 ret = clrsetbits_u32(target, rpc_base + RPC_CMNCR,
292 RPC_CMNCR_MD | RPC_CMNCR_BSZ(3),
293 RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
294 RPC_CMNCR_MD | RPC_CMNCR_BSZ(1));
295 if (ret != ERROR_OK)
296 return ret;
297 } else {
298 ret = rpc_hf_mode(target, 1);
299 if (ret != ERROR_OK)
300 return ret;
301 }
302
303 /* Submit HF address, SMCMR CMD[7] ~= CA Bit# 47 (R/nW) */
304 ret = target_write_u32(target, rpc_base + RPC_SMCMR,
305 write ? 0 : RPC_SMCMR_CMD(0x80));
306 if (ret != ERROR_OK)
307 return ret;
308
309 ret = target_write_u32(target, rpc_base + RPC_SMADR,
310 addr >> 1);
311 if (ret != ERROR_OK)
312 return ret;
313
314 ret = target_write_u32(target, rpc_base + RPC_SMOPR, 0x0);
315 if (ret != ERROR_OK)
316 return ret;
317
318 ret = target_write_u32(target, rpc_base + RPC_SMDRENR,
319 RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE |
320 RPC_SMDRENR_SPIDRE);
321 if (ret != ERROR_OK)
322 return ret;
323
324 val = RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |
325 RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |
326 (wbuf_size ? RPC_SMENR_OPDB(2) : 0) |
327 RPC_SMENR_CDE | RPC_SMENR_OCDE | RPC_SMENR_ADE(4) | size;
328
329 if (write) {
330 ret = target_write_u32(target, rpc_base + RPC_SMENR, val);
331 if (ret != ERROR_OK)
332 return ret;
333
334 if (wbuf_size == 0) {
335 buf_bswap32((uint8_t *)&wdata, (uint8_t *)&wdata, 4);
336 ret = target_write_u32(target, rpc_base + RPC_SMWDR0,
337 wdata);
338 if (ret != ERROR_OK)
339 return ret;
340 }
341
342 ret = target_write_u32(target, rpc_base + RPC_SMCR,
343 RPC_SMCR_SPIWE | RPC_SMCR_SPIE);
344 if (ret != ERROR_OK)
345 return ret;
346 } else {
347 val |= RPC_SMENR_DME;
348
349 ret = target_write_u32(target, rpc_base + RPC_SMDMCR,
350 RPC_SMDMCR_DMCYC(0xE));
351 if (ret != ERROR_OK)
352 return ret;
353
354 ret = target_write_u32(target, rpc_base + RPC_SMENR, val);
355 if (ret != ERROR_OK)
356 return ret;
357
358 ret = target_write_u32(target, rpc_base + RPC_SMCR,
359 RPC_SMCR_SPIRE | RPC_SMCR_SPIE);
360 if (ret != ERROR_OK)
361 return ret;
362
363 ret = rpc_hf_wait_tend(target);
364 if (ret != ERROR_OK)
365 return ret;
366
367 uint32_t val32;
368 ret = target_read_u32(target, rpc_base + RPC_SMRDR0, &val32);
369 if (ret != ERROR_OK)
370 return ret;
371 buf_bswap32((uint8_t *)&val32, (uint8_t *)&val32, 4);
372 *rdata = val32;
373 }
374
375 ret = rpc_hf_mode(target, 0);
376 if (ret != ERROR_OK)
377 LOG_ERROR("Xfer done TEND timeout");
378 return ret;
379 }
380
381 static int rpchf_target_write_memory(struct flash_bank *bank, target_addr_t addr,
382 uint32_t count, const uint8_t *buffer)
383 {
384 struct target *target = bank->target;
385 uint32_t wdata;
386
387 if (count != 2)
388 return ERROR_FAIL;
389
390 wdata = buffer[0] | (buffer[1] << 8);
391
392 return rpc_hf_xfer(target, addr, wdata, NULL, RPC_HF_SIZE_16BIT,
393 true, NULL, 0);
394 }
395
396 static int rpchf_target_read_memory(struct flash_bank *bank, target_addr_t addr,
397 uint32_t count, uint8_t *buffer)
398 {
399 struct target *target = bank->target;
400 uint32_t i, rdata;
401 int ret;
402
403 for (i = 0; i < count; i++) {
404 ret = rpc_hf_xfer(target, addr + (2 * i), 0, &rdata,
405 RPC_HF_SIZE_16BIT, false, NULL, 0);
406 if (ret != ERROR_OK)
407 return ret;
408 buffer[(2 * i) + 0] = rdata & 0xff;
409 buffer[(2 * i) + 1] = (rdata >> 8) & 0xff;
410 }
411
412 return ERROR_OK;
413 }
414
415 FLASH_BANK_COMMAND_HANDLER(rpchf_flash_bank_command)
416 {
417 struct cfi_flash_bank *cfi_info;
418 int ret;
419
420 ret = cfi_flash_bank_cmd(bank, CMD_ARGC, CMD_ARGV);
421 if (ret != ERROR_OK)
422 return ret;
423
424 cfi_info = bank->driver_priv;
425 cfi_info->read_mem = rpchf_target_read_memory;
426 cfi_info->write_mem = rpchf_target_write_memory;
427
428 return ERROR_OK;
429 }
430
431 static int rpchf_spansion_write_words(struct flash_bank *bank, const uint8_t *word,
432 uint32_t wordcount, uint32_t address)
433 {
434 int retval;
435 struct cfi_flash_bank *cfi_info = bank->driver_priv;
436 struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;
437
438 /* Calculate buffer size and boundary mask
439 * buffersize is (buffer size per chip) * (number of chips)
440 * bufferwsize is buffersize in words */
441 uint32_t buffersize = RPC_WBUF_SIZE;
442 uint32_t buffermask = buffersize - 1;
443 uint32_t bufferwsize = buffersize / 2;
444
445 /* Check for valid range */
446 if (address & buffermask) {
447 LOG_ERROR("Write address at base " TARGET_ADDR_FMT
448 ", address 0x%" PRIx32 " not aligned to 2^%d boundary",
449 bank->base, address, cfi_info->max_buf_write_size);
450 return ERROR_FLASH_OPERATION_FAILED;
451 }
452
453 /* Check for valid size */
454 if (wordcount > bufferwsize) {
455 LOG_ERROR("Number of data words %" PRIu32 " exceeds available buffersize %"
456 PRIu32, wordcount, buffersize);
457 return ERROR_FLASH_OPERATION_FAILED;
458 }
459
460 /* Unlock */
461 retval = cfi_spansion_unlock_seq(bank);
462 if (retval != ERROR_OK)
463 return retval;
464
465 retval = cfi_send_command(bank, 0xa0, cfi_flash_address(bank, 0, pri_ext->_unlock1));
466 if (retval != ERROR_OK)
467 return retval;
468
469 retval = rpc_hf_xfer(bank->target, address, 0, NULL, RPC_HF_SIZE_64BIT, true, word, wordcount * 2);
470 if (retval != ERROR_OK)
471 return retval;
472
473 if (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) {
474 retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));
475 if (retval != ERROR_OK)
476 return retval;
477
478 LOG_ERROR("couldn't write block at base " TARGET_ADDR_FMT
479 ", address 0x%" PRIx32 ", size 0x%" PRIx32, bank->base, address,
480 bufferwsize);
481 return ERROR_FLASH_OPERATION_FAILED;
482 }
483
484 return ERROR_OK;
485 }
486
487 static int rpchf_write_words(struct flash_bank *bank, const uint8_t *word,
488 uint32_t wordcount, uint32_t address)
489 {
490 return rpchf_spansion_write_words(bank, word, wordcount, address);
491 }
492
493 static int rpchf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
494 {
495 struct cfi_flash_bank *cfi_info = bank->driver_priv;
496 uint32_t address = bank->base + offset; /* address of first byte to be programmed */
497 uint32_t write_p;
498 int align; /* number of unaligned bytes */
499 uint8_t current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being
500 *programmed */
501 int retval;
502
503 if (bank->target->state != TARGET_HALTED) {
504 LOG_ERROR("Target not halted");
505 return ERROR_TARGET_NOT_HALTED;
506 }
507
508 if (offset + count > bank->size)
509 return ERROR_FLASH_DST_OUT_OF_BANK;
510
511 if (cfi_info->qry[0] != 'Q')
512 return ERROR_FLASH_BANK_NOT_PROBED;
513
514 /* start at the first byte of the first word (bus_width size) */
515 write_p = address & ~(bank->bus_width - 1);
516 align = address - write_p;
517 if (align != 0) {
518 LOG_INFO("Fixup %d unaligned head bytes", align);
519
520 /* read a complete word from flash */
521 retval = cfi_target_read_memory(bank, write_p, 1, current_word);
522 if (retval != ERROR_OK)
523 return retval;
524
525 /* replace only bytes that must be written */
526 for (unsigned int i = align; (i < bank->bus_width) && (count > 0); i++, count--) {
527 if (cfi_info->data_swap)
528 /* data bytes are swapped (reverse endianness) */
529 current_word[bank->bus_width - i] = *buffer++;
530 else
531 current_word[i] = *buffer++;
532 }
533
534 retval = cfi_write_word(bank, current_word, write_p);
535 if (retval != ERROR_OK)
536 return retval;
537 write_p += bank->bus_width;
538 }
539
540 /* Calculate buffer size and boundary mask
541 * buffersize is (buffer size per chip) * (number of chips)
542 * bufferwsize is buffersize in words */
543 uint32_t buffersize = RPC_WBUF_SIZE;
544 uint32_t buffermask = buffersize-1;
545 uint32_t bufferwsize = buffersize / bank->bus_width;
546
547 /* fall back to memory writes */
548 while (count >= (uint32_t)bank->bus_width) {
549 bool fallback;
550 if ((write_p & 0xff) == 0) {
551 LOG_INFO("Programming at 0x%08" PRIx32 ", count 0x%08"
552 PRIx32 " bytes remaining", write_p, count);
553 }
554 fallback = true;
555 if ((bufferwsize > 0) && (count >= buffersize) &&
556 !(write_p & buffermask)) {
557 retval = rpchf_write_words(bank, buffer, bufferwsize, write_p);
558 if (retval == ERROR_OK) {
559 buffer += buffersize;
560 write_p += buffersize;
561 count -= buffersize;
562 fallback = false;
563 } else if (retval != ERROR_FLASH_OPER_UNSUPPORTED)
564 return retval;
565 }
566 /* try the slow way? */
567 if (fallback) {
568 for (unsigned int i = 0; i < bank->bus_width; i++)
569 current_word[i] = *buffer++;
570
571 retval = cfi_write_word(bank, current_word, write_p);
572 if (retval != ERROR_OK)
573 return retval;
574
575 write_p += bank->bus_width;
576 count -= bank->bus_width;
577 }
578 }
579
580 /* return to read array mode, so we can read from flash again for padding */
581 retval = cfi_reset(bank);
582 if (retval != ERROR_OK)
583 return retval;
584
585 /* handle unaligned tail bytes */
586 if (count > 0) {
587 LOG_INFO("Fixup %" PRIu32 " unaligned tail bytes", count);
588
589 /* read a complete word from flash */
590 retval = cfi_target_read_memory(bank, write_p, 1, current_word);
591 if (retval != ERROR_OK)
592 return retval;
593
594 /* replace only bytes that must be written */
595 for (unsigned int i = 0; (i < bank->bus_width) && (count > 0); i++, count--)
596 if (cfi_info->data_swap)
597 /* data bytes are swapped (reverse endianness) */
598 current_word[bank->bus_width - i] = *buffer++;
599 else
600 current_word[i] = *buffer++;
601
602 retval = cfi_write_word(bank, current_word, write_p);
603 if (retval != ERROR_OK)
604 return retval;
605 }
606
607 /* return to read array mode */
608 return cfi_reset(bank);
609 }
610
611 static int rpchf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
612 {
613 struct cfi_flash_bank *cfi_info = bank->driver_priv;
614 struct target *target = bank->target;
615
616 LOG_DEBUG("reading buffer of %" PRIu32 " byte at 0x%8.8" PRIx32,
617 count, offset);
618
619 if (bank->target->state != TARGET_HALTED) {
620 LOG_ERROR("Target not halted");
621 return ERROR_TARGET_NOT_HALTED;
622 }
623
624 if (offset + count > bank->size)
625 return ERROR_FLASH_DST_OUT_OF_BANK;
626
627 if (cfi_info->qry[0] != 'Q')
628 return ERROR_FLASH_BANK_NOT_PROBED;
629
630 return target_read_memory(target, offset | mem_base,
631 4, count / 4, buffer);
632 }
633
634 const struct flash_driver renesas_rpchf_flash = {
635 .name = "rpchf",
636 .flash_bank_command = rpchf_flash_bank_command,
637 .erase = cfi_erase,
638 .protect = cfi_protect,
639 .write = rpchf_write,
640 .read = rpchf_read,
641 .probe = cfi_probe,
642 .auto_probe = cfi_auto_probe,
643 .erase_check = default_flash_blank_check,
644 .protect_check = cfi_protect_check,
645 .info = cfi_get_info,
646 .free_driver_priv = default_flash_free_driver_priv,
647 };

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)