2 * Copyright © 2011 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 #include <ao_storage.h>
23 ao_storage_read(ao_pos_t pos, void *buf, uint16_t len)
26 return ao_storage_device_read(pos, buf, len);
32 if (pos >= ao_storage_total || pos + len > ao_storage_total)
36 /* Compute portion of transfer within
39 this_off = (uint16_t) pos & (ao_storage_unit - 1);
40 this_len = ao_storage_unit - this_off;
44 if (!ao_storage_device_read(pos, buf, this_len))
47 /* See how much is left */
57 ao_storage_write(ao_pos_t pos, void *buf, uint16_t len)
60 return ao_storage_device_write(pos, buf, len);
66 if (pos >= ao_storage_total || pos + len > ao_storage_total)
70 /* Compute portion of transfer within
73 this_off = (uint16_t) pos & (ao_storage_unit - 1);
74 this_len = ao_storage_unit - this_off;
78 if (!ao_storage_device_write(pos, buf, this_len))
81 /* See how much is left */
90 static uint8_t storage_data[128];
99 if (ao_cmd_status != ao_cmd_success)
101 for (i = 0; ; i += 8) {
102 if (ao_storage_read((block << 8) + i,
105 ao_cmd_put16((uint16_t) i);
106 for (j = 0; j < 8; j++) {
108 ao_cmd_put8(storage_data[j]);
117 #if HAS_STORAGE_DEBUG
119 /* not enough space for this today
122 ao_storage_store(void)
130 block = ao_cmd_hex();
132 addr = ((uint32_t) block << 8) | i;
134 if (ao_cmd_status != ao_cmd_success)
137 b = ao_cmd_hexbyte();
138 if (ao_cmd_status != ao_cmd_success)
140 ao_storage_write(addr, &b, 1);
149 uint32_t v = ao_cmd_hex();
150 if (ao_cmd_status != ao_cmd_success)
152 ao_storage_erase((uint32_t) v << 8);
156 ao_storage_zapall(void)
161 if (!ao_match_word("DoIt"))
163 for (pos = 0; pos < ao_storage_log_max; pos += ao_storage_block)
164 ao_storage_erase(pos);
170 ao_storage_failure(uint32_t pos, char *format, ...)
173 printf("TEST FAILURE AT %08x: ", pos);
180 ao_storage_check_block(uint32_t pos, uint8_t value)
185 for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) {
186 if (!ao_storage_read(pos + offset, storage_data, sizeof (storage_data))) {
187 ao_storage_failure(pos + offset, "read failed\n");
190 for (byte = 0; byte < sizeof (storage_data); byte++)
191 if (storage_data[byte] != value) {
192 ao_storage_failure(pos + offset + byte,
193 "want %02x got %02x\n",
194 value, storage_data[byte]);
202 ao_storage_fill_block(uint32_t pos, uint8_t value)
207 for (byte = 0; byte < sizeof (storage_data); byte++)
208 storage_data[byte] = value;
209 for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) {
210 if (!ao_storage_write(pos + offset, storage_data, sizeof (storage_data))) {
211 ao_storage_failure(pos + offset, "write failed\n");
219 ao_storage_check_incr_block(uint32_t pos)
224 for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) {
225 if (!ao_storage_read(pos + offset, storage_data, sizeof (storage_data))) {
226 ao_storage_failure(pos + offset, "read failed\n");
229 for (byte = 0; byte < sizeof (storage_data); byte++) {
230 uint8_t value = offset + byte;
231 if (storage_data[byte] != value) {
232 ao_storage_failure(pos + offset + byte,
233 "want %02x got %02x\n",
234 value, storage_data[byte]);
243 ao_storage_fill_incr_block(uint32_t pos)
248 for (offset = 0; offset < ao_storage_block; offset += sizeof (storage_data)) {
249 for (byte = 0; byte < sizeof (storage_data); byte++)
250 storage_data[byte] = offset + byte;
251 if (!ao_storage_write(pos + offset, storage_data, sizeof (storage_data))) {
252 ao_storage_failure(pos + offset, "write failed\n");
260 ao_storage_fill_check_block(uint32_t pos, uint8_t value)
262 return ao_storage_fill_block(pos, value) && ao_storage_check_block(pos, value);
266 ao_storage_incr_check_block(uint32_t pos)
268 return ao_storage_fill_incr_block(pos) && ao_storage_check_incr_block(pos);
272 ao_storage_test_block(uint32_t pos)
274 ao_storage_erase(pos);
275 printf(" erase"); flush();
276 if (!ao_storage_check_block(pos, 0xff))
278 printf(" zero"); flush();
279 if (!ao_storage_fill_check_block(pos, 0x00))
281 ao_storage_erase(pos);
282 printf(" 0xaa"); flush();
283 if (!ao_storage_fill_check_block(pos, 0xaa))
285 ao_storage_erase(pos);
286 printf(" 0x55"); flush();
287 if (!ao_storage_fill_check_block(pos, 0x55))
289 ao_storage_erase(pos);
290 printf(" increment"); flush();
291 if (!ao_storage_incr_check_block(pos))
293 ao_storage_erase(pos);
294 printf(" pass\n"); flush();
299 ao_storage_test(void)
304 if (!ao_match_word("DoIt"))
306 for (pos = 0; pos < ao_storage_log_max; pos += ao_storage_block) {
307 printf("Testing block 0x%08x:", pos); flush();
308 if (!ao_storage_test_block(pos))
311 printf("Test complete\n");
313 #endif /* AO_STORAGE_TEST */
316 ao_storage_info(void)
319 printf("Storage size: %ld\n", (long) ao_storage_total);
320 printf("Storage erase unit: %ld\n", (long) ao_storage_block);
321 ao_storage_device_info();
324 const struct ao_cmds ao_storage_cmds[] = {
325 { ao_storage_info, "f\0Show storage" },
326 { ao_storage_dump, "e <block>\0Dump flash" },
327 #if HAS_STORAGE_DEBUG
328 { ao_storage_store, "w <block> <start> <len> <data> ...\0Write data to flash" },
330 { ao_storage_zap, "z <block>\0Erase <block>" },
331 { ao_storage_zapall,"Z <key>\0Erase all. <key> is doit with D&I" },
333 { ao_storage_test, "V <key>\0Validate flash (destructive). <key> is doit with D&I" },
339 ao_storage_init(void)
341 ao_storage_device_init();
342 ao_cmd_register(&ao_storage_cmds[0]);