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,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 | static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | 238 | static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, |
198 | int width) | 239 | int width) |
199 | { | 240 | { |
@@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
221 | switch (cmd) { | 262 | switch (cmd) { |
222 | case 0x00: /* ??? */ | 263 | case 0x00: /* ??? */ |
223 | goto reset_flash; | 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 | case 0x20: /* Block erase */ | 269 | case 0x20: /* Block erase */ |
225 | p = pfl->storage; | 270 | p = pfl->storage; |
226 | offset &= ~(pfl->sector_len - 1); | 271 | offset &= ~(pfl->sector_len - 1); |
@@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
262 | return; | 307 | return; |
263 | case 1: | 308 | case 1: |
264 | switch (pfl->cmd) { | 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 | case 0x20: /* Block erase */ | 317 | case 0x20: /* Block erase */ |
266 | case 0x28: | 318 | case 0x28: |
267 | if (cmd == 0xd0) { /* confirm */ | 319 | if (cmd == 0xd0) { /* confirm */ |
@@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | @@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, | ||
306 | case 2: | 358 | case 2: |
307 | switch (pfl->cmd) { | 359 | switch (pfl->cmd) { |
308 | case 0xe8: /* Block write */ | 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 | pfl->status |= 0x80; | 363 | pfl->status |= 0x80; |
345 | 364 |