Revision 3d08ff69 hw/pflash_cfi01.c
b/hw/pflash_cfi01.c | ||
---|---|---|
97 | 97 |
} |
98 | 98 |
|
99 | 99 |
static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset, |
100 |
int width) |
|
100 |
int width, int be)
|
|
101 | 101 |
{ |
102 | 102 |
target_phys_addr_t boff; |
103 | 103 |
uint32_t ret; |
... | ... | |
126 | 126 |
__func__, offset, ret); |
127 | 127 |
break; |
128 | 128 |
case 2: |
129 |
#if defined(TARGET_WORDS_BIGENDIAN)
|
|
130 |
ret = p[offset] << 8; |
|
131 |
ret |= p[offset + 1]; |
|
132 |
#else
|
|
133 |
ret = p[offset]; |
|
134 |
ret |= p[offset + 1] << 8; |
|
135 |
#endif
|
|
129 |
if (be) {
|
|
130 |
ret = p[offset] << 8;
|
|
131 |
ret |= p[offset + 1];
|
|
132 |
} else {
|
|
133 |
ret = p[offset];
|
|
134 |
ret |= p[offset + 1] << 8;
|
|
135 |
}
|
|
136 | 136 |
DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n", |
137 | 137 |
__func__, offset, ret); |
138 | 138 |
break; |
139 | 139 |
case 4: |
140 |
#if defined(TARGET_WORDS_BIGENDIAN)
|
|
141 |
ret = p[offset] << 24; |
|
142 |
ret |= p[offset + 1] << 16; |
|
143 |
ret |= p[offset + 2] << 8; |
|
144 |
ret |= p[offset + 3]; |
|
145 |
#else
|
|
146 |
ret = p[offset]; |
|
147 |
ret |= p[offset + 1] << 8; |
|
148 |
ret |= p[offset + 1] << 8; |
|
149 |
ret |= p[offset + 2] << 16; |
|
150 |
ret |= p[offset + 3] << 24; |
|
151 |
#endif
|
|
140 |
if (be) {
|
|
141 |
ret = p[offset] << 24;
|
|
142 |
ret |= p[offset + 1] << 16;
|
|
143 |
ret |= p[offset + 2] << 8;
|
|
144 |
ret |= p[offset + 3];
|
|
145 |
} else {
|
|
146 |
ret = p[offset];
|
|
147 |
ret |= p[offset + 1] << 8;
|
|
148 |
ret |= p[offset + 1] << 8;
|
|
149 |
ret |= p[offset + 2] << 16;
|
|
150 |
ret |= p[offset + 3] << 24;
|
|
151 |
}
|
|
152 | 152 |
DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n", |
153 | 153 |
__func__, offset, ret); |
154 | 154 |
break; |
... | ... | |
197 | 197 |
} |
198 | 198 |
|
199 | 199 |
static inline void pflash_data_write(pflash_t *pfl, target_phys_addr_t offset, |
200 |
uint32_t value, int width)
|
|
200 |
uint32_t value, int width, int be)
|
|
201 | 201 |
{ |
202 | 202 |
uint8_t *p = pfl->storage; |
203 | 203 |
|
... | ... | |
209 | 209 |
p[offset] = value; |
210 | 210 |
break; |
211 | 211 |
case 2: |
212 |
#if defined(TARGET_WORDS_BIGENDIAN)
|
|
213 |
p[offset] = value >> 8; |
|
214 |
p[offset + 1] = value; |
|
215 |
#else
|
|
216 |
p[offset] = value; |
|
217 |
p[offset + 1] = value >> 8; |
|
218 |
#endif
|
|
212 |
if (be) {
|
|
213 |
p[offset] = value >> 8;
|
|
214 |
p[offset + 1] = value;
|
|
215 |
} else {
|
|
216 |
p[offset] = value;
|
|
217 |
p[offset + 1] = value >> 8;
|
|
218 |
}
|
|
219 | 219 |
break; |
220 | 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
|
|
221 |
if (be) {
|
|
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 |
}
|
|
232 | 232 |
break; |
233 | 233 |
} |
234 | 234 |
|
235 | 235 |
} |
236 | 236 |
|
237 | 237 |
static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, |
238 |
uint32_t value, int width) |
|
238 |
uint32_t value, int width, int be)
|
|
239 | 239 |
{ |
240 | 240 |
uint8_t *p; |
241 | 241 |
uint8_t cmd; |
... | ... | |
304 | 304 |
case 0x10: /* Single Byte Program */ |
305 | 305 |
case 0x40: /* Single Byte Program */ |
306 | 306 |
DPRINTF("%s: Single Byte Program\n", __func__); |
307 |
pflash_data_write(pfl, offset, value, width); |
|
307 |
pflash_data_write(pfl, offset, value, width, be);
|
|
308 | 308 |
pflash_update(pfl, offset, width); |
309 | 309 |
pfl->status |= 0x80; /* Ready! */ |
310 | 310 |
pfl->wcycle = 0; |
... | ... | |
353 | 353 |
case 2: |
354 | 354 |
switch (pfl->cmd) { |
355 | 355 |
case 0xe8: /* Block write */ |
356 |
pflash_data_write(pfl, offset, value, width); |
|
356 |
pflash_data_write(pfl, offset, value, width, be);
|
|
357 | 357 |
|
358 | 358 |
pfl->status |= 0x80; |
359 | 359 |
|
... | ... | |
412 | 412 |
} |
413 | 413 |
|
414 | 414 |
|
415 |
static uint32_t pflash_readb (void *opaque, target_phys_addr_t addr) |
|
415 |
static uint32_t pflash_readb_be(void *opaque, target_phys_addr_t addr) |
|
416 |
{ |
|
417 |
return pflash_read(opaque, addr, 1, 1); |
|
418 |
} |
|
419 |
|
|
420 |
static uint32_t pflash_readb_le(void *opaque, target_phys_addr_t addr) |
|
421 |
{ |
|
422 |
return pflash_read(opaque, addr, 1, 0); |
|
423 |
} |
|
424 |
|
|
425 |
static uint32_t pflash_readw_be(void *opaque, target_phys_addr_t addr) |
|
426 |
{ |
|
427 |
pflash_t *pfl = opaque; |
|
428 |
|
|
429 |
return pflash_read(pfl, addr, 2, 1); |
|
430 |
} |
|
431 |
|
|
432 |
static uint32_t pflash_readw_le(void *opaque, target_phys_addr_t addr) |
|
416 | 433 |
{ |
417 |
return pflash_read(opaque, addr, 1); |
|
434 |
pflash_t *pfl = opaque; |
|
435 |
|
|
436 |
return pflash_read(pfl, addr, 2, 0); |
|
418 | 437 |
} |
419 | 438 |
|
420 |
static uint32_t pflash_readw (void *opaque, target_phys_addr_t addr)
|
|
439 |
static uint32_t pflash_readl_be(void *opaque, target_phys_addr_t addr)
|
|
421 | 440 |
{ |
422 | 441 |
pflash_t *pfl = opaque; |
423 | 442 |
|
424 |
return pflash_read(pfl, addr, 2);
|
|
443 |
return pflash_read(pfl, addr, 4, 1);
|
|
425 | 444 |
} |
426 | 445 |
|
427 |
static uint32_t pflash_readl (void *opaque, target_phys_addr_t addr)
|
|
446 |
static uint32_t pflash_readl_le(void *opaque, target_phys_addr_t addr)
|
|
428 | 447 |
{ |
429 | 448 |
pflash_t *pfl = opaque; |
430 | 449 |
|
431 |
return pflash_read(pfl, addr, 4); |
|
450 |
return pflash_read(pfl, addr, 4, 0);
|
|
432 | 451 |
} |
433 | 452 |
|
434 |
static void pflash_writeb (void *opaque, target_phys_addr_t addr,
|
|
435 |
uint32_t value) |
|
453 |
static void pflash_writeb_be(void *opaque, target_phys_addr_t addr,
|
|
454 |
uint32_t value)
|
|
436 | 455 |
{ |
437 |
pflash_write(opaque, addr, value, 1); |
|
456 |
pflash_write(opaque, addr, value, 1, 1);
|
|
438 | 457 |
} |
439 | 458 |
|
440 |
static void pflash_writew (void *opaque, target_phys_addr_t addr, |
|
441 |
uint32_t value) |
|
459 |
static void pflash_writeb_le(void *opaque, target_phys_addr_t addr, |
|
460 |
uint32_t value) |
|
461 |
{ |
|
462 |
pflash_write(opaque, addr, value, 1, 0); |
|
463 |
} |
|
464 |
|
|
465 |
static void pflash_writew_be(void *opaque, target_phys_addr_t addr, |
|
466 |
uint32_t value) |
|
442 | 467 |
{ |
443 | 468 |
pflash_t *pfl = opaque; |
444 | 469 |
|
445 |
pflash_write(pfl, addr, value, 2); |
|
470 |
pflash_write(pfl, addr, value, 2, 1);
|
|
446 | 471 |
} |
447 | 472 |
|
448 |
static void pflash_writel (void *opaque, target_phys_addr_t addr,
|
|
449 |
uint32_t value) |
|
473 |
static void pflash_writew_le(void *opaque, target_phys_addr_t addr,
|
|
474 |
uint32_t value)
|
|
450 | 475 |
{ |
451 | 476 |
pflash_t *pfl = opaque; |
452 | 477 |
|
453 |
pflash_write(pfl, addr, value, 4);
|
|
478 |
pflash_write(pfl, addr, value, 2, 0);
|
|
454 | 479 |
} |
455 | 480 |
|
456 |
static CPUWriteMemoryFunc * const pflash_write_ops[] = { |
|
457 |
&pflash_writeb, |
|
458 |
&pflash_writew, |
|
459 |
&pflash_writel, |
|
481 |
static void pflash_writel_be(void *opaque, target_phys_addr_t addr, |
|
482 |
uint32_t value) |
|
483 |
{ |
|
484 |
pflash_t *pfl = opaque; |
|
485 |
|
|
486 |
pflash_write(pfl, addr, value, 4, 1); |
|
487 |
} |
|
488 |
|
|
489 |
static void pflash_writel_le(void *opaque, target_phys_addr_t addr, |
|
490 |
uint32_t value) |
|
491 |
{ |
|
492 |
pflash_t *pfl = opaque; |
|
493 |
|
|
494 |
pflash_write(pfl, addr, value, 4, 0); |
|
495 |
} |
|
496 |
|
|
497 |
static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { |
|
498 |
&pflash_writeb_be, |
|
499 |
&pflash_writew_be, |
|
500 |
&pflash_writel_be, |
|
460 | 501 |
}; |
461 | 502 |
|
462 |
static CPUReadMemoryFunc * const pflash_read_ops[] = { |
|
463 |
&pflash_readb, |
|
464 |
&pflash_readw, |
|
465 |
&pflash_readl, |
|
503 |
static CPUReadMemoryFunc * const pflash_read_ops_be[] = { |
|
504 |
&pflash_readb_be, |
|
505 |
&pflash_readw_be, |
|
506 |
&pflash_readl_be, |
|
507 |
}; |
|
508 |
|
|
509 |
static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { |
|
510 |
&pflash_writeb_le, |
|
511 |
&pflash_writew_le, |
|
512 |
&pflash_writel_le, |
|
513 |
}; |
|
514 |
|
|
515 |
static CPUReadMemoryFunc * const pflash_read_ops_le[] = { |
|
516 |
&pflash_readb_le, |
|
517 |
&pflash_readw_le, |
|
518 |
&pflash_readl_le, |
|
466 | 519 |
}; |
467 | 520 |
|
468 | 521 |
/* Count trailing zeroes of a 32 bits quantity */ |
... | ... | |
503 | 556 |
BlockDriverState *bs, uint32_t sector_len, |
504 | 557 |
int nb_blocs, int width, |
505 | 558 |
uint16_t id0, uint16_t id1, |
506 |
uint16_t id2, uint16_t id3) |
|
559 |
uint16_t id2, uint16_t id3, |
|
560 |
int be) |
|
507 | 561 |
{ |
508 | 562 |
pflash_t *pfl; |
509 | 563 |
target_phys_addr_t total_len; |
... | ... | |
522 | 576 |
|
523 | 577 |
/* FIXME: Allocate ram ourselves. */ |
524 | 578 |
pfl->storage = qemu_get_ram_ptr(off); |
525 |
pfl->fl_mem = cpu_register_io_memory( |
|
526 |
pflash_read_ops, pflash_write_ops, pfl); |
|
579 |
if (be) { |
|
580 |
pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, |
|
581 |
pflash_write_ops_be, pfl); |
|
582 |
} else { |
|
583 |
pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, |
|
584 |
pflash_write_ops_le, pfl); |
|
585 |
} |
|
527 | 586 |
pfl->off = off; |
528 | 587 |
cpu_register_physical_memory(base, total_len, |
529 | 588 |
off | pfl->fl_mem | IO_MEM_ROMD); |
Also available in: Unified diff