X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=hw%2Fpflash_cfi02.c;h=08f88900f074b54f40f8899f241b06ccfe859a4e;hb=cd346349b45ef056f138a184f660b8c34c3213cc;hp=1f0cbe2f9aa1a8f968a61c003c3044147052e17c;hpb=29133e9a0fff5775f8a1bef8671802a8624fc2c4;p=qemu diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index 1f0cbe2..08f8890 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -1,6 +1,6 @@ /* * CFI parallel flash with AMD command set emulation - * + * * Copyright (c) 2005 Jocelyn Mayer * * This library is free software; you can redistribute it and/or @@ -42,9 +42,6 @@ #ifdef PFLASH_DEBUG #define DPRINTF(fmt, args...) \ do { \ - if (loglevel) \ - fprintf(logfile, "PFLASH: " fmt , ##args); \ - else \ printf("PFLASH: " fmt , ##args); \ } while (0) #else @@ -53,9 +50,9 @@ do { \ struct pflash_t { BlockDriverState *bs; - target_ulong base; - target_ulong sector_len; - target_ulong total_len; + target_phys_addr_t base; + uint32_t sector_len; + uint32_t total_len; int width; int wcycle; /* if 0, the flash is read normally */ int bypass; @@ -88,13 +85,13 @@ static void pflash_timer (void *opaque) pfl->cmd = 0; } -static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) +static uint32_t pflash_read (pflash_t *pfl, uint32_t offset, int width) { - target_ulong boff; + uint32_t boff; uint32_t ret; uint8_t *p; - DPRINTF("%s: offset %08x\n", __func__, offset); + DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset); ret = -1; offset -= pfl->base; boff = offset & 0xFF; @@ -138,7 +135,6 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) #else ret = p[offset]; ret |= p[offset + 1] << 8; - ret |= p[offset + 1] << 8; ret |= p[offset + 2] << 16; ret |= p[offset + 3] << 24; #endif @@ -165,7 +161,7 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) default: goto flash_read; } - DPRINTF("%s: ID %d %x\n", __func__, boff, ret); + DPRINTF("%s: ID " TARGET_FMT_ld " %x\n", __func__, boff, ret); break; case 0xA0: case 0x10: @@ -189,7 +185,7 @@ static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width) } /* update flash content on disk */ -static void pflash_update(pflash_t *pfl, int offset, +static void pflash_update(pflash_t *pfl, int offset, int size) { int offset_end; @@ -198,32 +194,37 @@ static void pflash_update(pflash_t *pfl, int offset, /* round to sectors */ offset = offset >> 9; offset_end = (offset_end + 511) >> 9; - bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9), + bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9), offset_end - offset); } } -static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, +static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value, int width) { - target_ulong boff; + uint32_t boff; uint8_t *p; uint8_t cmd; /* WARNING: when the memory area is in ROMD mode, the offset is a ram offset, not a physical address */ - if (pfl->wcycle == 0) - offset -= pfl->off; - else - offset -= pfl->base; - cmd = value; - DPRINTF("%s: offset %08x %08x %d\n", __func__, offset, value, width); if (pfl->cmd != 0xA0 && cmd == 0xF0) { +#if 0 DPRINTF("%s: flash reset asked (%02x %02x)\n", __func__, pfl->cmd, cmd); +#endif goto reset_flash; } + DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__, + offset, value, width, pfl->wcycle); + if (pfl->wcycle == 0) + offset -= (uint32_t)(long)pfl->storage; + else + offset -= pfl->base; + + DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__, + offset, value, width); /* Set the device in I/O access mode */ cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); boff = offset & (pfl->sector_len - 1); @@ -243,7 +244,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, return; } if (boff != 0x555 || cmd != 0xAA) { - DPRINTF("%s: unlock0 failed %04x %02x %04x\n", + DPRINTF("%s: unlock0 failed " TARGET_FMT_lx " %02x %04x\n", __func__, boff, cmd, 0x555); goto reset_flash; } @@ -253,7 +254,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, /* We started an unlock sequence */ check_unlock1: if (boff != 0x2AA || cmd != 0x55) { - DPRINTF("%s: unlock1 failed %04x %02x\n", __func__, boff, cmd); + DPRINTF("%s: unlock1 failed " TARGET_FMT_lx " %02x\n", __func__, + boff, cmd); goto reset_flash; } DPRINTF("%s: unlock sequence done\n", __func__); @@ -261,7 +263,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, case 2: /* We finished an unlock sequence */ if (!pfl->bypass && boff != 0x555) { - DPRINTF("%s: command failed %04x %02x\n", __func__, boff, cmd); + DPRINTF("%s: command failed " TARGET_FMT_lx " %02x\n", __func__, + boff, cmd); goto reset_flash; } switch (cmd) { @@ -285,7 +288,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, /* We need another unlock sequence */ goto check_unlock0; case 0xA0: - DPRINTF("%s: write data offset %08x %08x %d\n", + DPRINTF("%s: write data offset " TARGET_FMT_lx " %08x %d\n", __func__, offset, value, width); p = pfl->storage; switch (width) { @@ -356,7 +359,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, switch (cmd) { case 0x10: if (boff != 0x555) { - DPRINTF("%s: chip erase: invalid address %04x\n", + DPRINTF("%s: chip erase: invalid address " TARGET_FMT_lx "\n", __func__, offset); goto reset_flash; } @@ -366,19 +369,20 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, pfl->status = 0x00; pflash_update(pfl, 0, pfl->total_len); /* Let's wait 5 seconds before chip erase is done */ - qemu_mod_timer(pfl->timer, + qemu_mod_timer(pfl->timer, qemu_get_clock(vm_clock) + (ticks_per_sec * 5)); break; case 0x30: /* Sector erase */ p = pfl->storage; offset &= ~(pfl->sector_len - 1); - DPRINTF("%s: start sector erase at %08x\n", __func__, offset); + DPRINTF("%s: start sector erase at " TARGET_FMT_lx "\n", __func__, + offset); memset(p + offset, 0xFF, pfl->sector_len); pflash_update(pfl, offset, pfl->sector_len); pfl->status = 0x00; /* Let's wait 1/2 second before sector erase is done */ - qemu_mod_timer(pfl->timer, + qemu_mod_timer(pfl->timer, qemu_get_clock(vm_clock) + (ticks_per_sec / 2)); break; default: @@ -416,10 +420,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, /* Reset flash */ reset_flash: - if (pfl->wcycle != 0) { - cpu_register_physical_memory(pfl->base, pfl->total_len, - pfl->off | IO_MEM_ROMD | pfl->fl_mem); - } + cpu_register_physical_memory(pfl->base, pfl->total_len, + pfl->off | IO_MEM_ROMD | pfl->fl_mem); pfl->bypass = 0; pfl->wcycle = 0; pfl->cmd = 0; @@ -519,25 +521,28 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_register (target_ulong base, ram_addr_t off, +pflash_t *pflash_register (target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, - target_ulong sector_len, int nb_blocs, int width, - uint16_t id0, uint16_t id1, + uint32_t sector_len, int nb_blocs, int width, + uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3) { pflash_t *pfl; - target_long total_len; + int32_t total_len; total_len = sector_len * nb_blocs; /* XXX: to be fixed */ +#if 0 if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) && total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) return NULL; +#endif pfl = qemu_mallocz(sizeof(pflash_t)); if (pfl == NULL) return NULL; pfl->storage = phys_ram_base + off; - pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops, pfl); + pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops, + pfl); pfl->off = off; cpu_register_physical_memory(base, total_len, off | pfl->fl_mem | IO_MEM_ROMD); @@ -613,7 +618,9 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off, pfl->cfi_table[0x28] = 0x02; pfl->cfi_table[0x29] = 0x00; /* Max number of bytes in multi-bytes write */ - pfl->cfi_table[0x2A] = 0x05; + /* XXX: disable buffered write as it's not supported */ + // pfl->cfi_table[0x2A] = 0x05; + pfl->cfi_table[0x2A] = 0x00; pfl->cfi_table[0x2B] = 0x00; /* Number of erase block regions (uniform) */ pfl->cfi_table[0x2C] = 0x01;