pflash_cfi01: add Single Byte Program (Jean-Christophe PLAGNIOL-VILLARD).

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5904 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
balrog 2008-12-07 12:36:28 +00:00
parent 575750581c
commit d361be2566

View File

@ -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, static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
int width) int width)
{ {
@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
switch (cmd) { switch (cmd) {
case 0x00: /* ??? */ case 0x00: /* ??? */
goto reset_flash; 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 */ case 0x20: /* Block erase */
p = pfl->storage; p = pfl->storage;
offset &= ~(pfl->sector_len - 1); offset &= ~(pfl->sector_len - 1);
@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
return; return;
case 1: case 1:
switch (pfl->cmd) { 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 0x20: /* Block erase */
case 0x28: case 0x28:
if (cmd == 0xd0) { /* confirm */ if (cmd == 0xd0) { /* confirm */
@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
case 2: case 2:
switch (pfl->cmd) { switch (pfl->cmd) {
case 0xe8: /* Block write */ case 0xe8: /* Block write */
p = pfl->storage; pflash_data_write(pfl, offset, value, width);
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;
}
pfl->status |= 0x80; pfl->status |= 0x80;