All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] Non-contiguous IO map support for PREP
@ 2005-04-18  8:37 J. Mayer
  0 siblings, 0 replies; only message in thread
From: J. Mayer @ 2005-04-18  8:37 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 285 bytes --]

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 <l_indien@magic.fr>
Never organized

[-- Attachment #2: ppc_prep_IO.diff --]
[-- Type: text/x-patch, Size: 6433 bytes --]

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);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-04-18  8:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-18  8:37 [Qemu-devel] Non-contiguous IO map support for PREP J. Mayer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.