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, |