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.

-- 
J. Mayer <[EMAIL PROTECTED]>
Never organized
Index: hw/ppc_prep.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/ppc_prep.c,v
retrieving revision 1.16
diff -u -d -w -B -b -d -p -r1.16 ppc_prep.c
--- hw/ppc_prep.c	24 Aug 2004 21:13:40 -0000	1.16
+++ hw/ppc_prep.c	18 Apr 2005 07:59:15 -0000
@@ -249,6 +249,7 @@ typedef struct sysctrl_t {
     uint8_t state;
     uint8_t syscontrol;
     uint8_t fake_io[2];
+    int contiguous_map;
 } sysctrl_t;
 
 enum {
@@ -328,10 +332,7 @@ static void PREP_io_800_writeb (void *op
         break;
     case 0x0850:
         /* I/O map type register */
-        if (!(val & 0x01)) {
-            printf("No support for non-continuous I/O map mode\n");
-            abort();
-        }
+        sysctrl->contiguous_map = val & 0x01;
         break;
     default:
         printf("ERROR: unaffected IO port write: %04lx => %02x\n",
@@ -375,6 +376,9 @@ static uint32_t PREP_io_800_readb (void 
         /* Motorola base module extended feature register */
         retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
         break;
+    case 0x0814:
+        /* L2 invalidate: don't care */
+        break;
     case 0x0818:
         /* Keylock */
         retval = 0x00;
@@ -391,7 +395,7 @@ static uint32_t PREP_io_800_readb (void 
         break;
     case 0x0850:
         /* I/O map type register */
-        retval = 0x01;
+        retval = sysctrl->contiguous_map;
         break;
     default:
         printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
@@ -402,6 +406,108 @@ static uint32_t PREP_io_800_readb (void 
     return retval;
 }
 
+static inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
+                                                  target_phys_addr_t addr)
+{
+    if (sysctrl->contiguous_map == 0) {
+        /* 64 KB contiguous space for IOs */
+        addr &= 0xFFFF;
+    } else {
+        /* 8 MB non-contiguous space for IOs */
+        addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
+    }
+
+    return addr;
+}
+
+static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    addr = prep_IO_address(sysctrl, addr);
+    cpu_outb(NULL, addr, value);
+}
+
+static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
+{
+    sysctrl_t *sysctrl = opaque;
+    uint32_t ret;
+
+    addr = prep_IO_address(sysctrl, addr);
+    ret = cpu_inb(NULL, addr);
+
+    return ret;
+}
+
+static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    addr = prep_IO_address(sysctrl, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
+    cpu_outw(NULL, addr, value);
+}
+
+static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
+{
+    sysctrl_t *sysctrl = opaque;
+    uint32_t ret;
+
+    addr = prep_IO_address(sysctrl, addr);
+    ret = cpu_inw(NULL, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap16(ret);
+#endif
+    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
+
+    return ret;
+}
+
+static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    addr = prep_IO_address(sysctrl, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr, value);
+    cpu_outl(NULL, addr, value);
+}
+
+static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
+{
+    sysctrl_t *sysctrl = opaque;
+    uint32_t ret;
+
+    addr = prep_IO_address(sysctrl, addr);
+    ret = cpu_inl(NULL, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap32(ret);
+#endif
+    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr, ret);
+
+    return ret;
+}
+
+CPUWriteMemoryFunc *PPC_prep_io_write[] = {
+    &PPC_prep_io_writeb,
+    &PPC_prep_io_writew,
+    &PPC_prep_io_writel,
+};
+
+CPUReadMemoryFunc *PPC_prep_io_read[] = {
+    &PPC_prep_io_readb,
+    &PPC_prep_io_readw,
+    &PPC_prep_io_readl,
+};
+
 extern CPUPPCState *global_env;
 
 #define NVRAM_SIZE        0x2000
@@ -472,16 +580,18 @@ void ppc_prep_init(int ram_size, int vga
         initrd_size = 0;
     }
 
-    /* Register CPU as a 74x/75x */
-    cpu_ppc_register(cpu_single_env, 0x00080000);
+    /* Register CPU as a 604 */
+    cpu_ppc_register(cpu_single_env, 0x00040000);
     /* Set time-base frequency to 100 Mhz */
     cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
 
     isa_mem_base = 0xc0000000;
     pci_bus = pci_prep_init();
-    /* Register 64 KB of ISA IO space */
-    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
-    cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory);
+    //    pci_bus = i440fx_init();
+    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
+    PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
+                                           PPC_prep_io_write, sysctrl);
+    cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
 
     /* init basic PC hardware */
     vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
Index: hw/pci.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/pci.c,v
retrieving revision 1.16
diff -u -d -w -B -b -d -p -r1.16 pci.c
--- hw/pci.c	6 Apr 2005 23:00:25 -0000	1.16
+++ hw/pci.c	18 Apr 2005 07:59:15 -0000
@@ -694,6 +702,16 @@ PCIBus *pci_prep_init(void)
     s = pci_register_bus();
     s->set_irq = prep_set_irq;
 
+    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
+    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
+
+    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
+    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
+    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
+    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
+    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
+    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
+
     PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, 
                                            PPC_PCIIO_write, s);
     cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to