summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2012-11-01 16:42:49 +0100
committerAurelien Jarno <aurelien@aurel32.net>2012-11-01 16:42:49 +0100
commit46a3f234134a708883c4ace95d739f6226bb17f0 (patch)
treed06a33ad6133dc0ecf7f46b2804d129bf424fb93 /hw
parent735c1eeb85450acd551c5990952f7ed8512d8547 (diff)
parent1ecbbab46925d4810fc35aba45cf93cb80ff0734 (diff)
downloadfocaccia-qemu-46a3f234134a708883c4ace95d739f6226bb17f0.tar.gz
focaccia-qemu-46a3f234134a708883c4ace95d739f6226bb17f0.zip
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
  pseries: Cleanup duplications of ics_valid_irq() code
  pseries: Clean up inconsistent variable name in xics.c
  target-ppc: Extend FPU state for newer POWER CPUs
  target-ppc: Rework storage of VPA registration state
  Revert "PPC: pseries: Remove hack for PIO window"
Diffstat (limited to 'hw')
-rw-r--r--hw/spapr_pci.c44
-rw-r--r--hw/spapr_pci.h2
-rw-r--r--hw/xics.c12
3 files changed, 49 insertions, 9 deletions
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index c2c3079d21..a08ed11166 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -439,6 +439,43 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
 }
 
+static uint64_t spapr_io_read(void *opaque, hwaddr addr,
+                              unsigned size)
+{
+    switch (size) {
+    case 1:
+        return cpu_inb(addr);
+    case 2:
+        return cpu_inw(addr);
+    case 4:
+        return cpu_inl(addr);
+    }
+    assert(0);
+}
+
+static void spapr_io_write(void *opaque, hwaddr addr,
+                           uint64_t data, unsigned size)
+{
+    switch (size) {
+    case 1:
+        cpu_outb(addr, data);
+        return;
+    case 2:
+        cpu_outw(addr, data);
+        return;
+    case 4:
+        cpu_outl(addr, data);
+        return;
+    }
+    assert(0);
+}
+
+static const MemoryRegionOps spapr_io_ops = {
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .read = spapr_io_read,
+    .write = spapr_io_write
+};
+
 /*
  * MSI/MSIX memory region implementation.
  * The handler handles both MSI and MSIX.
@@ -508,9 +545,14 @@ static int spapr_phb_init(SysBusDevice *s)
      * old_portion are updated */
     sprintf(namebuf, "%s.io", sphb->dtbusname);
     memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
+    /* FIXME: fix to support multiple PHBs */
+    memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);
 
+    sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
+    memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,
+                          namebuf, SPAPR_PCI_IO_WIN_SIZE);
     memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
-                                &sphb->iospace);
+                                &sphb->iowindow);
 
     /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
      * we need to allocate some memory to catch those writes coming
diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h
index a77d7d5448..e307ac8035 100644
--- a/hw/spapr_pci.h
+++ b/hw/spapr_pci.h
@@ -44,7 +44,7 @@ typedef struct sPAPRPHBState {
     MemoryRegion memspace, iospace;
     hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
     hwaddr msi_win_addr;
-    MemoryRegion memwindow, msiwindow;
+    MemoryRegion memwindow, iowindow, msiwindow;
 
     uint32_t dma_liobn;
     uint64_t dma_window_start;
diff --git a/hw/xics.c b/hw/xics.c
index ce88aa750b..ff4b5e210f 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -108,13 +108,13 @@ static void icp_set_cppr(struct icp_state *icp, int server, uint8_t cppr)
     }
 }
 
-static void icp_set_mfrr(struct icp_state *icp, int nr, uint8_t mfrr)
+static void icp_set_mfrr(struct icp_state *icp, int server, uint8_t mfrr)
 {
-    struct icp_server_state *ss = icp->ss + nr;
+    struct icp_server_state *ss = icp->ss + server;
 
     ss->mfrr = mfrr;
     if (mfrr < CPPR(ss)) {
-        icp_check_ipi(icp, nr);
+        icp_check_ipi(icp, server);
     }
 }
 
@@ -326,8 +326,7 @@ static void ics_eoi(struct ics_state *ics, int nr)
 
 qemu_irq xics_get_qirq(struct icp_state *icp, int irq)
 {
-    if ((irq < icp->ics->offset)
-        || (irq >= (icp->ics->offset + icp->ics->nr_irqs))) {
+    if (!ics_valid_irq(icp->ics, irq)) {
         return NULL;
     }
 
@@ -336,8 +335,7 @@ qemu_irq xics_get_qirq(struct icp_state *icp, int irq)
 
 void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi)
 {
-    assert((irq >= icp->ics->offset)
-           && (irq < (icp->ics->offset + icp->ics->nr_irqs)));
+    assert(ics_valid_irq(icp->ics, irq));
 
     icp->ics->irqs[irq - icp->ics->offset].lsi = lsi;
 }