OpenOCD
swm050.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io> *
5  * Copyright (C) 2019 Caleb Szalacinski <contact@skiboy.net> *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include "imp.h"
13 #include <target/image.h>
14 
15 #define SWM050_DELAY 100
16 
17 #define SWM050_FLASH_PAGE_SIZE 0x200
18 #define SWM050_FLASH_PAGES 16
19 
20 #define SWM050_CPU_ID 0xE000ED00
21 #define SWM050_CPU_ID_VAL 0x410CC200
22 
23 #define SWM050_FLASH_REG1 0x1F000000
24 #define SWM050_FLASH_REG2 0x1F000038
25 #define SWM050_FLASH_KEY 0xAAAAAAAA
26 
27 #define SWM050_SYSCTL_CFG_0 0x400F0000
28 #define SWM050_SYSCTL_DBLF 0x400F0008
29 
30 static int swm050_erase(struct flash_bank *bank, unsigned int first,
31  unsigned int last)
32 {
33  struct target *target = bank->target;
34  int retval;
35 
36  if (target->state != TARGET_HALTED) {
37  LOG_ERROR("Target not halted");
39  }
40 
41  /* Perform erase */
43  if (retval != ERROR_OK)
44  return retval;
45 
46  for (unsigned int curr_page = first; curr_page <= last; curr_page++) {
47  uint32_t curr_addr = bank->base + (SWM050_FLASH_PAGE_SIZE * curr_page);
48  /* Perform write */
49  retval = target_write_u32(target, curr_addr, SWM050_FLASH_KEY);
50  if (retval != ERROR_OK)
51  return retval;
53  }
54 
55  /* Close flash interface */
57  if (retval != ERROR_OK)
58  return retval;
59 
60  return ERROR_OK;
61 }
62 
63 static int swm050_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
64 {
65  struct target *target = bank->target;
66  int retval;
67 
68  if (target->state != TARGET_HALTED) {
69  LOG_ERROR("Target not halted");
71  }
72 
73  /* Perform write */
75  if (retval != ERROR_OK)
76  return retval;
77 
78  retval = target_write_memory(target, bank->base + offset, 4, count/4, buffer);
79  if (retval != ERROR_OK)
80  return retval;
81 
82  /* Close flash interface */
84  if (retval != ERROR_OK)
85  return retval;
86 
87  return ERROR_OK;
88 }
89 
90 static int swm050_probe(struct flash_bank *bank)
91 {
92  return ERROR_OK;
93 }
94 
95 static int swm050_mass_erase(struct flash_bank *bank)
96 {
97  struct target *target = bank->target;
98  int retval;
99 
100  if (target->state != TARGET_HALTED) {
101  LOG_ERROR("Target not halted");
103  }
104 
105  /* Perform mass erase */
106  retval = target_write_u32(target, SWM050_FLASH_REG1, 0x6);
107  if (retval != ERROR_OK)
108  return retval;
109  retval = target_write_u32(target, SWM050_FLASH_REG2, 0x1);
110  if (retval != ERROR_OK)
111  return retval;
112  retval = target_write_u32(target, 0x0, SWM050_FLASH_KEY);
113  if (retval != ERROR_OK)
114  return retval;
115 
117 
118  /* Close flash interface */
119  retval = target_write_u32(target, SWM050_FLASH_REG1, 0x0);
120  if (retval != ERROR_OK)
121  return retval;
122 
123  return ERROR_OK;
124 }
125 
126 COMMAND_HANDLER(swm050_handle_mass_erase_command)
127 {
128  if (CMD_ARGC < 1)
130 
131  struct flash_bank *bank;
132  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
133  if (retval != ERROR_OK)
134  return retval;
135 
136  retval = swm050_mass_erase(bank);
137  if (retval == ERROR_OK)
138  command_print(CMD, "swm050 mass erase complete");
139  else
140  command_print(CMD, "swm050 mass erase failed");
141 
142  return retval;
143 }
144 
145 FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
146 {
147  free(bank->sectors);
148  bank->write_start_alignment = 4;
149  bank->write_end_alignment = 4;
151 
152  bank->num_sectors = SWM050_FLASH_PAGES;
154  if (!bank->sectors)
155  return ERROR_FAIL;
156 
157  for (unsigned int i = 0; i < bank->num_sectors; i++)
158  bank->sectors[i].is_protected = 0;
159 
160  return ERROR_OK;
161 }
162 
163 static const struct command_registration swm050_exec_command_handlers[] = {
164  {
165  .name = "mass_erase",
166  .handler = swm050_handle_mass_erase_command,
167  .mode = COMMAND_EXEC,
168  .usage = "bank_id",
169  .help = "Erase entire flash device.",
170  },
172 };
173 
174 static const struct command_registration swm050_command_handlers[] = {
175  {
176  .name = "swm050",
177  .mode = COMMAND_ANY,
178  .help = "swm050 flash command group",
179  .usage = "",
181  },
183 };
184 
185 const struct flash_driver swm050_flash = {
186  .name = "swm050",
187  .commands = swm050_command_handlers,
188  .flash_bank_command = swm050_flash_bank_command,
189  .erase = swm050_erase,
190  .write = swm050_write,
191  .read = default_flash_read,
192  .probe = swm050_probe,
193  .auto_probe = swm050_probe,
194  .erase_check = default_flash_blank_check,
195  .free_driver_priv = default_flash_free_driver_priv,
196 };
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:123
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint8_t bank
Definition: esirisc.c:135
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void alive_sleep(uint64_t ms)
Definition: log.c:478
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define ERROR_OK
Definition: log.h:182
const char * name
Definition: command.h:239
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Definition: target.h:119
enum target_state state
Definition: target.h:167
static int swm050_mass_erase(struct flash_bank *bank)
Definition: swm050.c:95
static int swm050_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: swm050.c:63
const struct flash_driver swm050_flash
Definition: swm050.c:185
FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
Definition: swm050.c:145
static const struct command_registration swm050_command_handlers[]
Definition: swm050.c:174
#define SWM050_FLASH_REG2
Definition: swm050.c:24
COMMAND_HANDLER(swm050_handle_mass_erase_command)
Definition: swm050.c:126
static const struct command_registration swm050_exec_command_handlers[]
Definition: swm050.c:163
#define SWM050_DELAY
Definition: swm050.c:15
#define SWM050_FLASH_PAGE_SIZE
Definition: swm050.c:17
#define SWM050_FLASH_REG1
Definition: swm050.c:23
#define SWM050_FLASH_KEY
Definition: swm050.c:25
static int swm050_probe(struct flash_bank *bank)
Definition: swm050.c:90
#define SWM050_FLASH_PAGES
Definition: swm050.c:18
static int swm050_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: swm050.c:30
int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Write count items of size bytes to the memory of target at the address given.
Definition: target.c:1288
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2635
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:817
@ TARGET_HALTED
Definition: target.h:58
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22