Commit da9b266bb8491fd41badfff8ae1772007602dcca

Authored by bellard
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,
... ...