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