2
dev_flash_sst39lvf160.c - skyeye SST39LF/VF160 flash simulation
3
Copyright (C) 2007 Skyeye Develop Group
4
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
* 2007.04.03 Written by Anthony Lee
29
#include "skyeye_device.h"
30
#include "skyeye_flash.h"
31
#include "dev_flash_sst39lvf160.h"
33
#define FLASH_SST39LVF160_DEBUG 0
35
#define PRINT(x...) printf("[FLASH_SST39LVF160]: " x)
37
#if FLASH_SST39LVF160_DEBUG
38
#define DEBUG(x...) printf("[FLASH_SST39LVF160]: " x)
40
#define DEBUG(x...) (void)0
43
extern mem_bank_t *global_mbp;
44
extern mem_bank_t *bank_ptr(ARMword addr);
46
extern ARMword real_read_byte(ARMul_State*, ARMword);
47
extern ARMword real_read_halfword(ARMul_State*, ARMword);
48
extern ARMword real_read_word(ARMul_State*, ARMword);
49
extern void real_write_byte(ARMul_State*, ARMword, ARMword);
50
extern void real_write_halfword(ARMul_State*, ARMword, ARMword);
51
extern void real_write_word(ARMul_State*, ARMword, ARMword);
54
static void flash_sst39lvf160_fini(struct device_desc *dev)
56
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
63
static void flash_sst39lvf160_reset(struct device_desc *dev)
65
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
67
memset(io, 0, sizeof(struct flash_sst39lvf160_io));
68
io->dump_cnt = 0xffff;
72
static void flash_sst39lvf160_update(struct device_desc *dev)
74
struct flash_device *flash_dev = (struct flash_device*)dev->dev;
75
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
76
struct machine_config *mc = (struct machine_config*)dev->mach;
77
ARMul_State *state = (ARMul_State*)mc->state;
81
if (flash_dev->dump[0] == 0) return;
82
if (io->dump_flags == 0 || (io->dump_flags & 0x2) != 0) return;
86
if (io->dump_cnt == 0) {
87
if (skyeye_flash_dump(flash_dev->dump, dev->base, 0x200000) != 0) {
88
io->dump_flags |= 0x2;
90
PRINT("*** FAILED: Can't dump to %s\n", flash_dev->dump);
94
io->dump_cnt = 0xffff;
98
PRINT("Dumped to %s\n", flash_dev->dump);
103
static int flash_sst39lvf160_read_byte(struct device_desc *dev, uint32_t addr, uint8_t *data)
105
struct machine_config *mc = (struct machine_config*)dev->mach;
106
ARMul_State *state = (ARMul_State*)mc->state;
108
global_mbp = bank_ptr(addr);
109
*data = real_read_byte(state, addr);
111
DEBUG("read_byte(addr:0x%08x, data:0x%x)\n", addr, *data);
117
static int flash_sst39lvf160_write_byte(struct device_desc *dev, uint32_t addr, uint8_t data)
120
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
121
struct machine_config *mc = (struct machine_config*)dev->mach;
122
ARMul_State *state = (ARMul_State*)mc->state;
124
global_mbp = bank_ptr(addr);
125
real_write_byte(state, addr, data);
127
io->dump_flags |= 0x1;
129
DEBUG("write_byte(addr:0x%08x, data:0x%x)\n", addr, data);
133
PRINT("write_byte: Unsupported !!!\n");
139
static int flash_sst39lvf160_read_halfword(struct device_desc *dev, uint32_t addr, uint16_t *data)
141
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
142
struct machine_config *mc = (struct machine_config*)dev->mach;
143
ARMul_State *state = (ARMul_State*)mc->state;
144
uint32_t offset = (addr - dev->base) >> 1;
146
if (CMD_SOFTWARE_ID_ENTRY(io)) {
148
case 0: *data = 0xbf; break;
149
case 1: *data = 0x2782; break;
151
default: *data = 0x0; break;
155
if (CMD_CFI_QUERY_ENTRY(io)) {
157
/* CFI QUERY IDENTIFICATION STRING */
158
case 0x10: *data= 0x51; break;
159
case 0x11: *data= 0x52; break;
160
case 0x12: *data= 0x59; break;
161
case 0x13: *data= 0x1; break;
162
case 0x14: *data= 0x7; break;
163
case 0x15: *data= 0x0; break;
164
case 0x16: *data= 0x0; break;
165
case 0x17: *data= 0x0; break;
166
case 0x18: *data= 0x0; break;
167
case 0x19: *data= 0x0; break;
168
case 0x1a: *data= 0x0; break;
170
/* SYSTEM INTERFACE INFORMATION */
171
case 0x1b: *data= strcmp(dev->type, "SST39LF160") == 0 ? 0x30 : 0x27; break;
172
case 0x1c: *data= 0x36; break;
173
case 0x1d: *data= 0x0; break;
174
case 0x1e: *data= 0x0; break;
175
case 0x1f: *data= 0x4; break;
176
case 0x20: *data= 0x0; break;
177
case 0x21: *data= 0x4; break;
178
case 0x22: *data= 0x6; break;
179
case 0x23: *data= 0x1; break;
180
case 0x24: *data= 0x0; break;
181
case 0x25: *data= 0x1; break;
182
case 0x26: *data= 0x1; break;
184
/* DEVICE GEOMETRY INFORMATION */
185
case 0x27: *data= 0x15; break;
186
case 0x28: *data= 0x1; break;
187
case 0x29: *data= 0x0; break;
188
case 0x2a: *data= 0x0; break;
189
case 0x2b: *data= 0x0; break;
190
case 0x2c: *data= 0x2; break;
191
case 0x2d: *data= 0xff; break;
192
case 0x2e: *data= 0x1; break;
193
case 0x2f: *data= 0x10; break;
194
case 0x30: *data= 0x0; break;
195
case 0x31: *data= 0x1f; break;
196
case 0x32: *data= 0x0; break;
197
case 0x33: *data= 0x0; break;
198
case 0x34: *data= 0x1; break;
200
default: *data = 0x0; break;
205
/* read data from addr */
206
global_mbp = bank_ptr(addr);
207
*data = real_read_halfword(state, addr);
212
DEBUG("read_halfword(offset:0x%08x, data:0x%x)\n", offset, *data);
218
static int flash_sst39lvf160_write_halfword(struct device_desc *dev, uint32_t addr, uint16_t data)
220
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
221
struct machine_config *mc = (struct machine_config*)dev->mach;
222
ARMul_State *state = (ARMul_State*)mc->state;
223
uint32_t offset = (addr - dev->base) >> 1;
226
DEBUG("write_halfword(%dst Bus, offset:0x%08x, data:0x%x)\n", io->n_bus + 1, offset, data);
228
if (CMD_WORD_PROGRAM(io)) {
229
/* write data to addr */
230
global_mbp = bank_ptr(addr);
231
real_write_halfword(state, addr, data);
232
io->dump_flags |= 0x1;
238
case 0x10: /* Chip-Erase */
240
end = start + 0x200000;
243
case 0x30: /* Sector-Erase: 4KBytes/sector */
245
end = start + 0x1000;
248
case 0x50: /* Block-Erase: 64KBytes/block */
250
end = start + 0x10000;
258
if (end > start && end <= dev->base + 0x200000) {
259
for (addr = start; addr < end; addr += 4) {
260
global_mbp = bank_ptr(addr);
261
real_write_word(state, addr, 0xffffffff);
263
DEBUG("*** Erase(start:0x%08x, end:0x%08x)\n", start, end);
265
PRINT("*** ERROR: Erase(start:0x%08x, end:0x%08x)\n", start, end);
272
io->bus[io->n_bus].addr = offset;
273
io->bus[io->n_bus].data = data;
278
if (CMD_QUERY_EXIT(io)) goto reset;
284
io->cnt = io->n_bus = 0;
285
memset(&io->bus[0], 0, sizeof(io->bus[0]) * 6);
292
static int flash_sst39lvf160_read_word(struct device_desc *dev, uint32_t addr, uint32_t *data)
294
struct machine_config *mc = (struct machine_config*)dev->mach;
295
ARMul_State *state = (ARMul_State*)mc->state;
297
global_mbp = bank_ptr(addr);
298
*data = real_read_word(state, addr);
300
DEBUG("read_word(addr:0x%08x, data:0x%x)\n", addr, *data);
306
static int flash_sst39lvf160_write_word(struct device_desc *dev, uint32_t addr, uint32_t data)
309
struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
310
struct machine_config *mc = (struct machine_config*)dev->mach;
311
ARMul_State *state = (ARMul_State*)mc->state;
313
global_mbp = bank_ptr(addr);
314
real_write_word(state, addr, data);
316
io->dump_flags |= 0x1;
318
DEBUG("write_word(addr:0x%08x, data:0x%x)\n", addr, data);
322
PRINT("write_word: Unsupported !!!\n");
328
static int flash_sst39lvf160_setup(struct device_desc *dev)
330
struct flash_sst39lvf160_io *io;
332
if (skyeye_config.arch == NULL ||
333
skyeye_config.arch->arch_name == NULL ||
334
strcmp(skyeye_config.arch->arch_name, "arm") != 0) {
335
PRINT("*** ERROR: Unsupported architecture !!!\n");
339
if (dev->size != 0x200000) {
340
PRINT("*** ERROR: Only support 2M flash !!!\n");
344
io = (struct flash_sst39lvf160_io*)malloc(sizeof(struct flash_sst39lvf160_io));
345
if (io == NULL) return -1;
347
dev->fini = flash_sst39lvf160_fini;
348
dev->reset = flash_sst39lvf160_reset;
349
dev->update = flash_sst39lvf160_update;
350
dev->read_byte = flash_sst39lvf160_read_byte;
351
dev->write_byte = flash_sst39lvf160_write_byte;
352
dev->read_halfword = flash_sst39lvf160_read_halfword;
353
dev->write_halfword = flash_sst39lvf160_write_halfword;
354
dev->read_word = flash_sst39lvf160_read_word;
355
dev->write_word = flash_sst39lvf160_write_word;
356
dev->data = (void*)io;
358
flash_sst39lvf160_reset(dev);
364
void flash_sst39lvf160_init(struct device_module_set *mod_set)
366
register_device_module("SST39LF160", mod_set, &flash_sst39lvf160_setup);
367
register_device_module("SST39VF160", mod_set, &flash_sst39lvf160_setup);