build: cleanup src/flash/nand directory
[fw/openocd] / src / flash / nor / virtual.c
1 /***************************************************************************
2  *   Copyright (C) 2010 by Spencer Oliver                                  *
3  *   spen@spen-soft.co.uk                                                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "imp.h"
25
26 static struct flash_bank* virtual_get_master_bank(struct flash_bank *bank)
27 {
28         struct flash_bank* master_bank;
29
30         master_bank = get_flash_bank_by_name_noprobe(bank->driver_priv);
31         if (master_bank == NULL) {
32                 LOG_ERROR("master flash bank '%s' does not exist", (char*)bank->driver_priv);
33         }
34
35         return master_bank;
36 }
37
38 static void virtual_update_bank_info(struct flash_bank *bank)
39 {
40         struct flash_bank *master_bank = virtual_get_master_bank(bank);
41
42         if (master_bank == NULL) {
43                 return;
44         }
45
46         /* update the info we do not have */
47         bank->size = master_bank->size;
48         bank->chip_width = master_bank->chip_width;
49         bank->bus_width = master_bank->bus_width;
50         bank->num_sectors = master_bank->num_sectors;
51         bank->sectors = master_bank->sectors;
52 }
53
54 FLASH_BANK_COMMAND_HANDLER(virtual_flash_bank_command)
55 {
56         if (CMD_ARGC < 7)
57         {
58                 return ERROR_COMMAND_SYNTAX_ERROR;
59         }
60
61         /* get the master flash bank */
62         const char *bank_name = CMD_ARGV[6];
63         struct flash_bank *master_bank = get_flash_bank_by_name_noprobe(bank_name);
64
65         if (master_bank == NULL)
66         {
67                 LOG_ERROR("master flash bank '%s' does not exist", bank_name);
68                 return ERROR_FLASH_OPERATION_FAILED;
69         }
70
71         /* save master bank name - use this to get settings later */
72         bank->driver_priv = strdup(bank_name);
73
74         return ERROR_OK;
75 }
76
77 static int virtual_protect(struct flash_bank *bank, int set, int first, int last)
78 {
79         struct flash_bank *master_bank = virtual_get_master_bank(bank);
80         int retval;
81
82         if (master_bank == NULL) {
83                 return ERROR_FLASH_OPERATION_FAILED;
84         }
85
86         /* call master handler */
87         if ((retval = master_bank->driver->protect(master_bank, set,
88                         first, last)) != ERROR_OK)
89                 return retval;
90
91         return ERROR_OK;
92 }
93
94 static int virtual_protect_check(struct flash_bank *bank)
95 {
96         struct flash_bank *master_bank = virtual_get_master_bank(bank);
97         int retval;
98
99         if (master_bank == NULL) {
100                 return ERROR_FLASH_OPERATION_FAILED;
101         }
102
103         /* call master handler */
104         if ((retval = master_bank->driver->protect_check(master_bank)) != ERROR_OK)
105                 return retval;
106
107         return ERROR_OK;
108 }
109
110 static int virtual_erase(struct flash_bank *bank, int first, int last)
111 {
112         struct flash_bank *master_bank = virtual_get_master_bank(bank);
113         int retval;
114
115         if (master_bank == NULL) {
116                 return ERROR_FLASH_OPERATION_FAILED;
117         }
118
119         /* call master handler */
120         if ((retval = master_bank->driver->erase(master_bank,
121                         first, last)) != ERROR_OK)
122                 return retval;
123
124         return ERROR_OK;
125 }
126
127 static int virtual_write(struct flash_bank *bank, uint8_t *buffer,
128                 uint32_t offset, uint32_t count)
129 {
130         struct flash_bank *master_bank = virtual_get_master_bank(bank);
131         int retval;
132
133         if (master_bank == NULL) {
134                 return ERROR_FLASH_OPERATION_FAILED;
135         }
136
137         /* call master handler */
138         if ((retval = master_bank->driver->write(master_bank, buffer,
139                         offset, count)) != ERROR_OK)
140                 return retval;
141
142         return ERROR_OK;
143 }
144
145 static int virtual_probe(struct flash_bank *bank)
146 {
147         struct flash_bank *master_bank = virtual_get_master_bank(bank);
148         int retval;
149
150         if (master_bank == NULL) {
151                 return ERROR_FLASH_OPERATION_FAILED;
152         }
153
154         /* call master handler */
155         if ((retval = master_bank->driver->probe(master_bank)) != ERROR_OK)
156                 return retval;
157
158         /* update the info we do not have */
159         virtual_update_bank_info(bank);
160
161         return ERROR_OK;
162 }
163
164 static int virtual_auto_probe(struct flash_bank *bank)
165 {
166         struct flash_bank *master_bank = virtual_get_master_bank(bank);
167         int retval;
168
169         if (master_bank == NULL) {
170                 return ERROR_FLASH_OPERATION_FAILED;
171         }
172
173         /* call master handler */
174         if ((retval = master_bank->driver->auto_probe(master_bank)) != ERROR_OK)
175                 return retval;
176
177         /* update the info we do not have */
178         virtual_update_bank_info(bank);
179
180         return ERROR_OK;
181 }
182
183 static int virtual_info(struct flash_bank *bank, char *buf, int buf_size)
184 {
185         struct flash_bank *master_bank = virtual_get_master_bank(bank);
186
187         if (master_bank == NULL) {
188                 return ERROR_FLASH_OPERATION_FAILED;
189         }
190
191         snprintf(buf, buf_size, "%s driver for flash bank %s at 0x%8.8" PRIx32 "",
192                         bank->driver->name, master_bank->name, master_bank->base);
193
194         return ERROR_OK;
195 }
196
197 static int virtual_blank_check(struct flash_bank *bank)
198 {
199         struct flash_bank *master_bank = virtual_get_master_bank(bank);
200         int retval;
201
202         if (master_bank == NULL) {
203                 return ERROR_FLASH_OPERATION_FAILED;
204         }
205
206         /* call master handler */
207         if ((retval = master_bank->driver->erase_check(master_bank)) != ERROR_OK)
208                 return retval;
209
210         return ERROR_OK;
211 }
212
213 static int virtual_flash_read(struct flash_bank *bank,
214                 uint8_t *buffer, uint32_t offset, uint32_t count)
215 {
216         struct flash_bank *master_bank = virtual_get_master_bank(bank);
217         int retval;
218
219         if (master_bank == NULL) {
220                 return ERROR_FLASH_OPERATION_FAILED;
221         }
222
223         /* call master handler */
224         if ((retval = master_bank->driver->read(master_bank, buffer,
225                         offset, count)) != ERROR_OK)
226                 return retval;
227
228         return ERROR_OK;
229 }
230
231 struct flash_driver virtual_flash = {
232         .name = "virtual",
233         .flash_bank_command = virtual_flash_bank_command,
234         .erase = virtual_erase,
235         .protect = virtual_protect,
236         .write = virtual_write,
237         .read = virtual_flash_read,
238         .probe = virtual_probe,
239         .auto_probe = virtual_auto_probe,
240         .erase_check = virtual_blank_check,
241         .protect_check = virtual_protect_check,
242         .info = virtual_info,
243 };