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");
70  retval = ERROR_TARGET_NOT_HALTED;
71  return retval;
72  }
73 
74  /* Perform write */
76  if (retval != ERROR_OK)
77  return retval;
78 
79  retval = target_write_memory(target, bank->base + offset, 4, count/4, buffer);
80  if (retval != ERROR_OK)
81  return retval;
82 
83  /* Close flash interface */
85  if (retval != ERROR_OK)
86  return retval;
87 
88  return ERROR_OK;
89 }
90 
91 static int swm050_probe(struct flash_bank *bank)
92 {
93  return ERROR_OK;
94 }
95 
96 static int swm050_mass_erase(struct flash_bank *bank)
97 {
98  struct target *target = bank->target;
99  int retval;
100 
101  if (target->state != TARGET_HALTED) {
102  LOG_ERROR("Target not halted");
104  }
105 
106  /* Perform mass erase */
107  retval = target_write_u32(target, SWM050_FLASH_REG1, 0x6);
108  if (retval != ERROR_OK)
109  return retval;
110  retval = target_write_u32(target, SWM050_FLASH_REG2, 0x1);
111  if (retval != ERROR_OK)
112  return retval;
113  retval = target_write_u32(target, 0x0, SWM050_FLASH_KEY);
114  if (retval != ERROR_OK)
115  return retval;
116 
118 
119  /* Close flash interface */
120  retval = target_write_u32(target, SWM050_FLASH_REG1, 0x0);
121  if (retval != ERROR_OK)
122  return retval;
123 
124  return ERROR_OK;
125 }
126 
127 COMMAND_HANDLER(swm050_handle_mass_erase_command)
128 {
129  if (CMD_ARGC < 1)
131 
132  struct flash_bank *bank;
133  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
134  if (retval != ERROR_OK)
135  return retval;
136 
137  retval = swm050_mass_erase(bank);
138  if (retval == ERROR_OK)
139  command_print(CMD, "swm050 mass erase complete");
140  else
141  command_print(CMD, "swm050 mass erase failed");
142 
143  return retval;
144 }
145 
146 FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
147 {
148  free(bank->sectors);
149  bank->write_start_alignment = 4;
150  bank->write_end_alignment = 4;
152 
153  bank->num_sectors = SWM050_FLASH_PAGES;
155  if (!bank->sectors)
156  return ERROR_FAIL;
157 
158  for (unsigned int i = 0; i < bank->num_sectors; i++)
159  bank->sectors[i].is_protected = 0;
160 
161  return ERROR_OK;
162 }
163 
164 static const struct command_registration swm050_exec_command_handlers[] = {
165  {
166  .name = "mass_erase",
167  .handler = swm050_handle_mass_erase_command,
168  .mode = COMMAND_EXEC,
169  .usage = "bank_id",
170  .help = "Erase entire flash device.",
171  },
173 };
174 
175 static const struct command_registration swm050_command_handlers[] = {
176  {
177  .name = "swm050",
178  .mode = COMMAND_ANY,
179  .help = "swm050 flash command group",
180  .usage = "",
182  },
184 };
185 
186 const struct flash_driver swm050_flash = {
187  .name = "swm050",
188  .commands = swm050_command_handlers,
189  .flash_bank_command = swm050_flash_bank_command,
190  .erase = swm050_erase,
191  .write = swm050_write,
192  .read = default_flash_read,
193  .probe = swm050_probe,
194  .auto_probe = swm050_probe,
195  .erase_check = default_flash_blank_check,
196  .free_driver_priv = default_flash_free_driver_priv,
197 };
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:118
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
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:456
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_OK
Definition: log.h:164
const char * name
Definition: command.h:235
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:116
enum target_state state
Definition: target.h:157
static int swm050_mass_erase(struct flash_bank *bank)
Definition: swm050.c:96
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:186
FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
Definition: swm050.c:146
static const struct command_registration swm050_command_handlers[]
Definition: swm050.c:175
#define SWM050_FLASH_REG2
Definition: swm050.c:24
COMMAND_HANDLER(swm050_handle_mass_erase_command)
Definition: swm050.c:127
static const struct command_registration swm050_exec_command_handlers[]
Definition: swm050.c:164
#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:91
#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:1265
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22