diff options
Diffstat (limited to 'hw/pflash_cfi01.c')
-rw-r--r-- | hw/pflash_cfi01.c | 195 |
1 files changed, 127 insertions, 68 deletions
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index 95b406be71..6b2adba87d 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -97,7 +97,7 @@ static void pflash_timer (void *opaque) } static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset, - int width) + int width, int be) { target_phys_addr_t boff; uint32_t ret; @@ -126,29 +126,29 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset, __func__, offset, ret); break; case 2: -#if defined(TARGET_WORDS_BIGENDIAN) - ret = p[offset] << 8; - ret |= p[offset + 1]; -#else - ret = p[offset]; - ret |= p[offset + 1] << 8; -#endif + if (be) { + ret = p[offset] << 8; + ret |= p[offset + 1]; + } else { + ret = p[offset]; + ret |= p[offset + 1] << 8; + } DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n", __func__, offset, ret); break; case 4: -#if defined(TARGET_WORDS_BIGENDIAN) - ret = p[offset] << 24; - ret |= p[offset + 1] << 16; - ret |= p[offset + 2] << 8; - ret |= p[offset + 3]; -#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 + if (be) { + ret = p[offset] << 24; + ret |= p[offset + 1] << 16; + ret |= p[offset + 2] << 8; + ret |= p[offset + 3]; + } else { + ret = p[offset]; + ret |= p[offset + 1] << 8; + ret |= p[offset + 1] << 8; + ret |= p[offset + 2] << 16; + ret |= p[offset + 3] << 24; + } DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n", __func__, offset, ret); break; @@ -197,7 +197,7 @@ static void pflash_update(pflash_t *pfl, int offset, } static inline void pflash_data_write(pflash_t *pfl, target_phys_addr_t offset, - uint32_t value, int width) + uint32_t value, int width, int be) { uint8_t *p = pfl->storage; @@ -209,33 +209,33 @@ static inline void pflash_data_write(pflash_t *pfl, target_phys_addr_t offset, p[offset] = value; break; case 2: -#if defined(TARGET_WORDS_BIGENDIAN) - p[offset] = value >> 8; - p[offset + 1] = value; -#else - p[offset] = value; - p[offset + 1] = value >> 8; -#endif + if (be) { + p[offset] = value >> 8; + p[offset + 1] = value; + } else { + p[offset] = value; + p[offset + 1] = value >> 8; + } break; case 4: -#if defined(TARGET_WORDS_BIGENDIAN) - p[offset] = value >> 24; - p[offset + 1] = value >> 16; - p[offset + 2] = value >> 8; - p[offset + 3] = value; -#else - p[offset] = value; - p[offset + 1] = value >> 8; - p[offset + 2] = value >> 16; - p[offset + 3] = value >> 24; -#endif + if (be) { + p[offset] = value >> 24; + p[offset + 1] = value >> 16; + p[offset + 2] = value >> 8; + p[offset + 3] = value; + } else { + p[offset] = value; + p[offset + 1] = value >> 8; + p[offset + 2] = value >> 16; + p[offset + 3] = value >> 24; + } break; } } static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, - uint32_t value, int width) + uint32_t value, int width, int be) { uint8_t *p; uint8_t cmd; @@ -304,7 +304,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, case 0x10: /* Single Byte Program */ case 0x40: /* Single Byte Program */ DPRINTF("%s: Single Byte Program\n", __func__); - pflash_data_write(pfl, offset, value, width); + pflash_data_write(pfl, offset, value, width, be); pflash_update(pfl, offset, width); pfl->status |= 0x80; /* Ready! */ pfl->wcycle = 0; @@ -353,7 +353,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, case 2: switch (pfl->cmd) { case 0xe8: /* Block write */ - pflash_data_write(pfl, offset, value, width); + pflash_data_write(pfl, offset, value, width, be); pfl->status |= 0x80; @@ -412,57 +412,110 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, } -static uint32_t pflash_readb (void *opaque, target_phys_addr_t addr) +static uint32_t pflash_readb_be(void *opaque, target_phys_addr_t addr) +{ + return pflash_read(opaque, addr, 1, 1); +} + +static uint32_t pflash_readb_le(void *opaque, target_phys_addr_t addr) +{ + return pflash_read(opaque, addr, 1, 0); +} + +static uint32_t pflash_readw_be(void *opaque, target_phys_addr_t addr) +{ + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 2, 1); +} + +static uint32_t pflash_readw_le(void *opaque, target_phys_addr_t addr) { - return pflash_read(opaque, addr, 1); + pflash_t *pfl = opaque; + + return pflash_read(pfl, addr, 2, 0); } -static uint32_t pflash_readw (void *opaque, target_phys_addr_t addr) +static uint32_t pflash_readl_be(void *opaque, target_phys_addr_t addr) { pflash_t *pfl = opaque; - return pflash_read(pfl, addr, 2); + return pflash_read(pfl, addr, 4, 1); } -static uint32_t pflash_readl (void *opaque, target_phys_addr_t addr) +static uint32_t pflash_readl_le(void *opaque, target_phys_addr_t addr) { pflash_t *pfl = opaque; - return pflash_read(pfl, addr, 4); + return pflash_read(pfl, addr, 4, 0); } -static void pflash_writeb (void *opaque, target_phys_addr_t addr, - uint32_t value) +static void pflash_writeb_be(void *opaque, target_phys_addr_t addr, + uint32_t value) { - pflash_write(opaque, addr, value, 1); + pflash_write(opaque, addr, value, 1, 1); } -static void pflash_writew (void *opaque, target_phys_addr_t addr, - uint32_t value) +static void pflash_writeb_le(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + pflash_write(opaque, addr, value, 1, 0); +} + +static void pflash_writew_be(void *opaque, target_phys_addr_t addr, + uint32_t value) { pflash_t *pfl = opaque; - pflash_write(pfl, addr, value, 2); + pflash_write(pfl, addr, value, 2, 1); } -static void pflash_writel (void *opaque, target_phys_addr_t addr, - uint32_t value) +static void pflash_writew_le(void *opaque, target_phys_addr_t addr, + uint32_t value) { pflash_t *pfl = opaque; - pflash_write(pfl, addr, value, 4); + pflash_write(pfl, addr, value, 2, 0); } -static CPUWriteMemoryFunc * const pflash_write_ops[] = { - &pflash_writeb, - &pflash_writew, - &pflash_writel, +static void pflash_writel_be(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 4, 1); +} + +static void pflash_writel_le(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + pflash_t *pfl = opaque; + + pflash_write(pfl, addr, value, 4, 0); +} + +static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { + &pflash_writeb_be, + &pflash_writew_be, + &pflash_writel_be, }; -static CPUReadMemoryFunc * const pflash_read_ops[] = { - &pflash_readb, - &pflash_readw, - &pflash_readl, +static CPUReadMemoryFunc * const pflash_read_ops_be[] = { + &pflash_readb_be, + &pflash_readw_be, + &pflash_readl_be, +}; + +static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { + &pflash_writeb_le, + &pflash_writew_le, + &pflash_writel_le, +}; + +static CPUReadMemoryFunc * const pflash_read_ops_le[] = { + &pflash_readb_le, + &pflash_readw_le, + &pflash_readl_le, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -503,7 +556,8 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3) + uint16_t id2, uint16_t id3, + int be) { pflash_t *pfl; target_phys_addr_t total_len; @@ -522,8 +576,13 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, /* FIXME: Allocate ram ourselves. */ pfl->storage = qemu_get_ram_ptr(off); - pfl->fl_mem = cpu_register_io_memory( - pflash_read_ops, pflash_write_ops, pfl); + if (be) { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, + pflash_write_ops_be, pfl); + } else { + pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, + pflash_write_ops_le, pfl); + } pfl->off = off; cpu_register_physical_memory(base, total_len, off | pfl->fl_mem | IO_MEM_ROMD); |