Commit da9b266bb8491fd41badfff8ae1772007602dcca
1 parent
dccfafc4
PREP machines have two IO mappings.
This patch adds support for non-contiguous IO map, which is used by OS/2. It also adds the missing legacy IO ports for the PREP PCI bridge and changes CPU PVR from 74x/75x to 604 to make OS/2 happy. (Jocelyn Mayer) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1381 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
125 additions
and
10 deletions
hw/pci.c
| @@ -694,6 +694,16 @@ PCIBus *pci_prep_init(void) | @@ -694,6 +694,16 @@ PCIBus *pci_prep_init(void) | ||
| 694 | s = pci_register_bus(); | 694 | s = pci_register_bus(); |
| 695 | s->set_irq = prep_set_irq; | 695 | s->set_irq = prep_set_irq; |
| 696 | 696 | ||
| 697 | + register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s); | ||
| 698 | + register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s); | ||
| 699 | + | ||
| 700 | + register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s); | ||
| 701 | + register_ioport_write(0xcfc, 4, 2, pci_data_writew, s); | ||
| 702 | + register_ioport_write(0xcfc, 4, 4, pci_data_writel, s); | ||
| 703 | + register_ioport_read(0xcfc, 4, 1, pci_data_readb, s); | ||
| 704 | + register_ioport_read(0xcfc, 4, 2, pci_data_readw, s); | ||
| 705 | + register_ioport_read(0xcfc, 4, 4, pci_data_readl, s); | ||
| 706 | + | ||
| 697 | PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, | 707 | PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, |
| 698 | PPC_PCIIO_write, s); | 708 | PPC_PCIIO_write, s); |
| 699 | cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); | 709 | cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); |
hw/ppc_prep.c
| @@ -249,6 +249,7 @@ typedef struct sysctrl_t { | @@ -249,6 +249,7 @@ typedef struct sysctrl_t { | ||
| 249 | uint8_t state; | 249 | uint8_t state; |
| 250 | uint8_t syscontrol; | 250 | uint8_t syscontrol; |
| 251 | uint8_t fake_io[2]; | 251 | uint8_t fake_io[2]; |
| 252 | + int contiguous_map; | ||
| 252 | } sysctrl_t; | 253 | } sysctrl_t; |
| 253 | 254 | ||
| 254 | enum { | 255 | enum { |
| @@ -328,10 +329,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) | @@ -328,10 +329,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) | ||
| 328 | break; | 329 | break; |
| 329 | case 0x0850: | 330 | case 0x0850: |
| 330 | /* I/O map type register */ | 331 | /* I/O map type register */ |
| 331 | - if (!(val & 0x01)) { | ||
| 332 | - printf("No support for non-continuous I/O map mode\n"); | ||
| 333 | - abort(); | ||
| 334 | - } | 332 | + sysctrl->contiguous_map = val & 0x01; |
| 335 | break; | 333 | break; |
| 336 | default: | 334 | default: |
| 337 | printf("ERROR: unaffected IO port write: %04lx => %02x\n", | 335 | printf("ERROR: unaffected IO port write: %04lx => %02x\n", |
| @@ -375,6 +373,9 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | @@ -375,6 +373,9 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | ||
| 375 | /* Motorola base module extended feature register */ | 373 | /* Motorola base module extended feature register */ |
| 376 | retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */ | 374 | retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */ |
| 377 | break; | 375 | break; |
| 376 | + case 0x0814: | ||
| 377 | + /* L2 invalidate: don't care */ | ||
| 378 | + break; | ||
| 378 | case 0x0818: | 379 | case 0x0818: |
| 379 | /* Keylock */ | 380 | /* Keylock */ |
| 380 | retval = 0x00; | 381 | retval = 0x00; |
| @@ -391,7 +392,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | @@ -391,7 +392,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | ||
| 391 | break; | 392 | break; |
| 392 | case 0x0850: | 393 | case 0x0850: |
| 393 | /* I/O map type register */ | 394 | /* I/O map type register */ |
| 394 | - retval = 0x01; | 395 | + retval = sysctrl->contiguous_map; |
| 395 | break; | 396 | break; |
| 396 | default: | 397 | default: |
| 397 | printf("ERROR: unaffected IO port: %04lx read\n", (long)addr); | 398 | printf("ERROR: unaffected IO port: %04lx read\n", (long)addr); |
| @@ -402,6 +403,108 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | @@ -402,6 +403,108 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) | ||
| 402 | return retval; | 403 | return retval; |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 406 | +static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl, | ||
| 407 | + target_phys_addr_t addr) | ||
| 408 | +{ | ||
| 409 | + if (sysctrl->contiguous_map == 0) { | ||
| 410 | + /* 64 KB contiguous space for IOs */ | ||
| 411 | + addr &= 0xFFFF; | ||
| 412 | + } else { | ||
| 413 | + /* 8 MB non-contiguous space for IOs */ | ||
| 414 | + addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7); | ||
| 415 | + } | ||
| 416 | + | ||
| 417 | + return addr; | ||
| 418 | +} | ||
| 419 | + | ||
| 420 | +static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr, | ||
| 421 | + uint32_t value) | ||
| 422 | +{ | ||
| 423 | + sysctrl_t *sysctrl = opaque; | ||
| 424 | + | ||
| 425 | + addr = prep_IO_address(sysctrl, addr); | ||
| 426 | + cpu_outb(NULL, addr, value); | ||
| 427 | +} | ||
| 428 | + | ||
| 429 | +static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr) | ||
| 430 | +{ | ||
| 431 | + sysctrl_t *sysctrl = opaque; | ||
| 432 | + uint32_t ret; | ||
| 433 | + | ||
| 434 | + addr = prep_IO_address(sysctrl, addr); | ||
| 435 | + ret = cpu_inb(NULL, addr); | ||
| 436 | + | ||
| 437 | + return ret; | ||
| 438 | +} | ||
| 439 | + | ||
| 440 | +static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr, | ||
| 441 | + uint32_t value) | ||
| 442 | +{ | ||
| 443 | + sysctrl_t *sysctrl = opaque; | ||
| 444 | + | ||
| 445 | + addr = prep_IO_address(sysctrl, addr); | ||
| 446 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 447 | + value = bswap16(value); | ||
| 448 | +#endif | ||
| 449 | + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value); | ||
| 450 | + cpu_outw(NULL, addr, value); | ||
| 451 | +} | ||
| 452 | + | ||
| 453 | +static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr) | ||
| 454 | +{ | ||
| 455 | + sysctrl_t *sysctrl = opaque; | ||
| 456 | + uint32_t ret; | ||
| 457 | + | ||
| 458 | + addr = prep_IO_address(sysctrl, addr); | ||
| 459 | + ret = cpu_inw(NULL, addr); | ||
| 460 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 461 | + ret = bswap16(ret); | ||
| 462 | +#endif | ||
| 463 | + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret); | ||
| 464 | + | ||
| 465 | + return ret; | ||
| 466 | +} | ||
| 467 | + | ||
| 468 | +static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr, | ||
| 469 | + uint32_t value) | ||
| 470 | +{ | ||
| 471 | + sysctrl_t *sysctrl = opaque; | ||
| 472 | + | ||
| 473 | + addr = prep_IO_address(sysctrl, addr); | ||
| 474 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 475 | + value = bswap32(value); | ||
| 476 | +#endif | ||
| 477 | + PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value); | ||
| 478 | + cpu_outl(NULL, addr, value); | ||
| 479 | +} | ||
| 480 | + | ||
| 481 | +static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr) | ||
| 482 | +{ | ||
| 483 | + sysctrl_t *sysctrl = opaque; | ||
| 484 | + uint32_t ret; | ||
| 485 | + | ||
| 486 | + addr = prep_IO_address(sysctrl, addr); | ||
| 487 | + ret = cpu_inl(NULL, addr); | ||
| 488 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 489 | + ret = bswap32(ret); | ||
| 490 | +#endif | ||
| 491 | + PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret); | ||
| 492 | + | ||
| 493 | + return ret; | ||
| 494 | +} | ||
| 495 | + | ||
| 496 | +CPUWriteMemoryFunc *PPC_prep_io_write[] = { | ||
| 497 | + &PPC_prep_io_writeb, | ||
| 498 | + &PPC_prep_io_writew, | ||
| 499 | + &PPC_prep_io_writel, | ||
| 500 | +}; | ||
| 501 | + | ||
| 502 | +CPUReadMemoryFunc *PPC_prep_io_read[] = { | ||
| 503 | + &PPC_prep_io_readb, | ||
| 504 | + &PPC_prep_io_readw, | ||
| 505 | + &PPC_prep_io_readl, | ||
| 506 | +}; | ||
| 507 | + | ||
| 405 | extern CPUPPCState *global_env; | 508 | extern CPUPPCState *global_env; |
| 406 | 509 | ||
| 407 | #define NVRAM_SIZE 0x2000 | 510 | #define NVRAM_SIZE 0x2000 |
| @@ -472,16 +575,18 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | @@ -472,16 +575,18 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | ||
| 472 | initrd_size = 0; | 575 | initrd_size = 0; |
| 473 | } | 576 | } |
| 474 | 577 | ||
| 475 | - /* Register CPU as a 74x/75x */ | ||
| 476 | - cpu_ppc_register(cpu_single_env, 0x00080000); | 578 | + /* Register CPU as a 604 */ |
| 579 | + cpu_ppc_register(cpu_single_env, 0x00040000); | ||
| 477 | /* Set time-base frequency to 100 Mhz */ | 580 | /* Set time-base frequency to 100 Mhz */ |
| 478 | cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); | 581 | cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); |
| 479 | 582 | ||
| 480 | isa_mem_base = 0xc0000000; | 583 | isa_mem_base = 0xc0000000; |
| 481 | pci_bus = pci_prep_init(); | 584 | pci_bus = pci_prep_init(); |
| 482 | - /* Register 64 KB of ISA IO space */ | ||
| 483 | - PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); | ||
| 484 | - cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory); | 585 | + // pci_bus = i440fx_init(); |
| 586 | + /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ | ||
| 587 | + PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read, | ||
| 588 | + PPC_prep_io_write, sysctrl); | ||
| 589 | + cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory); | ||
| 485 | 590 | ||
| 486 | /* init basic PC hardware */ | 591 | /* init basic PC hardware */ |
| 487 | vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, | 592 | vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, |