diff options
Diffstat (limited to 'hw/pflash_cfi01.c')
-rw-r--r-- | hw/pflash_cfi01.c | 87 |
1 files changed, 53 insertions, 34 deletions
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index 6113fa648b..6f97e9d838 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -194,6 +194,47 @@ static void pflash_update(pflash_t *pfl, int offset, } } +static void inline pflash_data_write(pflash_t *pfl, target_ulong offset, + uint32_t value, int width) +{ + uint8_t *p = pfl->storage; + + DPRINTF("%s: block write offset " TARGET_FMT_lx + " value %x counter " TARGET_FMT_lx "\n", + __func__, offset, value, pfl->counter); + switch (width) { + case 1: + p[offset] = value; + pflash_update(pfl, offset, 1); + 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 + pflash_update(pfl, offset, 2); + 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 + pflash_update(pfl, offset, 4); + break; + } + +} + static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, int width) { @@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, switch (cmd) { case 0x00: /* ??? */ goto reset_flash; + case 0x10: /* Single Byte Program */ + case 0x40: /* Single Byte Program */ + DPRINTF(stderr, "%s: Single Byte Program\n", __func__); + break; case 0x20: /* Block erase */ p = pfl->storage; offset &= ~(pfl->sector_len - 1); @@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, return; case 1: switch (pfl->cmd) { + case 0x10: /* Single Byte Program */ + case 0x40: /* Single Byte Program */ + DPRINTF("%s: Single Byte Program\n", __func__); + pflash_data_write(pfl, offset, value, width); + pfl->status |= 0x80; /* Ready! */ + pfl->wcycle = 0; + break; case 0x20: /* Block erase */ case 0x28: if (cmd == 0xd0) { /* confirm */ @@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, case 2: switch (pfl->cmd) { case 0xe8: /* Block write */ - p = pfl->storage; - DPRINTF("%s: block write offset " TARGET_FMT_lx - " value %x counter " TARGET_FMT_lx "\n", - __func__, offset, value, pfl->counter); - switch (width) { - case 1: - p[offset] = value; - pflash_update(pfl, offset, 1); - 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 - pflash_update(pfl, offset, 2); - 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 - pflash_update(pfl, offset, 4); - break; - } + pflash_data_write(pfl, offset, value, width); pfl->status |= 0x80; |