Commit 4fbd24ba35ce80b23253002116d5a90df6d25b2c

Authored by balrog
1 parent 6725070d

Emulate address wrap in CFI02 chips mapping (Jan Kiszka).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4219 c046a42c-6fe2-441c-8c8c-71466251a162
hw/flash.h
... ... @@ -11,7 +11,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
11 11 /* pflash_cfi02.c */
12 12 pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
13 13 BlockDriverState *bs, uint32_t sector_len,
14   - int nb_blocs, int width,
  14 + int nb_blocs, int nb_mappings, int width,
15 15 uint16_t id0, uint16_t id1,
16 16 uint16_t id2, uint16_t id3,
17 17 uint16_t unlock_addr0, uint16_t unlock_addr1);
... ...
hw/pflash_cfi02.c
... ... @@ -55,7 +55,8 @@ struct pflash_t {
55 55 BlockDriverState *bs;
56 56 target_phys_addr_t base;
57 57 uint32_t sector_len;
58   - uint32_t total_len;
  58 + uint32_t chip_len;
  59 + int mappings;
59 60 int width;
60 61 int wcycle; /* if 0, the flash is read normally */
61 62 int bypass;
... ... @@ -72,6 +73,19 @@ struct pflash_t {
72 73 void *storage;
73 74 };
74 75  
  76 +static void pflash_register_memory(pflash_t *pfl, int rom_mode)
  77 +{
  78 + unsigned long phys_offset = pfl->fl_mem;
  79 + int i;
  80 +
  81 + if (rom_mode)
  82 + phys_offset |= pfl->off | IO_MEM_ROMD;
  83 +
  84 + for (i = 0; i < pfl->mappings; i++)
  85 + cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
  86 + pfl->chip_len, phys_offset);
  87 +}
  88 +
75 89 static void pflash_timer (void *opaque)
76 90 {
77 91 pflash_t *pfl = opaque;
... ... @@ -82,8 +96,7 @@ static void pflash_timer (void *opaque)
82 96 if (pfl->bypass) {
83 97 pfl->wcycle = 2;
84 98 } else {
85   - cpu_register_physical_memory(pfl->base, pfl->total_len,
86   - pfl->off | IO_MEM_ROMD | pfl->fl_mem);
  99 + pflash_register_memory(pfl, 1);
87 100 pfl->wcycle = 0;
88 101 }
89 102 pfl->cmd = 0;
... ... @@ -98,6 +111,7 @@ static uint32_t pflash_read (pflash_t *pfl, uint32_t offset, int width)
98 111 DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset);
99 112 ret = -1;
100 113 offset -= pfl->base;
  114 + offset &= pfl->chip_len - 1;
101 115 boff = offset & 0xFF;
102 116 if (pfl->width == 2)
103 117 boff = boff >> 1;
... ... @@ -226,11 +240,10 @@ static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
226 240 offset -= (uint32_t)(long)pfl->storage;
227 241 else
228 242 offset -= pfl->base;
  243 + offset &= pfl->chip_len - 1;
229 244  
230 245 DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__,
231 246 offset, value, width);
232   - /* Set the device in I/O access mode */
233   - cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
234 247 boff = offset & (pfl->sector_len - 1);
235 248 if (pfl->width == 2)
236 249 boff = boff >> 1;
... ... @@ -238,6 +251,8 @@ static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
238 251 boff = boff >> 2;
239 252 switch (pfl->wcycle) {
240 253 case 0:
  254 + /* Set the device in I/O access mode */
  255 + pflash_register_memory(pfl, 0);
241 256 /* We're in read mode */
242 257 check_unlock0:
243 258 if (boff == 0x55 && cmd == 0x98) {
... ... @@ -369,9 +384,9 @@ static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
369 384 }
370 385 /* Chip erase */
371 386 DPRINTF("%s: start chip erase\n", __func__);
372   - memset(pfl->storage, 0xFF, pfl->total_len);
  387 + memset(pfl->storage, 0xFF, pfl->chip_len);
373 388 pfl->status = 0x00;
374   - pflash_update(pfl, 0, pfl->total_len);
  389 + pflash_update(pfl, 0, pfl->chip_len);
375 390 /* Let's wait 5 seconds before chip erase is done */
376 391 qemu_mod_timer(pfl->timer,
377 392 qemu_get_clock(vm_clock) + (ticks_per_sec * 5));
... ... @@ -424,8 +439,7 @@ static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
424 439  
425 440 /* Reset flash */
426 441 reset_flash:
427   - cpu_register_physical_memory(pfl->base, pfl->total_len,
428   - pfl->off | IO_MEM_ROMD | pfl->fl_mem);
  442 + pflash_register_memory(pfl, 1);
429 443 pfl->bypass = 0;
430 444 pfl->wcycle = 0;
431 445 pfl->cmd = 0;
... ... @@ -527,15 +541,15 @@ static int ctz32 (uint32_t n)
527 541  
528 542 pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
529 543 BlockDriverState *bs, uint32_t sector_len,
530   - int nb_blocs, int width,
  544 + int nb_blocs, int nb_mappings, int width,
531 545 uint16_t id0, uint16_t id1,
532 546 uint16_t id2, uint16_t id3,
533 547 uint16_t unlock_addr0, uint16_t unlock_addr1)
534 548 {
535 549 pflash_t *pfl;
536   - int32_t total_len;
  550 + int32_t chip_len;
537 551  
538   - total_len = sector_len * nb_blocs;
  552 + chip_len = sector_len * nb_blocs;
539 553 /* XXX: to be fixed */
540 554 #if 0
541 555 if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
... ... @@ -549,12 +563,14 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
549 563 pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops,
550 564 pfl);
551 565 pfl->off = off;
552   - cpu_register_physical_memory(base, total_len,
553   - off | pfl->fl_mem | IO_MEM_ROMD);
  566 + pfl->base = base;
  567 + pfl->chip_len = chip_len;
  568 + pfl->mappings = nb_mappings;
  569 + pflash_register_memory(pfl, 1);
554 570 pfl->bs = bs;
555 571 if (pfl->bs) {
556 572 /* read the initial flash content */
557   - bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
  573 + bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
558 574 }
559 575 #if 0 /* XXX: there should be a bit to set up read-only,
560 576 * the same way the hardware does (with WP pin).
... ... @@ -564,9 +580,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
564 580 pfl->ro = 0;
565 581 #endif
566 582 pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl);
567   - pfl->base = base;
568 583 pfl->sector_len = sector_len;
569   - pfl->total_len = total_len;
570 584 pfl->width = width;
571 585 pfl->wcycle = 0;
572 586 pfl->cmd = 0;
... ... @@ -620,7 +634,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
620 634 /* Max timeout for chip erase */
621 635 pfl->cfi_table[0x26] = 0x0D;
622 636 /* Device size */
623   - pfl->cfi_table[0x27] = ctz32(total_len) + 1;
  637 + pfl->cfi_table[0x27] = ctz32(chip_len) + 1;
624 638 /* Flash device interface (8 & 16 bits) */
625 639 pfl->cfi_table[0x28] = 0x02;
626 640 pfl->cfi_table[0x29] = 0x00;
... ...
hw/ppc405_boards.c
... ... @@ -235,8 +235,8 @@ static void ref405ep_init (int ram_size, int vga_ram_size,
235 235 bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
236 236 #endif
237 237 pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
238   - drives_table[index].bdrv, 65536, fl_sectors, 2,
239   - 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
  238 + drives_table[index].bdrv, 65536, fl_sectors, 1,
  239 + 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
240 240 fl_idx++;
241 241 } else
242 242 #endif
... ... @@ -552,8 +552,8 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size,
552 552 bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
553 553 #endif
554 554 pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
555   - drives_table[index].bdrv, 65536, fl_sectors, 4,
556   - 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
  555 + drives_table[index].bdrv, 65536, fl_sectors, 1,
  556 + 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
557 557 fl_idx++;
558 558 } else
559 559 #endif
... ... @@ -588,8 +588,8 @@ static void taihu_405ep_init(int ram_size, int vga_ram_size,
588 588 bdrv_get_device_name(drives_table[index].bdrv));
589 589 #endif
590 590 pflash_cfi02_register(0xfc000000, bios_offset,
591   - drives_table[index].bdrv, 65536, fl_sectors, 4,
592   - 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
  591 + drives_table[index].bdrv, 65536, fl_sectors, 1,
  592 + 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
593 593 fl_idx++;
594 594 }
595 595 /* Register CLPD & LCD display */
... ...