target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / flash / nor / eneispif.c
blob6572b8c25bf61918dfb10134c951f21ced635d2d
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /*
4 * Copyright (c) 2024 ENE Technology Inc.
5 * steven@ene.com.tw
6 */
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
12 #include <helper/time_support.h>
13 #include <helper/bits.h>
14 #include <target/target.h>
15 #include <flash/nor/core.h>
16 #include <flash/nor/driver.h>
17 #include <flash/nor/spi.h>
19 #define ISPICFG 0x0000
20 #define ISPISTS 0x0004
21 #define ISPIADDR 0x0008
22 #define ISPICMD 0x000C
23 #define ISPIDAT 0x0100
25 #define ISPISTS_BUSY BIT(0)
26 #define STATUS1_QE BIT(1)
28 #define CFG_READ 0x372
29 #define CFG_WRITE 0x371
31 #define ISPI_CTRL_BASE 0x50101000
33 /* name read qread page erase chip device_id page erase flash
34 * _cmd _cmd _prog _cmd* _erase size size* size
35 * _cmd _cmd
37 struct flash_device ene_flash_device =
38 FLASH_ID("ISPI flash", 0x03, 0x00, 0x02, 0x20, 0x60, 0x00132085, 0x100, 0x1000, 0x80000);
40 struct eneispif_flash_bank {
41 bool probed;
42 target_addr_t ctrl_base;
43 uint32_t dev_id;
44 const struct flash_device *dev;
47 FLASH_BANK_COMMAND_HANDLER(eneispif_flash_bank_command)
49 struct eneispif_flash_bank *eneispif_info;
51 LOG_DEBUG("%s", __func__);
53 if (CMD_ARGC < 6)
54 return ERROR_COMMAND_SYNTAX_ERROR;
56 eneispif_info = malloc(sizeof(struct eneispif_flash_bank));
57 if (!eneispif_info) {
58 LOG_ERROR("not enough memory");
59 return ERROR_FAIL;
62 bank->driver_priv = eneispif_info;
63 eneispif_info->probed = false;
64 eneispif_info->ctrl_base = ISPI_CTRL_BASE;
65 if (CMD_ARGC >= 7) {
66 COMMAND_PARSE_ADDRESS(CMD_ARGV[6], eneispif_info->ctrl_base);
67 LOG_INFO("ASSUMING ISPI device at ctrl_base = " TARGET_ADDR_FMT,
68 eneispif_info->ctrl_base);
71 return ERROR_OK;
74 static int eneispif_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)
76 struct target *target = bank->target;
77 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
79 int result = target_read_u32(target, eneispif_info->ctrl_base + address, value);
80 if (result != ERROR_OK) {
81 LOG_ERROR("%s error at " TARGET_ADDR_FMT, __func__,
82 eneispif_info->ctrl_base + address);
83 return result;
85 LOG_DEBUG("Read address " TARGET_ADDR_FMT " = 0x%" PRIx32,
86 eneispif_info->ctrl_base + address, *value);
87 return ERROR_OK;
90 static int eneispif_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)
92 struct target *target = bank->target;
93 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
95 LOG_DEBUG("Write address " TARGET_ADDR_FMT " = 0x%" PRIx32,
96 eneispif_info->ctrl_base + address, value);
97 int result = target_write_u32(target, eneispif_info->ctrl_base + address, value);
98 if (result != ERROR_OK) {
99 LOG_ERROR("%s error writing 0x%" PRIx32 " to " TARGET_ADDR_FMT, __func__,
100 value, eneispif_info->ctrl_base + address);
101 return result;
103 return ERROR_OK;
106 static int eneispif_wait(struct flash_bank *bank)
108 int64_t start = timeval_ms();
110 while (1) {
111 uint32_t status;
113 if (eneispif_read_reg(bank, &status, ISPISTS) != ERROR_OK)
114 return ERROR_FAIL;
116 if (!(status & ISPISTS_BUSY))
117 break;
119 int64_t now = timeval_ms();
120 if (now - start > 1000) {
121 LOG_ERROR("Busy more than 1000ms.");
122 return ERROR_TARGET_TIMEOUT;
126 return ERROR_OK;
129 static int eneispi_erase_sector(struct flash_bank *bank, int sector)
131 int retval = ERROR_OK;
132 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
133 uint32_t offset;
134 uint32_t conf;
136 retval = eneispif_read_reg(bank, &conf, ISPICFG);
137 if (retval != ERROR_OK)
138 return retval;
140 offset = bank->sectors[sector].offset;
141 retval = eneispif_write_reg(bank, ISPIADDR, offset); /* Address */
142 if (retval != ERROR_OK)
143 goto done;
145 eneispif_write_reg(bank, ISPICFG, CFG_WRITE); /* Cmmmand enable */
146 eneispif_write_reg(bank, ISPICMD, SPIFLASH_WRITE_ENABLE); /* Write enable */
147 retval = eneispif_write_reg(bank, ISPICMD, eneispif_info->dev->erase_cmd); /* Erase page */
148 if (retval != ERROR_OK)
149 goto done;
151 retval = eneispif_wait(bank);
152 if (retval != ERROR_OK)
153 goto done;
155 done:
156 eneispif_write_reg(bank, ISPICFG, conf); /* restore */
157 return retval;
160 static int eneispif_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
162 struct target *target = bank->target;
163 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
164 int retval = ERROR_OK;
166 LOG_DEBUG("%s: from sector %u to sector %u", __func__, first, last);
168 if (target->state != TARGET_HALTED) {
169 LOG_ERROR("Target not halted");
170 return ERROR_TARGET_NOT_HALTED;
173 if (last < first || last >= bank->num_sectors) {
174 LOG_ERROR("Flash sector invalid");
175 return ERROR_FLASH_SECTOR_INVALID;
178 if (!(eneispif_info->probed)) {
179 LOG_ERROR("Flash bank not probed");
180 return ERROR_FLASH_BANK_NOT_PROBED;
183 for (unsigned int sector = first; sector <= last; sector++) {
184 if (bank->sectors[sector].is_protected) {
185 LOG_ERROR("Flash sector %u protected", sector);
186 return ERROR_FAIL;
190 if (eneispif_info->dev->erase_cmd == 0x00)
191 return ERROR_FLASH_OPER_UNSUPPORTED;
193 for (unsigned int sector = first; sector <= last; sector++) {
194 retval = eneispi_erase_sector(bank, sector);
195 if (retval != ERROR_OK)
196 break;
199 return retval;
202 static int eneispif_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
204 for (unsigned int sector = first; sector <= last; sector++)
205 bank->sectors[sector].is_protected = set;
207 return ERROR_OK;
210 static int eneispif_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
211 uint32_t count)
213 struct target *target = bank->target;
214 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
215 uint32_t page_size;
216 uint32_t conf;
217 int retval = ERROR_OK;
219 LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32 " count=0x%08" PRIx32, bank->size, offset,
220 count);
222 if (target->state != TARGET_HALTED) {
223 LOG_ERROR("Target not halted");
224 return ERROR_TARGET_NOT_HALTED;
227 if (offset + count > eneispif_info->dev->size_in_bytes) {
228 LOG_WARNING("Write past end of flash. Extra data discarded.");
229 count = eneispif_info->dev->size_in_bytes - offset;
232 /* Check sector protection */
233 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
234 /* Start offset in or before this sector? */
235 /* End offset in or behind this sector? */
236 if ((offset < (bank->sectors[sector].offset + bank->sectors[sector].size)) &&
237 ((offset + count - 1) >= bank->sectors[sector].offset) &&
238 bank->sectors[sector].is_protected) {
239 LOG_ERROR("Flash sector %u protected", sector);
240 return ERROR_FAIL;
244 retval = eneispif_read_reg(bank, &conf, ISPICFG);
245 if (retval != ERROR_OK)
246 return retval;
248 eneispif_write_reg(bank, ISPICFG, CFG_WRITE); // Cmmmand enable
250 /* If no valid page_size, use reasonable default. */
251 page_size =
252 eneispif_info->dev->pagesize ? eneispif_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
253 uint32_t page_offset = offset % page_size;
255 while (count > 0) {
256 uint32_t cur_count;
258 /* clip block at page boundary */
259 if (page_offset + count > page_size)
260 cur_count = page_size - page_offset;
261 else
262 cur_count = count;
264 eneispif_write_reg(bank, ISPICMD, SPIFLASH_WRITE_ENABLE); /* Write enable */
265 target_write_buffer(target, eneispif_info->ctrl_base + ISPIDAT, cur_count, buffer);
266 eneispif_write_reg(bank, ISPIADDR, offset);
267 retval = eneispif_write_reg(bank, ISPICMD,
268 (cur_count << 16) | eneispif_info->dev->pprog_cmd);
269 if (retval != ERROR_OK)
270 goto err;
272 page_offset = 0;
273 buffer += cur_count;
274 offset += cur_count;
275 count -= cur_count;
276 retval = eneispif_wait(bank);
277 if (retval != ERROR_OK)
278 goto err;
281 err:
282 eneispif_write_reg(bank, ISPICFG, conf); /* restore */
283 return retval;
286 /* Return ID of flash device */
287 /* On exit, SW mode is kept */
288 static int eneispif_read_flash_id(struct flash_bank *bank, uint32_t *id)
290 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
291 struct target *target = bank->target;
292 int retval;
293 uint32_t conf, value;
294 uint8_t buffer[4];
296 if (target->state != TARGET_HALTED) {
297 LOG_ERROR("Target not halted");
298 return ERROR_TARGET_NOT_HALTED;
301 retval = eneispif_read_reg(bank, &conf, ISPICFG);
302 if (retval != ERROR_OK)
303 return retval;
305 LOG_DEBUG("ISPCFG = (0x%08" PRIx32 ")", conf);
307 /* read ID from Receive Register */
308 eneispif_write_reg(bank, ISPICFG, CFG_WRITE); /* Cmmmand enable */
309 retval = eneispif_write_reg(bank, ISPICMD, (3 << 16) | SPIFLASH_READ_ID);
310 if (retval != ERROR_OK)
311 goto done;
313 retval = eneispif_wait(bank);
314 if (retval != ERROR_OK)
315 goto done;
317 retval = target_read_buffer(target, eneispif_info->ctrl_base + ISPIDAT, 3, buffer);
318 if (retval != ERROR_OK)
319 goto done;
320 value = (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
321 LOG_DEBUG("ISPDAT = (0x%08" PRIx32 ")", value);
323 *id = value;
324 done:
325 eneispif_write_reg(bank, ISPICFG, conf); // restore
326 return retval;
329 static int eneispif_probe(struct flash_bank *bank)
331 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
332 struct flash_sector *sectors;
333 uint32_t id;
334 int retval;
335 uint32_t sectorsize;
337 if (eneispif_info->probed)
338 free(bank->sectors);
340 eneispif_info->probed = false;
342 LOG_INFO("Assuming ISPI flash at address " TARGET_ADDR_FMT
343 " with controller at " TARGET_ADDR_FMT,
344 bank->base, eneispif_info->ctrl_base);
346 eneispif_write_reg(bank, ISPICFG, CFG_READ); /* RAM map enable */
348 retval = eneispif_read_flash_id(bank, &id);
349 if (retval != ERROR_OK)
350 return retval;
352 eneispif_info->dev_id = id;
353 eneispif_info->dev = &ene_flash_device;
355 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", eneispif_info->dev->name,
356 eneispif_info->dev_id);
358 /* Set correct size value */
359 bank->size = eneispif_info->dev->size_in_bytes;
361 if (bank->size <= (1UL << 16))
362 LOG_WARNING("device needs 2-byte addresses - not implemented");
364 /* if no sectors, treat whole bank as single sector */
365 sectorsize = eneispif_info->dev->sectorsize ? eneispif_info->dev->sectorsize
366 : eneispif_info->dev->size_in_bytes;
368 /* create and fill sectors array */
369 bank->num_sectors = eneispif_info->dev->size_in_bytes / sectorsize;
370 sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
371 if (!sectors) {
372 LOG_ERROR("not enough memory");
373 return ERROR_FAIL;
376 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
377 sectors[sector].offset = sector * sectorsize;
378 sectors[sector].size = sectorsize;
379 sectors[sector].is_erased = -1;
380 sectors[sector].is_protected = 0;
383 bank->sectors = sectors;
384 eneispif_info->probed = true;
385 return ERROR_OK;
388 static int eneispif_auto_probe(struct flash_bank *bank)
390 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
391 if (eneispif_info->probed)
392 return ERROR_OK;
393 return eneispif_probe(bank);
396 static int eneispif_protect_check(struct flash_bank *bank)
398 /* Nothing to do. Protection is only handled in SW. */
399 return ERROR_OK;
402 static int get_eneispif_info(struct flash_bank *bank, struct command_invocation *cmd)
404 struct eneispif_flash_bank *eneispif_info = bank->driver_priv;
406 if (!(eneispif_info->probed)) {
407 command_print(cmd, "ENE ISPI flash bank not probed yet.");
408 return ERROR_OK;
411 command_print(cmd,
412 "ENE ISPI flash information:\n"
413 " Device \'%s\' (ID 0x%08" PRIx32 ")",
414 eneispif_info->dev->name, eneispif_info->dev_id);
416 return ERROR_OK;
419 const struct flash_driver eneispif_flash = {
420 .name = "eneispif",
421 .usage = "flash bank <name> 'eneispif' <base_address> <size> 0 0 <target> <ctrl_base>",
422 .flash_bank_command = eneispif_flash_bank_command,
423 .erase = eneispif_erase,
424 .protect = eneispif_protect,
425 .write = eneispif_write,
426 .read = default_flash_read,
427 .probe = eneispif_probe,
428 .auto_probe = eneispif_auto_probe,
429 .erase_check = default_flash_blank_check,
430 .protect_check = eneispif_protect_check,
431 .info = get_eneispif_info,
432 .free_driver_priv = default_flash_free_driver_priv,