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 | 694 | s = pci_register_bus(); |
| 695 | 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 | 707 | PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, |
| 698 | 708 | PPC_PCIIO_write, s); |
| 699 | 709 | cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); | ... | ... |
hw/ppc_prep.c
| ... | ... | @@ -249,6 +249,7 @@ typedef struct sysctrl_t { |
| 249 | 249 | uint8_t state; |
| 250 | 250 | uint8_t syscontrol; |
| 251 | 251 | uint8_t fake_io[2]; |
| 252 | + int contiguous_map; | |
| 252 | 253 | } sysctrl_t; |
| 253 | 254 | |
| 254 | 255 | enum { |
| ... | ... | @@ -328,10 +329,7 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) |
| 328 | 329 | break; |
| 329 | 330 | case 0x0850: |
| 330 | 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 | 333 | break; |
| 336 | 334 | default: |
| 337 | 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 | 373 | /* Motorola base module extended feature register */ |
| 376 | 374 | retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */ |
| 377 | 375 | break; |
| 376 | + case 0x0814: | |
| 377 | + /* L2 invalidate: don't care */ | |
| 378 | + break; | |
| 378 | 379 | case 0x0818: |
| 379 | 380 | /* Keylock */ |
| 380 | 381 | retval = 0x00; |
| ... | ... | @@ -391,7 +392,7 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr) |
| 391 | 392 | break; |
| 392 | 393 | case 0x0850: |
| 393 | 394 | /* I/O map type register */ |
| 394 | - retval = 0x01; | |
| 395 | + retval = sysctrl->contiguous_map; | |
| 395 | 396 | break; |
| 396 | 397 | default: |
| 397 | 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 | 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 | 508 | extern CPUPPCState *global_env; |
| 406 | 509 | |
| 407 | 510 | #define NVRAM_SIZE 0x2000 |
| ... | ... | @@ -472,16 +575,18 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, |
| 472 | 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 | 580 | /* Set time-base frequency to 100 Mhz */ |
| 478 | 581 | cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); |
| 479 | 582 | |
| 480 | 583 | isa_mem_base = 0xc0000000; |
| 481 | 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 | 591 | /* init basic PC hardware */ |
| 487 | 592 | vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, | ... | ... |