~ubuntu-branches/ubuntu/lucid/skyeye/lucid-proposed

« back to all changes in this revision

Viewing changes to device/flash/dev_flash_sst39lvf160.c

  • Committer: Bazaar Package Importer
  • Author(s): Yu Guanghui
  • Date: 2007-08-07 13:25:49 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20070807132549-96159k1obat1fxr0
Tags: 1.2.3-1
* New upstream release
* Added NO_BFD=1, don't require libbfd now. (Closes:Bug#423933) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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>
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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 
 
19
*/
 
20
 
 
21
/*
 
22
 * 2007.04.03   Written by Anthony Lee
 
23
 */
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
 
 
28
#include "armdefs.h"
 
29
#include "skyeye_device.h"
 
30
#include "skyeye_flash.h"
 
31
#include "dev_flash_sst39lvf160.h"
 
32
 
 
33
#define FLASH_SST39LVF160_DEBUG         0
 
34
 
 
35
#define PRINT(x...)                     printf("[FLASH_SST39LVF160]: " x)
 
36
 
 
37
#if FLASH_SST39LVF160_DEBUG
 
38
#define DEBUG(x...)                     printf("[FLASH_SST39LVF160]: " x)
 
39
#else
 
40
#define DEBUG(x...)                     (void)0
 
41
#endif
 
42
 
 
43
extern mem_bank_t *global_mbp;
 
44
extern mem_bank_t *bank_ptr(ARMword addr);
 
45
 
 
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);
 
52
 
 
53
 
 
54
static void flash_sst39lvf160_fini(struct device_desc *dev)
 
55
{
 
56
        struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
 
57
 
 
58
        free(dev->dev);
 
59
        free(io);
 
60
}
 
61
 
 
62
 
 
63
static void flash_sst39lvf160_reset(struct device_desc *dev)
 
64
{
 
65
        struct flash_sst39lvf160_io *io = (struct flash_sst39lvf160_io*)dev->data;
 
66
 
 
67
        memset(io, 0, sizeof(struct flash_sst39lvf160_io));
 
68
        io->dump_cnt = 0xffff;
 
69
}
 
70
 
 
71
 
 
72
static void flash_sst39lvf160_update(struct device_desc *dev)
 
73
{
 
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;
 
78
        uint32_t addr, data;
 
79
        int fd;
 
80
 
 
81
        if (flash_dev->dump[0] == 0) return;
 
82
        if (io->dump_flags == 0 || (io->dump_flags & 0x2) != 0) return;
 
83
 
 
84
        io->dump_cnt -= 1;
 
85
 
 
86
        if (io->dump_cnt == 0) {
 
87
                if (skyeye_flash_dump(flash_dev->dump, dev->base, 0x200000) != 0) {
 
88
                        io->dump_flags |= 0x2;
 
89
                        printf("\n");
 
90
                        PRINT("*** FAILED: Can't dump to %s\n", flash_dev->dump);
 
91
                        return;
 
92
                }
 
93
 
 
94
                io->dump_cnt = 0xffff;
 
95
                io->dump_flags = 0;
 
96
 
 
97
                printf("\n");
 
98
                PRINT("Dumped to %s\n", flash_dev->dump);
 
99
        }
 
100
}
 
101
 
 
102
 
 
103
static int flash_sst39lvf160_read_byte(struct device_desc *dev, uint32_t addr, uint8_t *data)
 
104
{
 
105
        struct machine_config *mc = (struct machine_config*)dev->mach;
 
106
        ARMul_State *state = (ARMul_State*)mc->state;
 
107
 
 
108
        global_mbp = bank_ptr(addr);
 
109
        *data = real_read_byte(state, addr);
 
110
 
 
111
        DEBUG("read_byte(addr:0x%08x, data:0x%x)\n", addr, *data);
 
112
 
 
113
        return ADDR_HIT;
 
114
}
 
115
 
 
116
 
 
117
static int flash_sst39lvf160_write_byte(struct device_desc *dev, uint32_t addr, uint8_t data)
 
118
{
 
119
#if 0
 
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;
 
123
 
 
124
        global_mbp = bank_ptr(addr);
 
125
        real_write_byte(state, addr, data);
 
126
 
 
127
        io->dump_flags |= 0x1;
 
128
 
 
129
        DEBUG("write_byte(addr:0x%08x, data:0x%x)\n", addr, data);
 
130
 
 
131
        return ADDR_HIT;
 
132
#else
 
133
        PRINT("write_byte: Unsupported !!!\n");
 
134
        return ADDR_NOHIT;
 
135
#endif
 
136
}
 
137
 
 
138
 
 
139
static int flash_sst39lvf160_read_halfword(struct device_desc *dev, uint32_t addr, uint16_t *data)
 
140
{
 
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;
 
145
 
 
146
        if (CMD_SOFTWARE_ID_ENTRY(io)) {
 
147
                switch (offset) {
 
148
                        case 0: *data = 0xbf; break;
 
149
                        case 1: *data = 0x2782; break;
 
150
 
 
151
                        default: *data = 0x0; break;
 
152
                }
 
153
        }
 
154
 
 
155
        if (CMD_CFI_QUERY_ENTRY(io)) {
 
156
                switch (offset) {
 
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;
 
169
 
 
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;
 
183
 
 
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;
 
199
 
 
200
                        default: *data = 0x0; break;
 
201
                }
 
202
        }
 
203
 
 
204
        if (io->cnt == 0) {
 
205
                /* read data from addr */
 
206
                global_mbp = bank_ptr(addr);
 
207
                *data = real_read_halfword(state, addr);
 
208
        }
 
209
 
 
210
        io->n_bus = 0;
 
211
 
 
212
        DEBUG("read_halfword(offset:0x%08x, data:0x%x)\n", offset, *data);
 
213
 
 
214
        return ADDR_HIT;
 
215
}
 
216
 
 
217
 
 
218
static int flash_sst39lvf160_write_halfword(struct device_desc *dev, uint32_t addr, uint16_t data)
 
219
{
 
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;
 
224
        uint32_t start, end;
 
225
 
 
226
        DEBUG("write_halfword(%dst Bus, offset:0x%08x, data:0x%x)\n", io->n_bus + 1, offset, data);
 
227
 
 
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;
 
233
                goto reset;
 
234
        }
 
235
 
 
236
        if (CMD_ERASE(io)) {
 
237
                switch (data) {
 
238
                        case 0x10: /* Chip-Erase */
 
239
                                start = dev->base;
 
240
                                end = start + 0x200000;
 
241
                                break;
 
242
 
 
243
                        case 0x30: /* Sector-Erase: 4KBytes/sector */
 
244
                                start = addr;
 
245
                                end = start + 0x1000;
 
246
                                break;
 
247
 
 
248
                        case 0x50: /* Block-Erase: 64KBytes/block */
 
249
                                start = addr;
 
250
                                end = start + 0x10000;
 
251
                                break;
 
252
 
 
253
                        default:
 
254
                                start = end = 0x0;
 
255
                                break;
 
256
                }
 
257
 
 
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);
 
262
                        }
 
263
                        DEBUG("*** Erase(start:0x%08x, end:0x%08x)\n", start, end);
 
264
                } else {
 
265
                        PRINT("*** ERROR: Erase(start:0x%08x, end:0x%08x)\n", start, end);
 
266
                }
 
267
 
 
268
                goto reset;
 
269
        }
 
270
 
 
271
        if (io->n_bus < 6) {
 
272
                io->bus[io->n_bus].addr = offset;
 
273
                io->bus[io->n_bus].data = data;
 
274
                io->n_bus += 1;
 
275
 
 
276
                io->cnt = io->n_bus;
 
277
 
 
278
                if (CMD_QUERY_EXIT(io)) goto reset;
 
279
        }
 
280
 
 
281
        goto exit;
 
282
 
 
283
reset:
 
284
        io->cnt = io->n_bus = 0;
 
285
        memset(&io->bus[0], 0, sizeof(io->bus[0]) * 6);
 
286
 
 
287
exit:
 
288
        return ADDR_HIT;
 
289
}
 
290
 
 
291
 
 
292
static int flash_sst39lvf160_read_word(struct device_desc *dev, uint32_t addr, uint32_t *data)
 
293
{
 
294
        struct machine_config *mc = (struct machine_config*)dev->mach;
 
295
        ARMul_State *state = (ARMul_State*)mc->state;
 
296
 
 
297
        global_mbp = bank_ptr(addr);
 
298
        *data = real_read_word(state, addr);
 
299
 
 
300
        DEBUG("read_word(addr:0x%08x, data:0x%x)\n", addr, *data);
 
301
 
 
302
        return ADDR_HIT;
 
303
}
 
304
 
 
305
 
 
306
static int flash_sst39lvf160_write_word(struct device_desc *dev, uint32_t addr, uint32_t data)
 
307
{
 
308
#if 0
 
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;
 
312
 
 
313
        global_mbp = bank_ptr(addr);
 
314
        real_write_word(state, addr, data);
 
315
 
 
316
        io->dump_flags |= 0x1;
 
317
 
 
318
        DEBUG("write_word(addr:0x%08x, data:0x%x)\n", addr, data);
 
319
 
 
320
        return ADDR_HIT;
 
321
#else
 
322
        PRINT("write_word: Unsupported !!!\n");
 
323
        return ADDR_NOHIT;
 
324
#endif
 
325
}
 
326
 
 
327
 
 
328
static int flash_sst39lvf160_setup(struct device_desc *dev)
 
329
{
 
330
        struct flash_sst39lvf160_io *io;
 
331
 
 
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");
 
336
                return -1;
 
337
        }
 
338
 
 
339
        if (dev->size != 0x200000) {
 
340
                PRINT("*** ERROR: Only support 2M flash !!!\n");
 
341
                return -1;
 
342
        }
 
343
 
 
344
        io = (struct flash_sst39lvf160_io*)malloc(sizeof(struct flash_sst39lvf160_io));
 
345
        if (io == NULL) return -1;
 
346
 
 
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;
 
357
 
 
358
        flash_sst39lvf160_reset(dev);
 
359
 
 
360
        return 0;
 
361
}
 
362
 
 
363
 
 
364
void flash_sst39lvf160_init(struct device_module_set *mod_set)
 
365
{
 
366
        register_device_module("SST39LF160", mod_set, &flash_sst39lvf160_setup);
 
367
        register_device_module("SST39VF160", mod_set, &flash_sst39lvf160_setup);
 
368
}
 
369