Commit d361be2566e01f59d49f8102a5af2820cbaf8e73
1 parent
57575058
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
Showing
1 changed file
with
53 additions
and
34 deletions
hw/pflash_cfi01.c
| ... | ... | @@ -194,6 +194,47 @@ static void pflash_update(pflash_t *pfl, int offset, |
| 194 | 194 | } |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | +static void inline pflash_data_write(pflash_t *pfl, target_ulong offset, | |
| 198 | + uint32_t value, int width) | |
| 199 | +{ | |
| 200 | + uint8_t *p = pfl->storage; | |
| 201 | + | |
| 202 | + DPRINTF("%s: block write offset " TARGET_FMT_lx | |
| 203 | + " value %x counter " TARGET_FMT_lx "\n", | |
| 204 | + __func__, offset, value, pfl->counter); | |
| 205 | + switch (width) { | |
| 206 | + case 1: | |
| 207 | + p[offset] = value; | |
| 208 | + pflash_update(pfl, offset, 1); | |
| 209 | + break; | |
| 210 | + case 2: | |
| 211 | +#if defined(TARGET_WORDS_BIGENDIAN) | |
| 212 | + p[offset] = value >> 8; | |
| 213 | + p[offset + 1] = value; | |
| 214 | +#else | |
| 215 | + p[offset] = value; | |
| 216 | + p[offset + 1] = value >> 8; | |
| 217 | +#endif | |
| 218 | + pflash_update(pfl, offset, 2); | |
| 219 | + break; | |
| 220 | + case 4: | |
| 221 | +#if defined(TARGET_WORDS_BIGENDIAN) | |
| 222 | + p[offset] = value >> 24; | |
| 223 | + p[offset + 1] = value >> 16; | |
| 224 | + p[offset + 2] = value >> 8; | |
| 225 | + p[offset + 3] = value; | |
| 226 | +#else | |
| 227 | + p[offset] = value; | |
| 228 | + p[offset + 1] = value >> 8; | |
| 229 | + p[offset + 2] = value >> 16; | |
| 230 | + p[offset + 3] = value >> 24; | |
| 231 | +#endif | |
| 232 | + pflash_update(pfl, offset, 4); | |
| 233 | + break; | |
| 234 | + } | |
| 235 | + | |
| 236 | +} | |
| 237 | + | |
| 197 | 238 | static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 198 | 239 | int width) |
| 199 | 240 | { |
| ... | ... | @@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 221 | 262 | switch (cmd) { |
| 222 | 263 | case 0x00: /* ??? */ |
| 223 | 264 | goto reset_flash; |
| 265 | + case 0x10: /* Single Byte Program */ | |
| 266 | + case 0x40: /* Single Byte Program */ | |
| 267 | + DPRINTF(stderr, "%s: Single Byte Program\n", __func__); | |
| 268 | + break; | |
| 224 | 269 | case 0x20: /* Block erase */ |
| 225 | 270 | p = pfl->storage; |
| 226 | 271 | offset &= ~(pfl->sector_len - 1); |
| ... | ... | @@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 262 | 307 | return; |
| 263 | 308 | case 1: |
| 264 | 309 | switch (pfl->cmd) { |
| 310 | + case 0x10: /* Single Byte Program */ | |
| 311 | + case 0x40: /* Single Byte Program */ | |
| 312 | + DPRINTF("%s: Single Byte Program\n", __func__); | |
| 313 | + pflash_data_write(pfl, offset, value, width); | |
| 314 | + pfl->status |= 0x80; /* Ready! */ | |
| 315 | + pfl->wcycle = 0; | |
| 316 | + break; | |
| 265 | 317 | case 0x20: /* Block erase */ |
| 266 | 318 | case 0x28: |
| 267 | 319 | if (cmd == 0xd0) { /* confirm */ |
| ... | ... | @@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
| 306 | 358 | case 2: |
| 307 | 359 | switch (pfl->cmd) { |
| 308 | 360 | case 0xe8: /* Block write */ |
| 309 | - p = pfl->storage; | |
| 310 | - DPRINTF("%s: block write offset " TARGET_FMT_lx | |
| 311 | - " value %x counter " TARGET_FMT_lx "\n", | |
| 312 | - __func__, offset, value, pfl->counter); | |
| 313 | - switch (width) { | |
| 314 | - case 1: | |
| 315 | - p[offset] = value; | |
| 316 | - pflash_update(pfl, offset, 1); | |
| 317 | - break; | |
| 318 | - case 2: | |
| 319 | -#if defined(TARGET_WORDS_BIGENDIAN) | |
| 320 | - p[offset] = value >> 8; | |
| 321 | - p[offset + 1] = value; | |
| 322 | -#else | |
| 323 | - p[offset] = value; | |
| 324 | - p[offset + 1] = value >> 8; | |
| 325 | -#endif | |
| 326 | - pflash_update(pfl, offset, 2); | |
| 327 | - break; | |
| 328 | - case 4: | |
| 329 | -#if defined(TARGET_WORDS_BIGENDIAN) | |
| 330 | - p[offset] = value >> 24; | |
| 331 | - p[offset + 1] = value >> 16; | |
| 332 | - p[offset + 2] = value >> 8; | |
| 333 | - p[offset + 3] = value; | |
| 334 | -#else | |
| 335 | - p[offset] = value; | |
| 336 | - p[offset + 1] = value >> 8; | |
| 337 | - p[offset + 2] = value >> 16; | |
| 338 | - p[offset + 3] = value >> 24; | |
| 339 | -#endif | |
| 340 | - pflash_update(pfl, offset, 4); | |
| 341 | - break; | |
| 342 | - } | |
| 361 | + pflash_data_write(pfl, offset, value, width); | |
| 343 | 362 | |
| 344 | 363 | pfl->status |= 0x80; |
| 345 | 364 | ... | ... |