~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/pflash_cfi02.c

Tags: upstream-0.9.0+20070816
ImportĀ upstreamĀ versionĀ 0.9.0+20070816

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
 
51
51
struct pflash_t {
52
52
    BlockDriverState *bs;
53
 
    target_ulong base;
54
 
    target_ulong sector_len;
55
 
    target_ulong total_len;
 
53
    target_phys_addr_t base;
 
54
    uint32_t sector_len;
 
55
    uint32_t total_len;
56
56
    int width;
57
57
    int wcycle; /* if 0, the flash is read normally */
58
58
    int bypass;
85
85
    pfl->cmd = 0;
86
86
}
87
87
 
88
 
static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width)
 
88
static uint32_t pflash_read (pflash_t *pfl, uint32_t offset, int width)
89
89
{
90
 
    target_ulong boff;
 
90
    uint32_t boff;
91
91
    uint32_t ret;
92
92
    uint8_t *p;
93
93
 
94
 
    DPRINTF("%s: offset %08x\n", __func__, offset);
 
94
    DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset);
95
95
    ret = -1;
96
96
    offset -= pfl->base;
97
97
    boff = offset & 0xFF;
161
161
        default:
162
162
            goto flash_read;
163
163
        }
164
 
        DPRINTF("%s: ID %d %x\n", __func__, boff, ret);
 
164
        DPRINTF("%s: ID " TARGET_FMT_ld " %x\n", __func__, boff, ret);
165
165
        break;
166
166
    case 0xA0:
167
167
    case 0x10:
199
199
    }
200
200
}
201
201
 
202
 
static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
 
202
static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
203
203
                          int width)
204
204
{
205
 
    target_ulong boff;
 
205
    uint32_t boff;
206
206
    uint8_t *p;
207
207
    uint8_t cmd;
208
208
 
209
209
    /* WARNING: when the memory area is in ROMD mode, the offset is a
210
210
       ram offset, not a physical address */
 
211
    cmd = value;
 
212
    if (pfl->cmd != 0xA0 && cmd == 0xF0) {
 
213
#if 0
 
214
        DPRINTF("%s: flash reset asked (%02x %02x)\n",
 
215
                __func__, pfl->cmd, cmd);
 
216
#endif
 
217
        goto reset_flash;
 
218
    }
 
219
    DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__,
 
220
            offset, value, width, pfl->wcycle);
211
221
    if (pfl->wcycle == 0)
212
 
        offset -= (target_ulong)(long)pfl->storage;
 
222
        offset -= (uint32_t)(long)pfl->storage;
213
223
    else
214
224
        offset -= pfl->base;
215
225
        
216
 
    cmd = value;
217
 
    DPRINTF("%s: offset %08x %08x %d\n", __func__, offset, value, width);
218
 
    if (pfl->cmd != 0xA0 && cmd == 0xF0) {
219
 
        DPRINTF("%s: flash reset asked (%02x %02x)\n",
220
 
                __func__, pfl->cmd, cmd);
221
 
        goto reset_flash;
222
 
    }
 
226
    DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__,
 
227
            offset, value, width);
223
228
    /* Set the device in I/O access mode */
224
229
    cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
225
230
    boff = offset & (pfl->sector_len - 1);
239
244
            return;
240
245
        }
241
246
        if (boff != 0x555 || cmd != 0xAA) {
242
 
            DPRINTF("%s: unlock0 failed %04x %02x %04x\n",
 
247
            DPRINTF("%s: unlock0 failed " TARGET_FMT_lx " %02x %04x\n",
243
248
                    __func__, boff, cmd, 0x555);
244
249
            goto reset_flash;
245
250
        }
249
254
        /* We started an unlock sequence */
250
255
    check_unlock1:
251
256
        if (boff != 0x2AA || cmd != 0x55) {
252
 
            DPRINTF("%s: unlock1 failed %04x %02x\n", __func__, boff, cmd);
 
257
            DPRINTF("%s: unlock1 failed " TARGET_FMT_lx " %02x\n", __func__,
 
258
                    boff, cmd);
253
259
            goto reset_flash;
254
260
        }
255
261
        DPRINTF("%s: unlock sequence done\n", __func__);
257
263
    case 2:
258
264
        /* We finished an unlock sequence */
259
265
        if (!pfl->bypass && boff != 0x555) {
260
 
            DPRINTF("%s: command failed %04x %02x\n", __func__, boff, cmd);
 
266
            DPRINTF("%s: command failed " TARGET_FMT_lx " %02x\n", __func__,
 
267
                    boff, cmd);
261
268
            goto reset_flash;
262
269
        }
263
270
        switch (cmd) {
281
288
            /* We need another unlock sequence */
282
289
            goto check_unlock0;
283
290
        case 0xA0:
284
 
            DPRINTF("%s: write data offset %08x %08x %d\n",
 
291
            DPRINTF("%s: write data offset " TARGET_FMT_lx " %08x %d\n",
285
292
                    __func__, offset, value, width);
286
293
            p = pfl->storage;
287
294
            switch (width) {
352
359
        switch (cmd) {
353
360
        case 0x10:
354
361
            if (boff != 0x555) {
355
 
                DPRINTF("%s: chip erase: invalid address %04x\n",
 
362
                DPRINTF("%s: chip erase: invalid address " TARGET_FMT_lx "\n",
356
363
                        __func__, offset);
357
364
                goto reset_flash;
358
365
            }
369
376
            /* Sector erase */
370
377
            p = pfl->storage;
371
378
            offset &= ~(pfl->sector_len - 1);
372
 
            DPRINTF("%s: start sector erase at %08x\n", __func__, offset);
 
379
            DPRINTF("%s: start sector erase at " TARGET_FMT_lx "\n", __func__,
 
380
                    offset);
373
381
            memset(p + offset, 0xFF, pfl->sector_len);
374
382
            pflash_update(pfl, offset, pfl->sector_len);
375
383
            pfl->status = 0x00;
412
420
 
413
421
    /* Reset flash */
414
422
 reset_flash:
415
 
    if (pfl->wcycle != 0) {
416
 
        cpu_register_physical_memory(pfl->base, pfl->total_len,
417
 
                                     pfl->off | IO_MEM_ROMD | pfl->fl_mem);
418
 
    }
 
423
    cpu_register_physical_memory(pfl->base, pfl->total_len,
 
424
                                 pfl->off | IO_MEM_ROMD | pfl->fl_mem);
419
425
    pfl->bypass = 0;
420
426
    pfl->wcycle = 0;
421
427
    pfl->cmd = 0;
515
521
    return ret;
516
522
}
517
523
 
518
 
pflash_t *pflash_register (target_ulong base, ram_addr_t off,
 
524
pflash_t *pflash_register (target_phys_addr_t base, ram_addr_t off,
519
525
                           BlockDriverState *bs,
520
 
                           target_ulong sector_len, int nb_blocs, int width,
 
526
                           uint32_t sector_len, int nb_blocs, int width,
521
527
                           uint16_t id0, uint16_t id1, 
522
528
                           uint16_t id2, uint16_t id3)
523
529
{
524
530
    pflash_t *pfl;
525
 
    target_long total_len;
 
531
    int32_t total_len;
526
532
 
527
533
    total_len = sector_len * nb_blocs;
528
534
    /* XXX: to be fixed */
 
535
#if 0
529
536
    if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
530
537
        total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
531
538
        return NULL;
 
539
#endif
532
540
    pfl = qemu_mallocz(sizeof(pflash_t));
533
541
    if (pfl == NULL)
534
542
        return NULL;
535
543
    pfl->storage = phys_ram_base + off;
536
 
    pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops, pfl);
 
544
    pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops,
 
545
                                         pfl);
537
546
    pfl->off = off;
538
547
    cpu_register_physical_memory(base, total_len,
539
548
                                 off | pfl->fl_mem | IO_MEM_ROMD);
609
618
    pfl->cfi_table[0x28] = 0x02;
610
619
    pfl->cfi_table[0x29] = 0x00;
611
620
    /* Max number of bytes in multi-bytes write */
612
 
    pfl->cfi_table[0x2A] = 0x05;
 
621
    /* XXX: disable buffered write as it's not supported */
 
622
    //    pfl->cfi_table[0x2A] = 0x05;
 
623
    pfl->cfi_table[0x2A] = 0x00;
613
624
    pfl->cfi_table[0x2B] = 0x00;
614
625
    /* Number of erase block regions (uniform) */
615
626
    pfl->cfi_table[0x2C] = 0x01;