All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
@ 2009-01-15 12:34 ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm-ppc

This patchset enable the support of MPC85xx platform in qemu/kvm.

patch 1,2: bug fix
patch 3: enable mpic for E500 core.
patch 4: enable E500 mmu in kvm mode.
patch 5: add E500 pci controller emulation.
patch 6: add E500 irq support
patch 7: add E500 core emulation
patch 8: extern one function for E500 code use
patch 9: add MPC85xx boards emulation.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
@ 2009-01-15 12:34 ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm-ppc

This patchset enable the support of MPC85xx platform in qemu/kvm.

patch 1,2: bug fix
patch 3: enable mpic for E500 core.
patch 4: enable E500 mmu in kvm mode.
patch 5: add E500 pci controller emulation.
patch 6: add E500 irq support
patch 7: add E500 core emulation
patch 8: extern one function for E500 code use
patch 9: add MPC85xx boards emulation.



^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 1/9] powerpc/kvm: Fix a uninitialized bug
  2009-01-15 12:34 ` Liu Yu
@ 2009-01-15 12:34   ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/kvm_ppc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 0caa5b9..f7ce52b 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -27,7 +27,7 @@ static int kvmppc_read_host_property(const char *node_path, const char *prop,
 {
     char *path;
     FILE *f;
-    int ret;
+    int ret = 0;
     int pathlen;
 
     pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 1/9] powerpc/kvm: Fix a uninitialized bug
@ 2009-01-15 12:34   ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/kvm_ppc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 0caa5b9..f7ce52b 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -27,7 +27,7 @@ static int kvmppc_read_host_property(const char *node_path, const char *prop,
 {
     char *path;
     FILE *f;
-    int ret;
+    int ret = 0;
     int pathlen;
 
     pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 2/9] powerpc/kvm: fix a openpic bug
  2009-01-15 12:34   ` Liu Yu
@ 2009-01-15 12:34     ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

An external interrupt should not interrupted in-servicing interrupt with equal priority.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/openpic.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/openpic.c b/hw/openpic.c
index def20eb..b8da4d7 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -279,7 +279,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
     }
     IRQ_get_next(opp, &dst->raised);
     if (IRQ_get_next(opp, &dst->servicing) != -1 &&
-        priority < dst->servicing.priority) {
+        priority <= dst->servicing.priority) {
         DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
                 __func__, n_IRQ, dst->servicing.next, n_CPU);
         /* Already servicing a higher priority IRQ */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 2/9] powerpc/kvm: fix a openpic bug
@ 2009-01-15 12:34     ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

An external interrupt should not interrupted in-servicing interrupt with equal priority.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/openpic.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/openpic.c b/hw/openpic.c
index def20eb..b8da4d7 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -279,7 +279,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
     }
     IRQ_get_next(opp, &dst->raised);
     if (IRQ_get_next(opp, &dst->servicing) != -1 &&
-        priority < dst->servicing.priority) {
+        priority <= dst->servicing.priority) {
         DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
                 __func__, n_IRQ, dst->servicing.next, n_CPU);
         /* Already servicing a higher priority IRQ */
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
  2009-01-15 12:34     ` Liu Yu
@ 2009-01-15 12:34       ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

The modify is based on original author's method
to switch openpic and mpic by static define,
like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
(Although the support for intel has broken)
So they can't be used at the same time.

I guess it's not the correct way to do this.
but I am not sure is the USE_MPC85xx and openpic are still needed?

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/openpic.c |  384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 hw/openpic.h |   19 +++
 hw/ppc_mac.h |   14 +--
 3 files changed, 389 insertions(+), 28 deletions(-)
 create mode 100644 hw/openpic.h

diff --git a/hw/openpic.c b/hw/openpic.c
index b8da4d7..bc5f72b 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -35,6 +35,7 @@
 #include "hw.h"
 #include "ppc_mac.h"
 #include "pci.h"
+#include "openpic.h"
 
 //#define DEBUG_OPENPIC
 
@@ -45,7 +46,8 @@
 #endif
 #define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
 
-#define USE_MPCxxx /* Intel model is broken, for now */
+/*#define USE_MPCxxx |+ Intel model is broken, for now +|*/
+#define USE_MPC85xx /* Intel model is broken, for now */
 
 #if defined (USE_INTEL_GW80314)
 /* Intel GW80314 I/O Companion chip */
@@ -84,15 +86,6 @@ enum {
 #define OPENPIC_LITTLE_ENDIAN 1
 #define OPENPIC_BIG_ENDIAN    0
 
-#else
-#error "Please select which OpenPic implementation is to be emulated"
-#endif
-
-#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
-    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
-#define OPENPIC_SWAP
-#endif
-
 /* Interrupt definitions */
 #define IRQ_FE     (EXT_IRQ)     /* Internal functional IRQ */
 #define IRQ_ERR    (EXT_IRQ + 1) /* Error IRQ */
@@ -105,6 +98,61 @@ enum {
 #define IRQ_MBX0   (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
 #endif
 
+#elif defined(USE_MPC85xx)
+
+#define MPIC_MAP_SIZE	0x40000
+
+#define MAX_CPU     1
+#define MAX_EXT    12
+#define MAX_INT    64
+#define MAX_DBL     0
+#define MAX_MBX     0
+#define MAX_TMR     4
+#define MAX_MSG     4
+#define MAX_MSI     8
+#define MAX_IPI     4
+#define MAX_IRQ    (MAX_EXT + MAX_INT + MAX_TMR + MAX_MSG + MAX_MSI + (MAX_IPI * MAX_CPU))
+
+#define VECTOR_BITS 8
+#define VID         0x0 /* MPIC version ID */
+#define VENI        0x00000000 /* Vendor ID */
+
+enum {
+    IRQ_IPVP = 0,
+    IRQ_IDE,
+};
+
+enum ide_bits {
+    IDR_EP     = 0,
+    IDR_CI0     = 1,
+    IDR_CI1     = 2,
+    IDR_P1     = 30,
+    IDR_P0     = 31,
+};
+
+#define OPENPIC_LITTLE_ENDIAN 0
+#define OPENPIC_BIG_ENDIAN    1
+
+/* Interrupt definitions */
+#define EXT_IRQ		0
+#define INT_IRQ		(EXT_IRQ + MAX_EXT)
+#define TMR_IRQ		(INT_IRQ + MAX_INT)
+#define MSG_IRQ		(TMR_IRQ + MAX_TMR)
+#define MSI_IRQ		(MSG_IRQ + MAX_MSG)
+#define IPI_IRQ		(MSI_IRQ + MAX_MSI)
+
+#define IRQ_IPI0        IPI_IRQ
+#define IRQ_TIM0        TMR_IRQ
+
+#else
+#error "Please select which OpenPic implementation is to be emulated"
+#endif
+
+#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
+    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
+#define OPENPIC_SWAP
+#endif
+
 #define BF_WIDTH(_bits_) \
 (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
 
@@ -157,6 +205,7 @@ enum IPVP_bits {
 #define IPVP_VECTOR(_ipvpr_)   ((_ipvpr_) & IPVP_VECTOR_MASK)
 
 typedef struct IRQ_dst_t {
+    uint32_t tfrr;
     uint32_t pctp; /* CPU current task priority */
     uint32_t pcsr; /* CPU sensitivity register */
     IRQ_queue_t raised;
@@ -200,6 +249,8 @@ typedef struct openpic_t {
 #endif
     /* IRQ out is used when in bypass mode (not implemented) */
     qemu_irq irq_out;
+    void (*reset) (struct openpic_t *);
+    void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *);
 } openpic_t;
 
 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
@@ -286,7 +337,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
         return;
     }
     DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
-    qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
+    opp->irq_raise(opp, n_CPU, src);
 }
 
 /* update pic state because registers for n_IRQ have changed value */
@@ -551,8 +602,8 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
     case 0x00: /* FREP */
         break;
     case 0x20: /* GLBC */
-        if (val & 0x80000000)
-            openpic_reset(opp);
+        if (val & 0x80000000 && opp->reset)
+            opp->reset(opp);
         opp->glbc = val & ~0x80000000;
 	break;
     case 0x80: /* VENI */
@@ -818,7 +869,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
              IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
             DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
                     idx, n_IRQ);
-            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
+            opp->irq_raise(opp, idx, src);
         }
 	break;
     default:
@@ -1001,6 +1052,11 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
 #endif
 }
 
+static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
+{
+    qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+}
+
 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out)
 {
@@ -1058,9 +1114,307 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
     for (i = 0; i < nb_cpus; i++)
         opp->dst[i].irqs = irqs[i];
     opp->irq_out = irq_out;
-    openpic_reset(opp);
+
+    opp->irq_raise = openpic_irq_raise;
+    opp->reset = openpic_reset;
+
+    opp->reset(opp);
     if (pmem_index)
         *pmem_index = opp->mem_index;
 
     return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
 }
+
+static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
+{
+    int n_ci = IDR_CI0 - n_CPU;
+    DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
+		    n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
+    if(test_bit(&src->ide, n_ci)) {
+        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
+    }
+    else {
+        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+    }
+}
+
+static void mpic_reset (openpic_t *mpp)
+{
+    int i;
+
+    mpp->glbc = 0x80000000;
+    /* Initialise controller registers */
+    mpp->frep = 0x004f0002;
+    mpp->veni = VENI;
+    mpp->pint = 0x00000000;
+    mpp->spve = 0x0000FFFF;
+    /* Initialise IRQ sources */
+    for (i = 0; i < MAX_IRQ; i++) {
+	mpp->src[i].ipvp = 0x80800000;
+	mpp->src[i].ide  = 0x00000001;
+    }
+    /* Initialise IRQ destinations */
+    for (i = 0; i < MAX_CPU; i++) {
+	mpp->dst[i].pctp      = 0x0000000F;
+        mpp->dst[i].tfrr      = 0x00000000;
+	memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
+	mpp->dst[i].raised.next = -1;
+	memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
+	mpp->dst[i].servicing.next = -1;
+    }
+    /* Initialise timers */
+    for (i = 0; i < MAX_TMR; i++) {
+	mpp->timers[i].ticc = 0x00000000;
+	mpp->timers[i].tibc = 0x80000000;
+    }
+    /* Go out of RESET state */
+    mpp->glbc = 0x00000000;
+}
+
+static void mpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+    int idx, cpu;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined MPIC_SWAP
+    val = bswap32(val);
+#endif
+    addr &= 0xFFFF;
+    cpu = addr >> 12;
+    idx = (addr >> 6) & 0x3;
+    switch (addr & 0x30) {
+    case 0x00: /* gtccr */
+        break;
+    case 0x10: /* gtbcr */
+	if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
+	    (val & 0x80000000) == 0 &&
+            (mpp->timers[idx].tibc & 0x80000000) != 0)
+	    mpp->timers[idx].ticc &= ~0x80000000;
+	mpp->timers[idx].tibc = val;
+	break;
+    case 0x20: /* GTIVPR */
+	write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP, val);
+	break;
+    case 0x30: /* GTIDR & TFRR */
+	if ((addr & 0xF0) == 0xF0)
+            mpp->dst[cpu].tfrr = val;
+	else
+	    write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE, val);
+	break;
+    }
+}
+
+static uint32_t mpic_timer_read (void *opaque, uint32_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval;
+    int idx, cpu;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr &= 0xFFFF;
+    cpu = addr >> 12;
+    idx = (addr >> 6) & 0x3;
+    switch (addr & 0x30) {
+    case 0x00: /* gtccr */
+	retval = mpp->timers[idx].ticc;
+        break;
+    case 0x10: /* gtbcr */
+	retval = mpp->timers[idx].tibc;
+	break;
+    case 0x20: /* TIPV */
+	retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP);
+	break;
+    case 0x30: /* TIDR */
+        if ((addr &0xF0) == 0XF0)
+	    retval = mpp->dst[cpu].tfrr;
+	else
+	    retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE);
+	break;
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined MPIC_SWAP
+    retval = bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void mpic_src_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+    int idx;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined MPIC_SWAP
+    val = tswap32(val);
+#endif
+    addr = addr & 0xFFF0;
+    if (addr < 0x180) {
+	idx = EXT_IRQ;
+    } else if (addr >= 0x200 && addr < 0xa00) {
+	idx = INT_IRQ;
+	addr -= 0x200;
+    } else if (addr >= 0x1600 && addr < 0x1700) {
+	idx = MSG_IRQ;
+	addr -= 0x1600;
+    } else if (addr >= 0x1C00 && addr < 0x1D00) {
+	idx = MSI_IRQ;
+	addr -= 0x1C00;
+    } else {
+	return;
+    }
+    idx += addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        write_IRQreg(mpp, idx, IRQ_IDE, val);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        write_IRQreg(mpp, idx, IRQ_IPVP, val);
+    }
+}
+
+static uint32_t mpic_src_read (void *opaque, uint32_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval;
+    int idx;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr = addr & 0xFFF0;
+    if (addr < 0x180) {
+	idx = EXT_IRQ;
+    } else if (addr >= 0x200 && addr < 0xa00) {
+	idx = INT_IRQ;
+	addr -= 0x200;
+    } else if (addr >= 0x1600 && addr < 0x1700) {
+	idx = MSG_IRQ;
+	addr -= 0x1600;
+    } else if (addr >= 0x1C00 && addr < 0x1D00) {
+	idx = MSI_IRQ;
+	addr -= 0x1C00;
+    } else {
+	return retval;
+    }
+    idx += addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        retval = read_IRQreg(mpp, idx, IRQ_IDE);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        retval = read_IRQreg(mpp, idx, IRQ_IPVP);
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined MPIC_SWAP
+    retval = tswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void mpic_writel (void *opaque,
+                            target_phys_addr_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
+    if (addr < 0x10F0) {
+        /* Global registers */
+	openpic_gbl_write(mpp, addr, val);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        mpic_timer_write(mpp, addr, val);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        mpic_src_write(mpp, addr, val);
+    } else if (addr < 0x30000){
+        /* CPU registers */
+	openpic_cpu_write(mpp, addr, val);
+    } else {
+    	DPRINTF("wrong mpic write addr %p\n",addr);
+    }
+}
+
+static uint32_t mpic_readl (void *opaque,target_phys_addr_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval = 0;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x\n", __func__, (int)addr);
+    if (addr < 0x10F0) {
+        /* Global registers */
+	retval = openpic_gbl_read(mpp, addr);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        retval = mpic_timer_read(mpp, addr);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        retval = mpic_src_read(mpp, addr);
+    } else if (addr < 0x30000){
+        /* CPU registers */
+	retval = openpic_cpu_read(mpp, addr);
+    } else {
+    	DPRINTF("wrong mpic read addr %p\n",addr);
+    }
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *mpic_write[] = {
+    &openpic_buggy_write,
+    &openpic_buggy_write,
+    &mpic_writel,
+};
+
+static CPUReadMemoryFunc *mpic_read[] = {
+    &openpic_buggy_read,
+    &openpic_buggy_read,
+    &mpic_readl,
+};
+
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out)
+{
+    openpic_t *mpp;
+    int i;
+
+    /* XXX: for now, only one CPU is supported */
+    if (nb_cpus != 1)
+        return NULL;
+
+    mpp = qemu_mallocz(sizeof(openpic_t));
+
+    mpp->mem_index = cpu_register_io_memory(0, mpic_read, mpic_write, mpp);
+    if (mpp->mem_index < 0)
+	goto free;
+    cpu_register_physical_memory(base, MPIC_MAP_SIZE, mpp->mem_index);
+
+    mpp->nb_cpus = nb_cpus;
+
+    for (i = 0; i < nb_cpus; i++)
+        mpp->dst[i].irqs = irqs[i];
+    mpp->irq_out = irq_out;
+
+    mpp->irq_raise = mpic_irq_raise;
+    mpp->reset = mpic_reset;
+
+    mpp->reset(mpp);
+
+    return qemu_allocate_irqs(openpic_set_irq, mpp, MAX_IRQ);
+
+free:
+    qemu_free(mpp);
+    return NULL;
+}
diff --git a/hw/openpic.h b/hw/openpic.h
new file mode 100644
index 0000000..2f85e16
--- /dev/null
+++ b/hw/openpic.h
@@ -0,0 +1,19 @@
+
+#if !defined(OPENPIC_H)
+#define OPENPIC_H
+
+/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
+enum {
+    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
+    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
+    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
+    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
+    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
+    OPENPIC_OUTPUT_NB,
+};
+
+qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+#endif /* OPENPIC_H */
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index cc70fb7..bf987b1 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -113,17 +113,5 @@ void adb_mouse_init(ADBBusState *bus);
 
 extern ADBBusState adb_bus;
 
-/* openpic.c */
-/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
-enum {
-    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
-    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
-    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
-    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
-    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
-    OPENPIC_OUTPUT_NB,
-};
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
-                        qemu_irq **irqs, qemu_irq irq_out);
-
+#include "openpic.h"
 #endif /* !defined(__PPC_MAC_H__) */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
@ 2009-01-15 12:34       ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

The modify is based on original author's method
to switch openpic and mpic by static define,
like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
(Although the support for intel has broken)
So they can't be used at the same time.

I guess it's not the correct way to do this.
but I am not sure is the USE_MPC85xx and openpic are still needed?

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/openpic.c |  384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 hw/openpic.h |   19 +++
 hw/ppc_mac.h |   14 +--
 3 files changed, 389 insertions(+), 28 deletions(-)
 create mode 100644 hw/openpic.h

diff --git a/hw/openpic.c b/hw/openpic.c
index b8da4d7..bc5f72b 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -35,6 +35,7 @@
 #include "hw.h"
 #include "ppc_mac.h"
 #include "pci.h"
+#include "openpic.h"
 
 //#define DEBUG_OPENPIC
 
@@ -45,7 +46,8 @@
 #endif
 #define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
 
-#define USE_MPCxxx /* Intel model is broken, for now */
+/*#define USE_MPCxxx |+ Intel model is broken, for now +|*/
+#define USE_MPC85xx /* Intel model is broken, for now */
 
 #if defined (USE_INTEL_GW80314)
 /* Intel GW80314 I/O Companion chip */
@@ -84,15 +86,6 @@ enum {
 #define OPENPIC_LITTLE_ENDIAN 1
 #define OPENPIC_BIG_ENDIAN    0
 
-#else
-#error "Please select which OpenPic implementation is to be emulated"
-#endif
-
-#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
-    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
-#define OPENPIC_SWAP
-#endif
-
 /* Interrupt definitions */
 #define IRQ_FE     (EXT_IRQ)     /* Internal functional IRQ */
 #define IRQ_ERR    (EXT_IRQ + 1) /* Error IRQ */
@@ -105,6 +98,61 @@ enum {
 #define IRQ_MBX0   (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
 #endif
 
+#elif defined(USE_MPC85xx)
+
+#define MPIC_MAP_SIZE	0x40000
+
+#define MAX_CPU     1
+#define MAX_EXT    12
+#define MAX_INT    64
+#define MAX_DBL     0
+#define MAX_MBX     0
+#define MAX_TMR     4
+#define MAX_MSG     4
+#define MAX_MSI     8
+#define MAX_IPI     4
+#define MAX_IRQ    (MAX_EXT + MAX_INT + MAX_TMR + MAX_MSG + MAX_MSI + (MAX_IPI * MAX_CPU))
+
+#define VECTOR_BITS 8
+#define VID         0x0 /* MPIC version ID */
+#define VENI        0x00000000 /* Vendor ID */
+
+enum {
+    IRQ_IPVP = 0,
+    IRQ_IDE,
+};
+
+enum ide_bits {
+    IDR_EP     = 0,
+    IDR_CI0     = 1,
+    IDR_CI1     = 2,
+    IDR_P1     = 30,
+    IDR_P0     = 31,
+};
+
+#define OPENPIC_LITTLE_ENDIAN 0
+#define OPENPIC_BIG_ENDIAN    1
+
+/* Interrupt definitions */
+#define EXT_IRQ		0
+#define INT_IRQ		(EXT_IRQ + MAX_EXT)
+#define TMR_IRQ		(INT_IRQ + MAX_INT)
+#define MSG_IRQ		(TMR_IRQ + MAX_TMR)
+#define MSI_IRQ		(MSG_IRQ + MAX_MSG)
+#define IPI_IRQ		(MSI_IRQ + MAX_MSI)
+
+#define IRQ_IPI0        IPI_IRQ
+#define IRQ_TIM0        TMR_IRQ
+
+#else
+#error "Please select which OpenPic implementation is to be emulated"
+#endif
+
+#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
+    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
+#define OPENPIC_SWAP
+#endif
+
 #define BF_WIDTH(_bits_) \
 (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
 
@@ -157,6 +205,7 @@ enum IPVP_bits {
 #define IPVP_VECTOR(_ipvpr_)   ((_ipvpr_) & IPVP_VECTOR_MASK)
 
 typedef struct IRQ_dst_t {
+    uint32_t tfrr;
     uint32_t pctp; /* CPU current task priority */
     uint32_t pcsr; /* CPU sensitivity register */
     IRQ_queue_t raised;
@@ -200,6 +249,8 @@ typedef struct openpic_t {
 #endif
     /* IRQ out is used when in bypass mode (not implemented) */
     qemu_irq irq_out;
+    void (*reset) (struct openpic_t *);
+    void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *);
 } openpic_t;
 
 static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
@@ -286,7 +337,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
         return;
     }
     DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
-    qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
+    opp->irq_raise(opp, n_CPU, src);
 }
 
 /* update pic state because registers for n_IRQ have changed value */
@@ -551,8 +602,8 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
     case 0x00: /* FREP */
         break;
     case 0x20: /* GLBC */
-        if (val & 0x80000000)
-            openpic_reset(opp);
+        if (val & 0x80000000 && opp->reset)
+            opp->reset(opp);
         opp->glbc = val & ~0x80000000;
 	break;
     case 0x80: /* VENI */
@@ -818,7 +869,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
              IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
             DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
                     idx, n_IRQ);
-            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
+            opp->irq_raise(opp, idx, src);
         }
 	break;
     default:
@@ -1001,6 +1052,11 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
 #endif
 }
 
+static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
+{
+    qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+}
+
 qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out)
 {
@@ -1058,9 +1114,307 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
     for (i = 0; i < nb_cpus; i++)
         opp->dst[i].irqs = irqs[i];
     opp->irq_out = irq_out;
-    openpic_reset(opp);
+
+    opp->irq_raise = openpic_irq_raise;
+    opp->reset = openpic_reset;
+
+    opp->reset(opp);
     if (pmem_index)
         *pmem_index = opp->mem_index;
 
     return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
 }
+
+static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
+{
+    int n_ci = IDR_CI0 - n_CPU;
+    DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
+		    n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
+    if(test_bit(&src->ide, n_ci)) {
+        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
+    }
+    else {
+        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
+    }
+}
+
+static void mpic_reset (openpic_t *mpp)
+{
+    int i;
+
+    mpp->glbc = 0x80000000;
+    /* Initialise controller registers */
+    mpp->frep = 0x004f0002;
+    mpp->veni = VENI;
+    mpp->pint = 0x00000000;
+    mpp->spve = 0x0000FFFF;
+    /* Initialise IRQ sources */
+    for (i = 0; i < MAX_IRQ; i++) {
+	mpp->src[i].ipvp = 0x80800000;
+	mpp->src[i].ide  = 0x00000001;
+    }
+    /* Initialise IRQ destinations */
+    for (i = 0; i < MAX_CPU; i++) {
+	mpp->dst[i].pctp      = 0x0000000F;
+        mpp->dst[i].tfrr      = 0x00000000;
+	memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
+	mpp->dst[i].raised.next = -1;
+	memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
+	mpp->dst[i].servicing.next = -1;
+    }
+    /* Initialise timers */
+    for (i = 0; i < MAX_TMR; i++) {
+	mpp->timers[i].ticc = 0x00000000;
+	mpp->timers[i].tibc = 0x80000000;
+    }
+    /* Go out of RESET state */
+    mpp->glbc = 0x00000000;
+}
+
+static void mpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+    int idx, cpu;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined MPIC_SWAP
+    val = bswap32(val);
+#endif
+    addr &= 0xFFFF;
+    cpu = addr >> 12;
+    idx = (addr >> 6) & 0x3;
+    switch (addr & 0x30) {
+    case 0x00: /* gtccr */
+        break;
+    case 0x10: /* gtbcr */
+	if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
+	    (val & 0x80000000) = 0 &&
+            (mpp->timers[idx].tibc & 0x80000000) != 0)
+	    mpp->timers[idx].ticc &= ~0x80000000;
+	mpp->timers[idx].tibc = val;
+	break;
+    case 0x20: /* GTIVPR */
+	write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP, val);
+	break;
+    case 0x30: /* GTIDR & TFRR */
+	if ((addr & 0xF0) = 0xF0)
+            mpp->dst[cpu].tfrr = val;
+	else
+	    write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE, val);
+	break;
+    }
+}
+
+static uint32_t mpic_timer_read (void *opaque, uint32_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval;
+    int idx, cpu;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr &= 0xFFFF;
+    cpu = addr >> 12;
+    idx = (addr >> 6) & 0x3;
+    switch (addr & 0x30) {
+    case 0x00: /* gtccr */
+	retval = mpp->timers[idx].ticc;
+        break;
+    case 0x10: /* gtbcr */
+	retval = mpp->timers[idx].tibc;
+	break;
+    case 0x20: /* TIPV */
+	retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP);
+	break;
+    case 0x30: /* TIDR */
+        if ((addr &0xF0) = 0XF0)
+	    retval = mpp->dst[cpu].tfrr;
+	else
+	    retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE);
+	break;
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined MPIC_SWAP
+    retval = bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void mpic_src_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+    int idx;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined MPIC_SWAP
+    val = tswap32(val);
+#endif
+    addr = addr & 0xFFF0;
+    if (addr < 0x180) {
+	idx = EXT_IRQ;
+    } else if (addr >= 0x200 && addr < 0xa00) {
+	idx = INT_IRQ;
+	addr -= 0x200;
+    } else if (addr >= 0x1600 && addr < 0x1700) {
+	idx = MSG_IRQ;
+	addr -= 0x1600;
+    } else if (addr >= 0x1C00 && addr < 0x1D00) {
+	idx = MSI_IRQ;
+	addr -= 0x1C00;
+    } else {
+	return;
+    }
+    idx += addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        write_IRQreg(mpp, idx, IRQ_IDE, val);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        write_IRQreg(mpp, idx, IRQ_IPVP, val);
+    }
+}
+
+static uint32_t mpic_src_read (void *opaque, uint32_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval;
+    int idx;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr = addr & 0xFFF0;
+    if (addr < 0x180) {
+	idx = EXT_IRQ;
+    } else if (addr >= 0x200 && addr < 0xa00) {
+	idx = INT_IRQ;
+	addr -= 0x200;
+    } else if (addr >= 0x1600 && addr < 0x1700) {
+	idx = MSG_IRQ;
+	addr -= 0x1600;
+    } else if (addr >= 0x1C00 && addr < 0x1D00) {
+	idx = MSI_IRQ;
+	addr -= 0x1C00;
+    } else {
+	return retval;
+    }
+    idx += addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        retval = read_IRQreg(mpp, idx, IRQ_IDE);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        retval = read_IRQreg(mpp, idx, IRQ_IPVP);
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined MPIC_SWAP
+    retval = tswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void mpic_writel (void *opaque,
+                            target_phys_addr_t addr, uint32_t val)
+{
+    openpic_t *mpp = opaque;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
+    if (addr < 0x10F0) {
+        /* Global registers */
+	openpic_gbl_write(mpp, addr, val);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        mpic_timer_write(mpp, addr, val);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        mpic_src_write(mpp, addr, val);
+    } else if (addr < 0x30000){
+        /* CPU registers */
+	openpic_cpu_write(mpp, addr, val);
+    } else {
+    	DPRINTF("wrong mpic write addr %p\n",addr);
+    }
+}
+
+static uint32_t mpic_readl (void *opaque,target_phys_addr_t addr)
+{
+    openpic_t *mpp = opaque;
+    uint32_t retval = 0;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x\n", __func__, (int)addr);
+    if (addr < 0x10F0) {
+        /* Global registers */
+	retval = openpic_gbl_read(mpp, addr);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        retval = mpic_timer_read(mpp, addr);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        retval = mpic_src_read(mpp, addr);
+    } else if (addr < 0x30000){
+        /* CPU registers */
+	retval = openpic_cpu_read(mpp, addr);
+    } else {
+    	DPRINTF("wrong mpic read addr %p\n",addr);
+    }
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *mpic_write[] = {
+    &openpic_buggy_write,
+    &openpic_buggy_write,
+    &mpic_writel,
+};
+
+static CPUReadMemoryFunc *mpic_read[] = {
+    &openpic_buggy_read,
+    &openpic_buggy_read,
+    &mpic_readl,
+};
+
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out)
+{
+    openpic_t *mpp;
+    int i;
+
+    /* XXX: for now, only one CPU is supported */
+    if (nb_cpus != 1)
+        return NULL;
+
+    mpp = qemu_mallocz(sizeof(openpic_t));
+
+    mpp->mem_index = cpu_register_io_memory(0, mpic_read, mpic_write, mpp);
+    if (mpp->mem_index < 0)
+	goto free;
+    cpu_register_physical_memory(base, MPIC_MAP_SIZE, mpp->mem_index);
+
+    mpp->nb_cpus = nb_cpus;
+
+    for (i = 0; i < nb_cpus; i++)
+        mpp->dst[i].irqs = irqs[i];
+    mpp->irq_out = irq_out;
+
+    mpp->irq_raise = mpic_irq_raise;
+    mpp->reset = mpic_reset;
+
+    mpp->reset(mpp);
+
+    return qemu_allocate_irqs(openpic_set_irq, mpp, MAX_IRQ);
+
+free:
+    qemu_free(mpp);
+    return NULL;
+}
diff --git a/hw/openpic.h b/hw/openpic.h
new file mode 100644
index 0000000..2f85e16
--- /dev/null
+++ b/hw/openpic.h
@@ -0,0 +1,19 @@
+
+#if !defined(OPENPIC_H)
+#define OPENPIC_H
+
+/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
+enum {
+    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
+    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
+    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
+    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
+    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
+    OPENPIC_OUTPUT_NB,
+};
+
+qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+#endif /* OPENPIC_H */
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index cc70fb7..bf987b1 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -113,17 +113,5 @@ void adb_mouse_init(ADBBusState *bus);
 
 extern ADBBusState adb_bus;
 
-/* openpic.c */
-/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
-enum {
-    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
-    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
-    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
-    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
-    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
-    OPENPIC_OUTPUT_NB,
-};
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
-                        qemu_irq **irqs, qemu_irq irq_out);
-
+#include "openpic.h"
 #endif /* !defined(__PPC_MAC_H__) */
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 4/9] powerpc/kvm: enable POWERPC_MMU_BOOKE_FSL when kvm is enabled
  2009-01-15 12:34       ` Liu Yu
@ 2009-01-15 12:34         ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/helper.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index a953e1f..0b5cd3e 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1939,7 +1939,8 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
         break;
     case POWERPC_MMU_BOOKE_FSL:
         /* XXX: TODO */
-        cpu_abort(env, "BookE MMU model is not implemented\n");
+        if (!kvm_enabled())
+            cpu_abort(env, "BookE MMU model is not implemented\n");
         break;
     case POWERPC_MMU_32B:
     case POWERPC_MMU_601:
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 4/9] powerpc/kvm: enable POWERPC_MMU_BOOKE_FSL when kvm is enabled
@ 2009-01-15 12:34         ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/helper.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index a953e1f..0b5cd3e 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1939,7 +1939,8 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
         break;
     case POWERPC_MMU_BOOKE_FSL:
         /* XXX: TODO */
-        cpu_abort(env, "BookE MMU model is not implemented\n");
+        if (!kvm_enabled())
+            cpu_abort(env, "BookE MMU model is not implemented\n");
         break;
     case POWERPC_MMU_32B:
     case POWERPC_MMU_601:
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
  2009-01-15 12:34         ` Liu Yu
@ 2009-01-15 12:34           ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 Makefile.target  |    2 +
 hw/ppce500_pci.c |  369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 371 insertions(+), 0 deletions(-)
 create mode 100644 hw/ppce500_pci.c

diff --git a/Makefile.target b/Makefile.target
index 58fe88f..2079fcb 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
 # PowerPC 4xx boards
 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 OBJS+= ppc440.o ppc440_bamboo.o
+# PowerPC E500 boards
+OBJS+= ppce500_pci.o
 ifdef FDT_LIBS
 OBJS+= device_tree.o
 LIBS+= $(FDT_LIBS)
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
new file mode 100644
index 0000000..9077591
--- /dev/null
+++ b/hw/ppce500_pci.c
@@ -0,0 +1,369 @@
+/*
+ * QEMU PowerPC E500 embedded processors pci controller emulation
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc4xx_pci.c,
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include "hw.h"
+#include "ppc.h"
+#include "ppce500.h"
+typedef target_phys_addr_t pci_addr_t;
+#include "pci.h"
+#include "pci_host.h"
+#include "bswap.h"
+#include "qemu-log.h"
+
+#ifdef DEBUG_PCI
+#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
+#else
+#define pci_debug(fmt, arg...)
+#endif
+
+#define PCIE500_CFGADDR       0x0
+#define PCIE500_CFGDATA       0x4
+#define PCIE500_REG_BASE      0xC00
+#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
+
+#define PPCE500_PCI_CONFIG_ADDR		0x0
+#define PPCE500_PCI_CONFIG_DATA		0x4
+#define PPCE500_PCI_INTACK		0x8
+
+#define PPCE500_PCI_OW1			(0xC20 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW2			(0xC40 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW3			(0xC60 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW4			(0xC80 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW3			(0xDA0 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW2			(0xDC0 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW1			(0xDE0 - PCIE500_REG_BASE)
+
+#define PPCE500_PCI_GASKET_TIMR		(0xE20 - PCIE500_REG_BASE)
+
+#define PCI_POTAR		0x0
+#define PCI_POTEAR		0x4
+#define PCI_POWBAR		0x8
+#define PCI_POWAR		0x10
+
+#define PCI_PITAR		0x0
+#define PCI_PIWBAR		0x8
+#define PCI_PIWBEAR		0xC
+#define PCI_PIWAR		0x10
+
+#define PPCE500_PCI_NR_POBS 5
+#define PPCE500_PCI_NR_PIBS 3
+
+struct  pci_outbound {
+    uint32_t potar;
+    uint32_t potear;
+    uint32_t powbar;
+    uint32_t powar;
+};
+
+struct pci_inbound {
+    uint32_t pitar;
+    uint32_t piwbar;
+    uint32_t piwbear;
+    uint32_t piwar;
+};
+
+struct PPCE500PCIState {
+    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
+    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
+    uint32_t gasket_time;
+    PCIHostState pci_state;
+    PCIDevice *pci_dev;
+};
+
+typedef struct PPCE500PCIState PPCE500PCIState;
+
+static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
+{
+    PPCE500PCIState *pci = opaque;
+
+    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
+		    pci->pci_state.config_reg);
+    return pci->pci_state.config_reg;
+}
+
+static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
+    &pcie500_cfgaddr_readl,
+    &pcie500_cfgaddr_readl,
+    &pcie500_cfgaddr_readl,
+};
+
+static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
+                                  uint32_t value)
+{
+    PPCE500PCIState *controller = opaque;
+
+    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
+    controller->pci_state.config_reg = value & ~0x3;
+}
+
+static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
+    pcie500_cfgaddr_writel,
+    &pcie500_cfgaddr_writel,
+    &pcie500_cfgaddr_writel,
+};
+
+static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
+    &pci_host_data_readb,
+    &pci_host_data_readw,
+    &pci_host_data_readl,
+};
+
+static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
+    &pci_host_data_writeb,
+    &pci_host_data_writew,
+    &pci_host_data_writel,
+};
+
+static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
+{
+    PPCE500PCIState *pci = opaque;
+    unsigned long win;
+    uint32_t value = 0;
+
+    win = addr & 0xfe0;
+
+    switch (win) {
+    case PPCE500_PCI_OW1:
+    case PPCE500_PCI_OW2:
+    case PPCE500_PCI_OW3:
+    case PPCE500_PCI_OW4:
+	switch (addr & 0xC) {
+	case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
+	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
+	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
+	case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
+	default: break;
+	}
+	break;
+
+    case PPCE500_PCI_IW3:
+    case PPCE500_PCI_IW2:
+    case PPCE500_PCI_IW1:
+	switch (addr & 0xC) {
+	case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
+	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
+	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
+	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_GASKET_TIMR:
+	value = pci->gasket_time;
+	break;
+
+    default:
+	break;
+    }
+
+    pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
+    return value;
+}
+
+static CPUReadMemoryFunc *e500_pci_reg_read[] = {
+    &pci_reg_read4,
+    &pci_reg_read4,
+    &pci_reg_read4,
+};
+
+static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
+                               uint32_t value)
+{
+    PPCE500PCIState *pci = opaque;
+    unsigned long win;
+
+    win = addr & 0xfe0;
+
+    pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
+
+    switch (win) {
+    case PPCE500_PCI_OW1:
+    case PPCE500_PCI_OW2:
+    case PPCE500_PCI_OW3:
+    case PPCE500_PCI_OW4:
+	switch (addr & 0xC) {
+	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
+	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
+	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
+	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_IW3:
+    case PPCE500_PCI_IW2:
+    case PPCE500_PCI_IW1:
+	switch (addr & 0xC) {
+	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
+	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
+	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
+	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_GASKET_TIMR:
+	pci->gasket_time = value;
+	break;
+
+    default:
+	break;
+    };
+}
+
+static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
+    &pci_reg_write4,
+    &pci_reg_write4,
+    &pci_reg_write4,
+};
+
+static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+    int devno = pci_dev->devfn >> 3, ret = 0;
+
+    switch (devno) {
+	/* Two PCI slot */
+	case 0x11:
+	case 0x12:
+	    ret = (irq_num + devno - 0x10) % 4;
+	    break;
+	default:
+	    printf("Error:%s:unknow dev number\n", __func__);
+    }
+
+    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
+           pci_dev->devfn, irq_num, ret, devno);
+
+    return ret;
+}
+
+static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
+{
+    pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
+
+    qemu_set_irq(pic[irq_num], level);
+}
+
+static void ppce500_pci_save(QEMUFile *f, void *opaque)
+{
+    PPCE500PCIState *controller = opaque;
+    int i;
+
+    pci_device_save(controller->pci_dev, f);
+
+    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
+        qemu_put_be32s(f, &controller->pob[i].potar);
+        qemu_put_be32s(f, &controller->pob[i].potear);
+        qemu_put_be32s(f, &controller->pob[i].powbar);
+        qemu_put_be32s(f, &controller->pob[i].powar);
+    }
+
+    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
+        qemu_put_be32s(f, &controller->pib[i].pitar);
+        qemu_put_be32s(f, &controller->pib[i].piwbar);
+        qemu_put_be32s(f, &controller->pib[i].piwbear);
+        qemu_put_be32s(f, &controller->pib[i].piwar);
+    }
+    qemu_put_be32s(f, &controller->gasket_time);
+}
+
+static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PPCE500PCIState *controller = opaque;
+    int i;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    pci_device_load(controller->pci_dev, f);
+
+    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
+        qemu_get_be32s(f, &controller->pob[i].potar);
+        qemu_get_be32s(f, &controller->pob[i].potear);
+        qemu_get_be32s(f, &controller->pob[i].powbar);
+        qemu_get_be32s(f, &controller->pob[i].powar);
+    }
+
+    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
+        qemu_get_be32s(f, &controller->pib[i].pitar);
+        qemu_get_be32s(f, &controller->pib[i].piwbar);
+        qemu_get_be32s(f, &controller->pib[i].piwbear);
+        qemu_get_be32s(f, &controller->pib[i].piwar);
+    }
+    qemu_get_be32s(f, &controller->gasket_time);
+
+    return 0;
+}
+PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
+{
+    PPCE500PCIState *controller;
+    PCIDevice *d;
+    int index;
+    static int ppce500_pci_id;
+
+    controller = qemu_mallocz(sizeof(PPCE500PCIState));
+    if (!controller)
+	return NULL;
+
+    controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
+                                                 mpc85xx_pci_map_irq,
+                                                 pci_irqs, 0x88, 4);
+    d = pci_register_device(controller->pci_state.bus,
+                            "host bridge", sizeof(PCIDevice),
+                            0, NULL, NULL);
+
+    d->config[0x00] = 0x57; // vendor_id
+    d->config[0x01] = 0x19;
+    d->config[0x02] = 0x30; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x0a] = 0x20; // class_sub = other bridge type
+    d->config[0x0b] = 0x0B; // class_base = PCI_bridge
+
+    controller->pci_dev = d;
+
+    /* CFGADDR */
+    index = cpu_register_io_memory(0, pcie500_cfgaddr_read,
+                                   pcie500_cfgaddr_write, controller);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
+
+    /* CFGDATA */
+    index = cpu_register_io_memory(0, pcie500_cfgdata_read,
+                                   pcie500_cfgdata_write,
+                                   &controller->pci_state);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
+
+    index = cpu_register_io_memory(0, e500_pci_reg_read,
+		                   e500_pci_reg_write, controller);
+    if (index < 0)
+	goto free;
+    cpu_register_physical_memory(registers + PCIE500_REG_BASE,
+                                   PCIE500_REG_SIZE, index);
+
+    /* XXX load/save code not tested. */
+    register_savevm("ppce500_pci", ppce500_pci_id++, 1,
+                    ppce500_pci_save, ppce500_pci_load, controller);
+
+    return controller->pci_state.bus;
+
+free:
+    printf("%s error\n", __func__);
+    qemu_free(controller);
+    return NULL;
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
@ 2009-01-15 12:34           ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 Makefile.target  |    2 +
 hw/ppce500_pci.c |  369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 371 insertions(+), 0 deletions(-)
 create mode 100644 hw/ppce500_pci.c

diff --git a/Makefile.target b/Makefile.target
index 58fe88f..2079fcb 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
 # PowerPC 4xx boards
 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 OBJS+= ppc440.o ppc440_bamboo.o
+# PowerPC E500 boards
+OBJS+= ppce500_pci.o
 ifdef FDT_LIBS
 OBJS+= device_tree.o
 LIBS+= $(FDT_LIBS)
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
new file mode 100644
index 0000000..9077591
--- /dev/null
+++ b/hw/ppce500_pci.c
@@ -0,0 +1,369 @@
+/*
+ * QEMU PowerPC E500 embedded processors pci controller emulation
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc4xx_pci.c,
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include "hw.h"
+#include "ppc.h"
+#include "ppce500.h"
+typedef target_phys_addr_t pci_addr_t;
+#include "pci.h"
+#include "pci_host.h"
+#include "bswap.h"
+#include "qemu-log.h"
+
+#ifdef DEBUG_PCI
+#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
+#else
+#define pci_debug(fmt, arg...)
+#endif
+
+#define PCIE500_CFGADDR       0x0
+#define PCIE500_CFGDATA       0x4
+#define PCIE500_REG_BASE      0xC00
+#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
+
+#define PPCE500_PCI_CONFIG_ADDR		0x0
+#define PPCE500_PCI_CONFIG_DATA		0x4
+#define PPCE500_PCI_INTACK		0x8
+
+#define PPCE500_PCI_OW1			(0xC20 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW2			(0xC40 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW3			(0xC60 - PCIE500_REG_BASE)
+#define PPCE500_PCI_OW4			(0xC80 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW3			(0xDA0 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW2			(0xDC0 - PCIE500_REG_BASE)
+#define PPCE500_PCI_IW1			(0xDE0 - PCIE500_REG_BASE)
+
+#define PPCE500_PCI_GASKET_TIMR		(0xE20 - PCIE500_REG_BASE)
+
+#define PCI_POTAR		0x0
+#define PCI_POTEAR		0x4
+#define PCI_POWBAR		0x8
+#define PCI_POWAR		0x10
+
+#define PCI_PITAR		0x0
+#define PCI_PIWBAR		0x8
+#define PCI_PIWBEAR		0xC
+#define PCI_PIWAR		0x10
+
+#define PPCE500_PCI_NR_POBS 5
+#define PPCE500_PCI_NR_PIBS 3
+
+struct  pci_outbound {
+    uint32_t potar;
+    uint32_t potear;
+    uint32_t powbar;
+    uint32_t powar;
+};
+
+struct pci_inbound {
+    uint32_t pitar;
+    uint32_t piwbar;
+    uint32_t piwbear;
+    uint32_t piwar;
+};
+
+struct PPCE500PCIState {
+    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
+    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
+    uint32_t gasket_time;
+    PCIHostState pci_state;
+    PCIDevice *pci_dev;
+};
+
+typedef struct PPCE500PCIState PPCE500PCIState;
+
+static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
+{
+    PPCE500PCIState *pci = opaque;
+
+    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
+		    pci->pci_state.config_reg);
+    return pci->pci_state.config_reg;
+}
+
+static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
+    &pcie500_cfgaddr_readl,
+    &pcie500_cfgaddr_readl,
+    &pcie500_cfgaddr_readl,
+};
+
+static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
+                                  uint32_t value)
+{
+    PPCE500PCIState *controller = opaque;
+
+    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
+    controller->pci_state.config_reg = value & ~0x3;
+}
+
+static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
+    pcie500_cfgaddr_writel,
+    &pcie500_cfgaddr_writel,
+    &pcie500_cfgaddr_writel,
+};
+
+static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
+    &pci_host_data_readb,
+    &pci_host_data_readw,
+    &pci_host_data_readl,
+};
+
+static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
+    &pci_host_data_writeb,
+    &pci_host_data_writew,
+    &pci_host_data_writel,
+};
+
+static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
+{
+    PPCE500PCIState *pci = opaque;
+    unsigned long win;
+    uint32_t value = 0;
+
+    win = addr & 0xfe0;
+
+    switch (win) {
+    case PPCE500_PCI_OW1:
+    case PPCE500_PCI_OW2:
+    case PPCE500_PCI_OW3:
+    case PPCE500_PCI_OW4:
+	switch (addr & 0xC) {
+	case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
+	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
+	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
+	case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
+	default: break;
+	}
+	break;
+
+    case PPCE500_PCI_IW3:
+    case PPCE500_PCI_IW2:
+    case PPCE500_PCI_IW1:
+	switch (addr & 0xC) {
+	case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
+	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
+	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
+	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_GASKET_TIMR:
+	value = pci->gasket_time;
+	break;
+
+    default:
+	break;
+    }
+
+    pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
+    return value;
+}
+
+static CPUReadMemoryFunc *e500_pci_reg_read[] = {
+    &pci_reg_read4,
+    &pci_reg_read4,
+    &pci_reg_read4,
+};
+
+static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
+                               uint32_t value)
+{
+    PPCE500PCIState *pci = opaque;
+    unsigned long win;
+
+    win = addr & 0xfe0;
+
+    pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
+
+    switch (win) {
+    case PPCE500_PCI_OW1:
+    case PPCE500_PCI_OW2:
+    case PPCE500_PCI_OW3:
+    case PPCE500_PCI_OW4:
+	switch (addr & 0xC) {
+	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
+	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
+	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
+	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_IW3:
+    case PPCE500_PCI_IW2:
+    case PPCE500_PCI_IW1:
+	switch (addr & 0xC) {
+	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
+	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
+	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
+	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
+	default: break;
+	};
+	break;
+
+    case PPCE500_PCI_GASKET_TIMR:
+	pci->gasket_time = value;
+	break;
+
+    default:
+	break;
+    };
+}
+
+static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
+    &pci_reg_write4,
+    &pci_reg_write4,
+    &pci_reg_write4,
+};
+
+static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+    int devno = pci_dev->devfn >> 3, ret = 0;
+
+    switch (devno) {
+	/* Two PCI slot */
+	case 0x11:
+	case 0x12:
+	    ret = (irq_num + devno - 0x10) % 4;
+	    break;
+	default:
+	    printf("Error:%s:unknow dev number\n", __func__);
+    }
+
+    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
+           pci_dev->devfn, irq_num, ret, devno);
+
+    return ret;
+}
+
+static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
+{
+    pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
+
+    qemu_set_irq(pic[irq_num], level);
+}
+
+static void ppce500_pci_save(QEMUFile *f, void *opaque)
+{
+    PPCE500PCIState *controller = opaque;
+    int i;
+
+    pci_device_save(controller->pci_dev, f);
+
+    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
+        qemu_put_be32s(f, &controller->pob[i].potar);
+        qemu_put_be32s(f, &controller->pob[i].potear);
+        qemu_put_be32s(f, &controller->pob[i].powbar);
+        qemu_put_be32s(f, &controller->pob[i].powar);
+    }
+
+    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
+        qemu_put_be32s(f, &controller->pib[i].pitar);
+        qemu_put_be32s(f, &controller->pib[i].piwbar);
+        qemu_put_be32s(f, &controller->pib[i].piwbear);
+        qemu_put_be32s(f, &controller->pib[i].piwar);
+    }
+    qemu_put_be32s(f, &controller->gasket_time);
+}
+
+static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PPCE500PCIState *controller = opaque;
+    int i;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    pci_device_load(controller->pci_dev, f);
+
+    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
+        qemu_get_be32s(f, &controller->pob[i].potar);
+        qemu_get_be32s(f, &controller->pob[i].potear);
+        qemu_get_be32s(f, &controller->pob[i].powbar);
+        qemu_get_be32s(f, &controller->pob[i].powar);
+    }
+
+    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
+        qemu_get_be32s(f, &controller->pib[i].pitar);
+        qemu_get_be32s(f, &controller->pib[i].piwbar);
+        qemu_get_be32s(f, &controller->pib[i].piwbear);
+        qemu_get_be32s(f, &controller->pib[i].piwar);
+    }
+    qemu_get_be32s(f, &controller->gasket_time);
+
+    return 0;
+}
+PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
+{
+    PPCE500PCIState *controller;
+    PCIDevice *d;
+    int index;
+    static int ppce500_pci_id;
+
+    controller = qemu_mallocz(sizeof(PPCE500PCIState));
+    if (!controller)
+	return NULL;
+
+    controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
+                                                 mpc85xx_pci_map_irq,
+                                                 pci_irqs, 0x88, 4);
+    d = pci_register_device(controller->pci_state.bus,
+                            "host bridge", sizeof(PCIDevice),
+                            0, NULL, NULL);
+
+    d->config[0x00] = 0x57; // vendor_id
+    d->config[0x01] = 0x19;
+    d->config[0x02] = 0x30; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x0a] = 0x20; // class_sub = other bridge type
+    d->config[0x0b] = 0x0B; // class_base = PCI_bridge
+
+    controller->pci_dev = d;
+
+    /* CFGADDR */
+    index = cpu_register_io_memory(0, pcie500_cfgaddr_read,
+                                   pcie500_cfgaddr_write, controller);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
+
+    /* CFGDATA */
+    index = cpu_register_io_memory(0, pcie500_cfgdata_read,
+                                   pcie500_cfgdata_write,
+                                   &controller->pci_state);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
+
+    index = cpu_register_io_memory(0, e500_pci_reg_read,
+		                   e500_pci_reg_write, controller);
+    if (index < 0)
+	goto free;
+    cpu_register_physical_memory(registers + PCIE500_REG_BASE,
+                                   PCIE500_REG_SIZE, index);
+
+    /* XXX load/save code not tested. */
+    register_savevm("ppce500_pci", ppce500_pci_id++, 1,
+                    ppce500_pci_save, ppce500_pci_load, controller);
+
+    return controller->pci_state.bus;
+
+free:
+    printf("%s error\n", __func__);
+    qemu_free(controller);
+    return NULL;
+}
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 6/9] powerpc/kvm: Add E500 irq support
  2009-01-15 12:34           ` Liu Yu
@ 2009-01-15 12:34             ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/ppc.c                    |   89 +++++++++++++++++++++++++++++++++++++++++++
 hw/ppc.h                    |    1 +
 target-ppc/cpu.h            |   12 ++++++
 target-ppc/translate_init.c |    6 ++-
 4 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/hw/ppc.c b/hw/ppc.c
index 60d6e86..fbce211 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -421,6 +421,95 @@ void ppc40x_irq_init (CPUState *env)
                                                   env, PPC40x_INPUT_NB);
 }
 
+/* PowerPC E500 internal IRQ controller */
+static void ppce500_set_irq (void *opaque, int pin, int level)
+{
+    CPUState *env = opaque;
+    int cur_level;
+
+#if defined(PPC_DEBUG_IRQ)
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
+                env, pin, level);
+    }
+#endif
+    cur_level = (env->irq_input_state >> pin) & 1;
+    /* Don't generate spurious events */
+    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
+        switch (pin) {
+        case PPCE500_INPUT_MCK:
+            if (level) {
+#if defined(PPC_DEBUG_IRQ)
+                if (loglevel & CPU_LOG_INT) {
+                    fprintf(logfile, "%s: reset the PowerPC system\n",
+                            __func__);
+                }
+#endif
+		fprintf(stderr,"PowerPC E500 reset core\n");
+		qemu_system_reset_request();
+            }
+            break;
+        case PPCE500_INPUT_RESET_CORE:
+            if (level) {
+#if defined(PPC_DEBUG_IRQ)
+                if (loglevel & CPU_LOG_INT) {
+                    fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
+                }
+#endif
+		ppc_set_irq(env, PPC_INTERRUPT_MCK, level);
+            }
+            break;
+        case PPCE500_INPUT_CINT:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the critical IRQ state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
+            break;
+        case PPCE500_INPUT_INT:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the core IRQ state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
+            break;
+        case PPCE500_INPUT_DEBUG:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the debug pin state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
+            break;
+        default:
+            /* Unknown pin - do nothing */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
+            }
+#endif
+            return;
+        }
+        if (level)
+            env->irq_input_state |= 1 << pin;
+        else
+            env->irq_input_state &= ~(1 << pin);
+    }
+}
+
+void ppce500_irq_init (CPUState *env)
+{
+    env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
+					env, PPCE500_INPUT_NB);
+}
 /*****************************************************************************/
 /* PowerPC time base and decrementer emulation */
 struct ppc_tb_t {
diff --git a/hw/ppc.h b/hw/ppc.h
index 75eb11a..2ec4680 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[];
 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
 
 void ppc40x_irq_init (CPUState *env);
+void ppce500_irq_init (CPUState *env);
 void ppc6xx_irq_init (CPUState *env);
 void ppc970_irq_init (CPUState *env);
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f7a12da..9f92cd8 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1352,6 +1352,18 @@ enum {
 };
 
 enum {
+    /* PowerPC E500 input pins */
+    PPCE500_INPUT_RESET_CORE = 0,
+    PPCE500_INPUT_MCK        = 1,
+    PPCE500_INPUT_RESET_SYS  = 2,      // in order same with 440
+    PPCE500_INPUT_CINT       = 3,
+    PPCE500_INPUT_INT        = 4,
+    PPCE500_INPUT_HALT       = 5,      // in order same with 440
+    PPCE500_INPUT_DEBUG      = 6,
+    PPCE500_INPUT_NB,
+};
+
+enum {
     /* PowerPC 40x input pins */
     PPC40x_INPUT_RESET_CORE = 0,
     PPC40x_INPUT_RESET_CHIP = 1,
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 5008a3a..7953c69 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -4154,7 +4154,8 @@ static void init_proc_e300 (CPUPPCState *env)
                               POWERPC_FLAG_BUS_CLK)
 #define check_pow_e500       check_pow_hid0
 
-__attribute__ (( unused ))
+extern void ppce500_irq_init (CPUState *env);
+
 static void init_proc_e500 (CPUPPCState *env)
 {
     /* Time base */
@@ -4256,7 +4257,8 @@ static void init_proc_e500 (CPUPPCState *env)
     init_excp_e200(env);
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
-    /* XXX: TODO: allocate internal IRQ controller */
+    /* Allocate hardware IRQ controller */
+    ppce500_irq_init(env);
 }
 
 /* Non-embedded PowerPC                                                      */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 6/9] powerpc/kvm: Add E500 irq support
@ 2009-01-15 12:34             ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/ppc.c                    |   89 +++++++++++++++++++++++++++++++++++++++++++
 hw/ppc.h                    |    1 +
 target-ppc/cpu.h            |   12 ++++++
 target-ppc/translate_init.c |    6 ++-
 4 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/hw/ppc.c b/hw/ppc.c
index 60d6e86..fbce211 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -421,6 +421,95 @@ void ppc40x_irq_init (CPUState *env)
                                                   env, PPC40x_INPUT_NB);
 }
 
+/* PowerPC E500 internal IRQ controller */
+static void ppce500_set_irq (void *opaque, int pin, int level)
+{
+    CPUState *env = opaque;
+    int cur_level;
+
+#if defined(PPC_DEBUG_IRQ)
+    if (loglevel & CPU_LOG_INT) {
+        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
+                env, pin, level);
+    }
+#endif
+    cur_level = (env->irq_input_state >> pin) & 1;
+    /* Don't generate spurious events */
+    if ((cur_level = 1 && level = 0) || (cur_level = 0 && level != 0)) {
+        switch (pin) {
+        case PPCE500_INPUT_MCK:
+            if (level) {
+#if defined(PPC_DEBUG_IRQ)
+                if (loglevel & CPU_LOG_INT) {
+                    fprintf(logfile, "%s: reset the PowerPC system\n",
+                            __func__);
+                }
+#endif
+		fprintf(stderr,"PowerPC E500 reset core\n");
+		qemu_system_reset_request();
+            }
+            break;
+        case PPCE500_INPUT_RESET_CORE:
+            if (level) {
+#if defined(PPC_DEBUG_IRQ)
+                if (loglevel & CPU_LOG_INT) {
+                    fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
+                }
+#endif
+		ppc_set_irq(env, PPC_INTERRUPT_MCK, level);
+            }
+            break;
+        case PPCE500_INPUT_CINT:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the critical IRQ state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
+            break;
+        case PPCE500_INPUT_INT:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the core IRQ state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
+            break;
+        case PPCE500_INPUT_DEBUG:
+            /* Level sensitive - active high */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: set the debug pin state to %d\n",
+                        __func__, level);
+            }
+#endif
+            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
+            break;
+        default:
+            /* Unknown pin - do nothing */
+#if defined(PPC_DEBUG_IRQ)
+            if (loglevel & CPU_LOG_INT) {
+                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
+            }
+#endif
+            return;
+        }
+        if (level)
+            env->irq_input_state |= 1 << pin;
+        else
+            env->irq_input_state &= ~(1 << pin);
+    }
+}
+
+void ppce500_irq_init (CPUState *env)
+{
+    env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
+					env, PPCE500_INPUT_NB);
+}
 /*****************************************************************************/
 /* PowerPC time base and decrementer emulation */
 struct ppc_tb_t {
diff --git a/hw/ppc.h b/hw/ppc.h
index 75eb11a..2ec4680 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[];
 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
 
 void ppc40x_irq_init (CPUState *env);
+void ppce500_irq_init (CPUState *env);
 void ppc6xx_irq_init (CPUState *env);
 void ppc970_irq_init (CPUState *env);
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f7a12da..9f92cd8 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1352,6 +1352,18 @@ enum {
 };
 
 enum {
+    /* PowerPC E500 input pins */
+    PPCE500_INPUT_RESET_CORE = 0,
+    PPCE500_INPUT_MCK        = 1,
+    PPCE500_INPUT_RESET_SYS  = 2,      // in order same with 440
+    PPCE500_INPUT_CINT       = 3,
+    PPCE500_INPUT_INT        = 4,
+    PPCE500_INPUT_HALT       = 5,      // in order same with 440
+    PPCE500_INPUT_DEBUG      = 6,
+    PPCE500_INPUT_NB,
+};
+
+enum {
     /* PowerPC 40x input pins */
     PPC40x_INPUT_RESET_CORE = 0,
     PPC40x_INPUT_RESET_CHIP = 1,
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 5008a3a..7953c69 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -4154,7 +4154,8 @@ static void init_proc_e300 (CPUPPCState *env)
                               POWERPC_FLAG_BUS_CLK)
 #define check_pow_e500       check_pow_hid0
 
-__attribute__ (( unused ))
+extern void ppce500_irq_init (CPUState *env);
+
 static void init_proc_e500 (CPUPPCState *env)
 {
     /* Time base */
@@ -4256,7 +4257,8 @@ static void init_proc_e500 (CPUPPCState *env)
     init_excp_e200(env);
     env->dcache_line_size = 32;
     env->icache_line_size = 32;
-    /* XXX: TODO: allocate internal IRQ controller */
+    /* Allocate hardware IRQ controller */
+    ppce500_irq_init(env);
 }
 
 /* Non-embedded PowerPC                                                      */
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-15 12:34             ` Liu Yu
@ 2009-01-15 12:34               ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 Makefile.target |    1 +
 hw/ppce500.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 hw/ppce500.c
 create mode 100644 hw/ppce500.h

diff --git a/Makefile.target b/Makefile.target
index 2079fcb..223d294 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 OBJS+= ppc440.o ppc440_bamboo.o
 # PowerPC E500 boards
 OBJS+= ppce500_pci.o
+OBJS+= ppce500.o
 ifdef FDT_LIBS
 OBJS+= device_tree.o
 LIBS+= $(FDT_LIBS)
diff --git a/hw/ppce500.c b/hw/ppce500.c
new file mode 100644
index 0000000..856cce2
--- /dev/null
+++ b/hw/ppce500.c
@@ -0,0 +1,49 @@
+/*
+ * Qemu PowerPC E500 core emualtion
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc440.c
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "hw/isa.h"
+#include "ppce500.h"
+#include "sysemu.h"
+
+#define bytes_to_mb(a) (a>>20)
+
+CPUState *ppce500_init(ram_addr_t *ram_size)
+{
+    int i;
+    ram_addr_t tmp_ram_size;
+    CPUState *env;
+    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 64<<20}; /* in bytes */
+
+    /* Setup Memory */
+    tmp_ram_size = *ram_size;
+
+    for (i=0; i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
+	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
+	    tmp_ram_size -= ram_stick_sizes[i];
+
+    if (tmp_ram_size)
+	*ram_size -= tmp_ram_size;
+
+    env = cpu_ppc_init("e500v2_v30");
+    if (!env) {
+	fprintf(stderr, "Unable to initilize CPU!\n");
+	exit(1);
+    }
+
+    return env;
+}
diff --git a/hw/ppce500.h b/hw/ppce500.h
new file mode 100644
index 0000000..37c4375
--- /dev/null
+++ b/hw/ppce500.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU PowerPC E500 emulation shared definitions
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc440.h
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#if !defined(PPC_E500_H)
+#define PPC_E500_H
+
+#include "hw.h"
+#include "pc.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "exec-all.h"
+#include "boards.h"
+
+/* PowerPC E500 XXX  initialization */
+extern CPUState *ppce500_init(ram_addr_t *ram_size);
+
+PCIBus *ppce500_pci_init(qemu_irq *pic, target_phys_addr_t registers);
+
+/* mpic.c */
+/* MPIC have 5 outputs per CPU connected and one IRQ out single output */
+enum {
+    MPIC_OUTPUT_INT = 0, /* IRQ                       */
+    MPIC_OUTPUT_CINT,    /* critical IRQ              */
+    MPIC_OUTPUT_MCK,     /* Machine check event       */
+    MPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
+    MPIC_OUTPUT_RESET,   /* Core reset event          */
+    MPIC_OUTPUT_NB,
+};
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+#endif /* !defined(PPC_E500_H) */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-15 12:34               ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 Makefile.target |    1 +
 hw/ppce500.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 hw/ppce500.c
 create mode 100644 hw/ppce500.h

diff --git a/Makefile.target b/Makefile.target
index 2079fcb..223d294 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 OBJS+= ppc440.o ppc440_bamboo.o
 # PowerPC E500 boards
 OBJS+= ppce500_pci.o
+OBJS+= ppce500.o
 ifdef FDT_LIBS
 OBJS+= device_tree.o
 LIBS+= $(FDT_LIBS)
diff --git a/hw/ppce500.c b/hw/ppce500.c
new file mode 100644
index 0000000..856cce2
--- /dev/null
+++ b/hw/ppce500.c
@@ -0,0 +1,49 @@
+/*
+ * Qemu PowerPC E500 core emualtion
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc440.c
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "hw/isa.h"
+#include "ppce500.h"
+#include "sysemu.h"
+
+#define bytes_to_mb(a) (a>>20)
+
+CPUState *ppce500_init(ram_addr_t *ram_size)
+{
+    int i;
+    ram_addr_t tmp_ram_size;
+    CPUState *env;
+    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 64<<20}; /* in bytes */
+
+    /* Setup Memory */
+    tmp_ram_size = *ram_size;
+
+    for (i=0; i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
+	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
+	    tmp_ram_size -= ram_stick_sizes[i];
+
+    if (tmp_ram_size)
+	*ram_size -= tmp_ram_size;
+
+    env = cpu_ppc_init("e500v2_v30");
+    if (!env) {
+	fprintf(stderr, "Unable to initilize CPU!\n");
+	exit(1);
+    }
+
+    return env;
+}
diff --git a/hw/ppce500.h b/hw/ppce500.h
new file mode 100644
index 0000000..37c4375
--- /dev/null
+++ b/hw/ppce500.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU PowerPC E500 emulation shared definitions
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu,     <yu.liu@freescale.com>
+ *
+ * This file is derived from hw/ppc440.h
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#if !defined(PPC_E500_H)
+#define PPC_E500_H
+
+#include "hw.h"
+#include "pc.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "exec-all.h"
+#include "boards.h"
+
+/* PowerPC E500 XXX  initialization */
+extern CPUState *ppce500_init(ram_addr_t *ram_size);
+
+PCIBus *ppce500_pci_init(qemu_irq *pic, target_phys_addr_t registers);
+
+/* mpic.c */
+/* MPIC have 5 outputs per CPU connected and one IRQ out single output */
+enum {
+    MPIC_OUTPUT_INT = 0, /* IRQ                       */
+    MPIC_OUTPUT_CINT,    /* critical IRQ              */
+    MPIC_OUTPUT_MCK,     /* Machine check event       */
+    MPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
+    MPIC_OUTPUT_RESET,   /* Core reset event          */
+    MPIC_OUTPUT_NB,
+};
+qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
+                        qemu_irq **irqs, qemu_irq irq_out);
+#endif /* !defined(PPC_E500_H) */
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH 8/9] powerpc/kvm: extern one function for E500 code use
  2009-01-15 12:34               ` Liu Yu
@ 2009-01-15 12:34                 ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/kvm_ppc.c |    2 +-
 target-ppc/kvm_ppc.h |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index f7ce52b..82c0f42 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -22,7 +22,7 @@ static QEMUTimer *kvmppc_timer;
 static unsigned int kvmppc_timer_rate;
 
 #ifdef HAVE_FDT
-static int kvmppc_read_host_property(const char *node_path, const char *prop,
+int kvmppc_read_host_property(const char *node_path, const char *prop,
                                      void *val, size_t len)
 {
     char *path;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index e536a88..3792ef7 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -11,5 +11,7 @@
 
 void kvmppc_init(void);
 void kvmppc_fdt_update(void *fdt);
+int kvmppc_read_host_property(const char *node_path, const char *prop,
+                                     void *val, size_t len);
 
 #endif /* __KVM_PPC_H__ */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 8/9] powerpc/kvm: extern one function for E500 code use
@ 2009-01-15 12:34                 ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-15 12:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 target-ppc/kvm_ppc.c |    2 +-
 target-ppc/kvm_ppc.h |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index f7ce52b..82c0f42 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -22,7 +22,7 @@ static QEMUTimer *kvmppc_timer;
 static unsigned int kvmppc_timer_rate;
 
 #ifdef HAVE_FDT
-static int kvmppc_read_host_property(const char *node_path, const char *prop,
+int kvmppc_read_host_property(const char *node_path, const char *prop,
                                      void *val, size_t len)
 {
     char *path;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index e536a88..3792ef7 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -11,5 +11,7 @@
 
 void kvmppc_init(void);
 void kvmppc_fdt_update(void *fdt);
+int kvmppc_read_host_property(const char *node_path, const char *prop,
+                                     void *val, size_t len);
 
 #endif /* __KVM_PPC_H__ */
-- 
1.5.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-15 12:34               ` Liu Yu
@ 2009-01-15 19:53                 ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 19:53 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  Makefile.target |    1 +
>  hw/ppce500.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 94 insertions(+), 0 deletions(-)
>  create mode 100644 hw/ppce500.c
>  create mode 100644 hw/ppce500.h
> 
> diff --git a/Makefile.target b/Makefile.target
> index 2079fcb..223d294 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
>  OBJS+= ppc440.o ppc440_bamboo.o
>  # PowerPC E500 boards
>  OBJS+= ppce500_pci.o
> +OBJS+= ppce500.o
>  ifdef FDT_LIBS
>  OBJS+= device_tree.o
>  LIBS+= $(FDT_LIBS)
> diff --git a/hw/ppce500.c b/hw/ppce500.c
> new file mode 100644
> index 0000000..856cce2
> --- /dev/null
> +++ b/hw/ppce500.c
> @@ -0,0 +1,49 @@
> +/*
> + * Qemu PowerPC E500 core emualtion

"emulation"

> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
> + *
> + * Author: Yu Liu,     <yu.liu@freescale.com>
> + *
> + * This file is derived from hw/ppc440.c
> + * the copyright for that material belongs to the original owners.
> + *
> + * This is free software; you can redistribute it and/or modify
> + * it under the terms of  the GNU General  Public License as published by
> + * the Free Software Foundation;  either version 2 of the  License, or
> + * (at your option) any later version.
> + */
> +
> +#include "hw.h"
> +#include "pc.h"
> +#include "hw/isa.h"
> +#include "ppce500.h"
> +#include "sysemu.h"
> +
> +#define bytes_to_mb(a) (a>>20)

Doesn't look like this is used.

> +CPUState *ppce500_init(ram_addr_t *ram_size)
> +{
> +    int i;
> +    ram_addr_t tmp_ram_size;
> +    CPUState *env;
> +    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 64<<20}; /* in bytes */
> +
> +    /* Setup Memory */
> +    tmp_ram_size = *ram_size;
> +
> +    for (i=0; i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
> +	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
> +	    tmp_ram_size -= ram_stick_sizes[i];
> +
> +    if (tmp_ram_size)
> +	*ram_size -= tmp_ram_size;

Since you said you don't actually have a memory controller you're
emulating, I think you should completely remove all this ram_size stuff.
Once you do that, this whole function becomes just cpu_ppc_init(), so
you can just call that instead.

> +    env = cpu_ppc_init("e500v2_v30");
> +    if (!env) {
> +	fprintf(stderr, "Unable to initilize CPU!\n");

"initialize"

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-15 19:53                 ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 19:53 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  Makefile.target |    1 +
>  hw/ppce500.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 94 insertions(+), 0 deletions(-)
>  create mode 100644 hw/ppce500.c
>  create mode 100644 hw/ppce500.h
> 
> diff --git a/Makefile.target b/Makefile.target
> index 2079fcb..223d294 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
>  OBJS+= ppc440.o ppc440_bamboo.o
>  # PowerPC E500 boards
>  OBJS+= ppce500_pci.o
> +OBJS+= ppce500.o
>  ifdef FDT_LIBS
>  OBJS+= device_tree.o
>  LIBS+= $(FDT_LIBS)
> diff --git a/hw/ppce500.c b/hw/ppce500.c
> new file mode 100644
> index 0000000..856cce2
> --- /dev/null
> +++ b/hw/ppce500.c
> @@ -0,0 +1,49 @@
> +/*
> + * Qemu PowerPC E500 core emualtion

"emulation"

> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
> + *
> + * Author: Yu Liu,     <yu.liu@freescale.com>
> + *
> + * This file is derived from hw/ppc440.c
> + * the copyright for that material belongs to the original owners.
> + *
> + * This is free software; you can redistribute it and/or modify
> + * it under the terms of  the GNU General  Public License as published by
> + * the Free Software Foundation;  either version 2 of the  License, or
> + * (at your option) any later version.
> + */
> +
> +#include "hw.h"
> +#include "pc.h"
> +#include "hw/isa.h"
> +#include "ppce500.h"
> +#include "sysemu.h"
> +
> +#define bytes_to_mb(a) (a>>20)

Doesn't look like this is used.

> +CPUState *ppce500_init(ram_addr_t *ram_size)
> +{
> +    int i;
> +    ram_addr_t tmp_ram_size;
> +    CPUState *env;
> +    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 64<<20}; /* in bytes */
> +
> +    /* Setup Memory */
> +    tmp_ram_size = *ram_size;
> +
> +    for (i=0; i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
> +	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
> +	    tmp_ram_size -= ram_stick_sizes[i];
> +
> +    if (tmp_ram_size)
> +	*ram_size -= tmp_ram_size;

Since you said you don't actually have a memory controller you're
emulating, I think you should completely remove all this ram_size stuff.
Once you do that, this whole function becomes just cpu_ppc_init(), so
you can just call that instead.

> +    env = cpu_ppc_init("e500v2_v30");
> +    if (!env) {
> +	fprintf(stderr, "Unable to initilize CPU!\n");

"initialize"

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] Re: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
  2009-01-15 12:34           ` Liu Yu
@ 2009-01-15 20:02             ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 20:02 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  Makefile.target  |    2 +
>  hw/ppce500_pci.c |  369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 371 insertions(+), 0 deletions(-)
>  create mode 100644 hw/ppce500_pci.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index 58fe88f..2079fcb 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
>  # PowerPC 4xx boards
>  OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
>  OBJS+= ppc440.o ppc440_bamboo.o
> +# PowerPC E500 boards
> +OBJS+= ppce500_pci.o
>  ifdef FDT_LIBS
>  OBJS+= device_tree.o
>  LIBS+= $(FDT_LIBS)
> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> new file mode 100644
> index 0000000..9077591
> --- /dev/null
> +++ b/hw/ppce500_pci.c
> @@ -0,0 +1,369 @@
> +/*
> + * QEMU PowerPC E500 embedded processors pci controller emulation
> + *
> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
> + *
> + * Author: Yu Liu,     <yu.liu@freescale.com>
> + *
> + * This file is derived from hw/ppc4xx_pci.c,
> + * the copyright for that material belongs to the original owners.
> + *
> + * This is free software; you can redistribute it and/or modify
> + * it under the terms of  the GNU General  Public License as published by
> + * the Free Software Foundation;  either version 2 of the  License, or
> + * (at your option) any later version.
> + */
> +
> +#include "hw.h"
> +#include "ppc.h"
> +#include "ppce500.h"
> +typedef target_phys_addr_t pci_addr_t;
> +#include "pci.h"
> +#include "pci_host.h"
> +#include "bswap.h"
> +#include "qemu-log.h"
> +
> +#ifdef DEBUG_PCI
> +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
> +#else
> +#define pci_debug(fmt, arg...)
> +#endif
> +
> +#define PCIE500_CFGADDR       0x0
> +#define PCIE500_CFGDATA       0x4
> +#define PCIE500_REG_BASE      0xC00
> +#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
> +
> +#define PPCE500_PCI_CONFIG_ADDR		0x0
> +#define PPCE500_PCI_CONFIG_DATA		0x4
> +#define PPCE500_PCI_INTACK		0x8
> +
> +#define PPCE500_PCI_OW1			(0xC20 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW2			(0xC40 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW3			(0xC60 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW4			(0xC80 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW3			(0xDA0 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW2			(0xDC0 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW1			(0xDE0 - PCIE500_REG_BASE)
> +
> +#define PPCE500_PCI_GASKET_TIMR		(0xE20 - PCIE500_REG_BASE)
> +
> +#define PCI_POTAR		0x0
> +#define PCI_POTEAR		0x4
> +#define PCI_POWBAR		0x8
> +#define PCI_POWAR		0x10
> +
> +#define PCI_PITAR		0x0
> +#define PCI_PIWBAR		0x8
> +#define PCI_PIWBEAR		0xC
> +#define PCI_PIWAR		0x10
> +
> +#define PPCE500_PCI_NR_POBS 5
> +#define PPCE500_PCI_NR_PIBS 3
> +
> +struct  pci_outbound {
> +    uint32_t potar;
> +    uint32_t potear;
> +    uint32_t powbar;
> +    uint32_t powar;
> +};
> +
> +struct pci_inbound {
> +    uint32_t pitar;
> +    uint32_t piwbar;
> +    uint32_t piwbear;
> +    uint32_t piwar;
> +};
> +
> +struct PPCE500PCIState {
> +    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
> +    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> +    uint32_t gasket_time;

Out of curiosity, is "gasket_time" supposed to be an actual timer, or
just a scratch register? It looks like you've just implemented it as a
scratch register.

> +    PCIHostState pci_state;
> +    PCIDevice *pci_dev;
> +};
> +
> +typedef struct PPCE500PCIState PPCE500PCIState;
> +
> +static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
> +{
> +    PPCE500PCIState *pci = opaque;
> +
> +    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
> +		    pci->pci_state.config_reg);
> +    return pci->pci_state.config_reg;
> +}
> +
> +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
> +    &pcie500_cfgaddr_readl,
> +    &pcie500_cfgaddr_readl,
> +    &pcie500_cfgaddr_readl,
> +};
> +
> +static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
> +                                  uint32_t value)
> +{
> +    PPCE500PCIState *controller = opaque;
> +
> +    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
> +    controller->pci_state.config_reg = value & ~0x3;
> +}
> +
> +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
> +    pcie500_cfgaddr_writel,

Missing & here.

> +    &pcie500_cfgaddr_writel,
> +    &pcie500_cfgaddr_writel,
> +};
> +
> +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
> +    &pci_host_data_readb,
> +    &pci_host_data_readw,
> +    &pci_host_data_readl,
> +};
> +
> +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
> +    &pci_host_data_writeb,
> +    &pci_host_data_writew,
> +    &pci_host_data_writel,
> +};
> +
> +static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
> +{
> +    PPCE500PCIState *pci = opaque;
> +    unsigned long win;
> +    uint32_t value = 0;
> +
> +    win = addr & 0xfe0;
> +
> +    switch (win) {
> +    case PPCE500_PCI_OW1:
> +    case PPCE500_PCI_OW2:
> +    case PPCE500_PCI_OW3:
> +    case PPCE500_PCI_OW4:
> +	switch (addr & 0xC) {
> +	case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
> +	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
> +	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
> +	case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
> +	default: break;
> +	}
> +	break;
> +
> +    case PPCE500_PCI_IW3:
> +    case PPCE500_PCI_IW2:
> +    case PPCE500_PCI_IW1:
> +	switch (addr & 0xC) {
> +	case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
> +	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
> +	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
> +	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_GASKET_TIMR:
> +	value = pci->gasket_time;
> +	break;
> +
> +    default:
> +	break;
> +    }
> +
> +    pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
> +    return value;
> +}
> +
> +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
> +    &pci_reg_read4,
> +    &pci_reg_read4,
> +    &pci_reg_read4,
> +};
> +
> +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
> +                               uint32_t value)
> +{
> +    PPCE500PCIState *pci = opaque;
> +    unsigned long win;
> +
> +    win = addr & 0xfe0;
> +
> +    pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
> +
> +    switch (win) {
> +    case PPCE500_PCI_OW1:
> +    case PPCE500_PCI_OW2:
> +    case PPCE500_PCI_OW3:
> +    case PPCE500_PCI_OW4:
> +	switch (addr & 0xC) {
> +	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
> +	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
> +	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
> +	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_IW3:
> +    case PPCE500_PCI_IW2:
> +    case PPCE500_PCI_IW1:
> +	switch (addr & 0xC) {
> +	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
> +	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
> +	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
> +	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_GASKET_TIMR:
> +	pci->gasket_time = value;
> +	break;
> +
> +    default:
> +	break;
> +    };
> +}
> +
> +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
> +    &pci_reg_write4,
> +    &pci_reg_write4,
> +    &pci_reg_write4,
> +};
> +
> +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> +{
> +    int devno = pci_dev->devfn >> 3, ret = 0;
> +
> +    switch (devno) {
> +	/* Two PCI slot */
> +	case 0x11:
> +	case 0x12:
> +	    ret = (irq_num + devno - 0x10) % 4;
> +	    break;
> +	default:
> +	    printf("Error:%s:unknow dev number\n", __func__);
> +    }
> +
> +    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
> +           pci_dev->devfn, irq_num, ret, devno);
> +
> +    return ret;
> +}
> +
> +static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
> +{
> +    pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
> +
> +    qemu_set_irq(pic[irq_num], level);
> +}
> +
> +static void ppce500_pci_save(QEMUFile *f, void *opaque)
> +{
> +    PPCE500PCIState *controller = opaque;
> +    int i;
> +
> +    pci_device_save(controller->pci_dev, f);
> +
> +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> +        qemu_put_be32s(f, &controller->pob[i].potar);
> +        qemu_put_be32s(f, &controller->pob[i].potear);
> +        qemu_put_be32s(f, &controller->pob[i].powbar);
> +        qemu_put_be32s(f, &controller->pob[i].powar);
> +    }
> +
> +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> +        qemu_put_be32s(f, &controller->pib[i].pitar);
> +        qemu_put_be32s(f, &controller->pib[i].piwbar);
> +        qemu_put_be32s(f, &controller->pib[i].piwbear);
> +        qemu_put_be32s(f, &controller->pib[i].piwar);
> +    }
> +    qemu_put_be32s(f, &controller->gasket_time);
> +}
> +
> +static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
> +{
> +    PPCE500PCIState *controller = opaque;
> +    int i;
> +
> +    if (version_id != 1)
> +        return -EINVAL;
> +
> +    pci_device_load(controller->pci_dev, f);
> +
> +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> +        qemu_get_be32s(f, &controller->pob[i].potar);
> +        qemu_get_be32s(f, &controller->pob[i].potear);
> +        qemu_get_be32s(f, &controller->pob[i].powbar);
> +        qemu_get_be32s(f, &controller->pob[i].powar);
> +    }
> +
> +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> +        qemu_get_be32s(f, &controller->pib[i].pitar);
> +        qemu_get_be32s(f, &controller->pib[i].piwbar);
> +        qemu_get_be32s(f, &controller->pib[i].piwbear);
> +        qemu_get_be32s(f, &controller->pib[i].piwar);
> +    }
> +    qemu_get_be32s(f, &controller->gasket_time);
> +
> +    return 0;
> +}

Should have a newline here.

> +PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
> +{
> +    PPCE500PCIState *controller;
> +    PCIDevice *d;
> +    int index;
> +    static int ppce500_pci_id;
> +
> +    controller = qemu_mallocz(sizeof(PPCE500PCIState));
> +    if (!controller)
> +	return NULL;
> +
> +    controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
> +                                                 mpc85xx_pci_map_irq,
> +                                                 pci_irqs, 0x88, 4);
> +    d = pci_register_device(controller->pci_state.bus,
> +                            "host bridge", sizeof(PCIDevice),
> +                            0, NULL, NULL);
> +
> +    d->config[0x00] = 0x57; // vendor_id
> +    d->config[0x01] = 0x19;
> +    d->config[0x02] = 0x30; // device_id
> +    d->config[0x03] = 0x00;
> +    d->config[0x0a] = 0x20; // class_sub = other bridge type
> +    d->config[0x0b] = 0x0B; // class_base = PCI_bridge
> +
> +    controller->pci_dev = d;
> +
> +    /* CFGADDR */
> +    index = cpu_register_io_memory(0, pcie500_cfgaddr_read,
> +                                   pcie500_cfgaddr_write, controller);
> +    if (index < 0)
> +        goto free;
> +    cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
> +
> +    /* CFGDATA */
> +    index = cpu_register_io_memory(0, pcie500_cfgdata_read,
> +                                   pcie500_cfgdata_write,
> +                                   &controller->pci_state);
> +    if (index < 0)
> +        goto free;
> +    cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
> +
> +    index = cpu_register_io_memory(0, e500_pci_reg_read,
> +		                   e500_pci_reg_write, controller);
> +    if (index < 0)
> +	goto free;
> +    cpu_register_physical_memory(registers + PCIE500_REG_BASE,
> +                                   PCIE500_REG_SIZE, index);
> +
> +    /* XXX load/save code not tested. */
> +    register_savevm("ppce500_pci", ppce500_pci_id++, 1,
> +                    ppce500_pci_save, ppce500_pci_load, controller);
> +
> +    return controller->pci_state.bus;
> +
> +free:
> +    printf("%s error\n", __func__);
> +    qemu_free(controller);
> +    return NULL;
> +}

The rest looks pretty good. :)

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
@ 2009-01-15 20:02             ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 20:02 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  Makefile.target  |    2 +
>  hw/ppce500_pci.c |  369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 371 insertions(+), 0 deletions(-)
>  create mode 100644 hw/ppce500_pci.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index 58fe88f..2079fcb 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
>  # PowerPC 4xx boards
>  OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
>  OBJS+= ppc440.o ppc440_bamboo.o
> +# PowerPC E500 boards
> +OBJS+= ppce500_pci.o
>  ifdef FDT_LIBS
>  OBJS+= device_tree.o
>  LIBS+= $(FDT_LIBS)
> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> new file mode 100644
> index 0000000..9077591
> --- /dev/null
> +++ b/hw/ppce500_pci.c
> @@ -0,0 +1,369 @@
> +/*
> + * QEMU PowerPC E500 embedded processors pci controller emulation
> + *
> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
> + *
> + * Author: Yu Liu,     <yu.liu@freescale.com>
> + *
> + * This file is derived from hw/ppc4xx_pci.c,
> + * the copyright for that material belongs to the original owners.
> + *
> + * This is free software; you can redistribute it and/or modify
> + * it under the terms of  the GNU General  Public License as published by
> + * the Free Software Foundation;  either version 2 of the  License, or
> + * (at your option) any later version.
> + */
> +
> +#include "hw.h"
> +#include "ppc.h"
> +#include "ppce500.h"
> +typedef target_phys_addr_t pci_addr_t;
> +#include "pci.h"
> +#include "pci_host.h"
> +#include "bswap.h"
> +#include "qemu-log.h"
> +
> +#ifdef DEBUG_PCI
> +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
> +#else
> +#define pci_debug(fmt, arg...)
> +#endif
> +
> +#define PCIE500_CFGADDR       0x0
> +#define PCIE500_CFGDATA       0x4
> +#define PCIE500_REG_BASE      0xC00
> +#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
> +
> +#define PPCE500_PCI_CONFIG_ADDR		0x0
> +#define PPCE500_PCI_CONFIG_DATA		0x4
> +#define PPCE500_PCI_INTACK		0x8
> +
> +#define PPCE500_PCI_OW1			(0xC20 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW2			(0xC40 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW3			(0xC60 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_OW4			(0xC80 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW3			(0xDA0 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW2			(0xDC0 - PCIE500_REG_BASE)
> +#define PPCE500_PCI_IW1			(0xDE0 - PCIE500_REG_BASE)
> +
> +#define PPCE500_PCI_GASKET_TIMR		(0xE20 - PCIE500_REG_BASE)
> +
> +#define PCI_POTAR		0x0
> +#define PCI_POTEAR		0x4
> +#define PCI_POWBAR		0x8
> +#define PCI_POWAR		0x10
> +
> +#define PCI_PITAR		0x0
> +#define PCI_PIWBAR		0x8
> +#define PCI_PIWBEAR		0xC
> +#define PCI_PIWAR		0x10
> +
> +#define PPCE500_PCI_NR_POBS 5
> +#define PPCE500_PCI_NR_PIBS 3
> +
> +struct  pci_outbound {
> +    uint32_t potar;
> +    uint32_t potear;
> +    uint32_t powbar;
> +    uint32_t powar;
> +};
> +
> +struct pci_inbound {
> +    uint32_t pitar;
> +    uint32_t piwbar;
> +    uint32_t piwbear;
> +    uint32_t piwar;
> +};
> +
> +struct PPCE500PCIState {
> +    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
> +    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> +    uint32_t gasket_time;

Out of curiosity, is "gasket_time" supposed to be an actual timer, or
just a scratch register? It looks like you've just implemented it as a
scratch register.

> +    PCIHostState pci_state;
> +    PCIDevice *pci_dev;
> +};
> +
> +typedef struct PPCE500PCIState PPCE500PCIState;
> +
> +static uint32_t pcie500_cfgaddr_readl(void *opaque, target_phys_addr_t addr)
> +{
> +    PPCE500PCIState *pci = opaque;
> +
> +    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
> +		    pci->pci_state.config_reg);
> +    return pci->pci_state.config_reg;
> +}
> +
> +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
> +    &pcie500_cfgaddr_readl,
> +    &pcie500_cfgaddr_readl,
> +    &pcie500_cfgaddr_readl,
> +};
> +
> +static void pcie500_cfgaddr_writel(void *opaque, target_phys_addr_t addr,
> +                                  uint32_t value)
> +{
> +    PPCE500PCIState *controller = opaque;
> +
> +    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, value, addr);
> +    controller->pci_state.config_reg = value & ~0x3;
> +}
> +
> +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
> +    pcie500_cfgaddr_writel,

Missing & here.

> +    &pcie500_cfgaddr_writel,
> +    &pcie500_cfgaddr_writel,
> +};
> +
> +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
> +    &pci_host_data_readb,
> +    &pci_host_data_readw,
> +    &pci_host_data_readl,
> +};
> +
> +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
> +    &pci_host_data_writeb,
> +    &pci_host_data_writew,
> +    &pci_host_data_writel,
> +};
> +
> +static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr)
> +{
> +    PPCE500PCIState *pci = opaque;
> +    unsigned long win;
> +    uint32_t value = 0;
> +
> +    win = addr & 0xfe0;
> +
> +    switch (win) {
> +    case PPCE500_PCI_OW1:
> +    case PPCE500_PCI_OW2:
> +    case PPCE500_PCI_OW3:
> +    case PPCE500_PCI_OW4:
> +	switch (addr & 0xC) {
> +	case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break;
> +	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break;
> +	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break;
> +	case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break;
> +	default: break;
> +	}
> +	break;
> +
> +    case PPCE500_PCI_IW3:
> +    case PPCE500_PCI_IW2:
> +    case PPCE500_PCI_IW1:
> +	switch (addr & 0xC) {
> +	case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break;
> +	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break;
> +	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break;
> +	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_GASKET_TIMR:
> +	value = pci->gasket_time;
> +	break;
> +
> +    default:
> +	break;
> +    }
> +
> +    pci_debug("%s: win:%lx(addr:%Lx) -> value:%x\n",__func__,win,addr,value);
> +    return value;
> +}
> +
> +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
> +    &pci_reg_read4,
> +    &pci_reg_read4,
> +    &pci_reg_read4,
> +};
> +
> +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
> +                               uint32_t value)
> +{
> +    PPCE500PCIState *pci = opaque;
> +    unsigned long win;
> +
> +    win = addr & 0xfe0;
> +
> +    pci_debug("%s: value:%x -> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
> +
> +    switch (win) {
> +    case PPCE500_PCI_OW1:
> +    case PPCE500_PCI_OW2:
> +    case PPCE500_PCI_OW3:
> +    case PPCE500_PCI_OW4:
> +	switch (addr & 0xC) {
> +	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break;
> +	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break;
> +	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break;
> +	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_IW3:
> +    case PPCE500_PCI_IW2:
> +    case PPCE500_PCI_IW1:
> +	switch (addr & 0xC) {
> +	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break;
> +	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break;
> +	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break;
> +	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break;
> +	default: break;
> +	};
> +	break;
> +
> +    case PPCE500_PCI_GASKET_TIMR:
> +	pci->gasket_time = value;
> +	break;
> +
> +    default:
> +	break;
> +    };
> +}
> +
> +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
> +    &pci_reg_write4,
> +    &pci_reg_write4,
> +    &pci_reg_write4,
> +};
> +
> +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> +{
> +    int devno = pci_dev->devfn >> 3, ret = 0;
> +
> +    switch (devno) {
> +	/* Two PCI slot */
> +	case 0x11:
> +	case 0x12:
> +	    ret = (irq_num + devno - 0x10) % 4;
> +	    break;
> +	default:
> +	    printf("Error:%s:unknow dev number\n", __func__);
> +    }
> +
> +    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
> +           pci_dev->devfn, irq_num, ret, devno);
> +
> +    return ret;
> +}
> +
> +static void mpc85xx_pci_set_irq(qemu_irq *pic, int irq_num, int level)
> +{
> +    pci_debug("%s: PCI irq %d, level:%d\n", __func__, irq_num, level);
> +
> +    qemu_set_irq(pic[irq_num], level);
> +}
> +
> +static void ppce500_pci_save(QEMUFile *f, void *opaque)
> +{
> +    PPCE500PCIState *controller = opaque;
> +    int i;
> +
> +    pci_device_save(controller->pci_dev, f);
> +
> +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> +        qemu_put_be32s(f, &controller->pob[i].potar);
> +        qemu_put_be32s(f, &controller->pob[i].potear);
> +        qemu_put_be32s(f, &controller->pob[i].powbar);
> +        qemu_put_be32s(f, &controller->pob[i].powar);
> +    }
> +
> +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> +        qemu_put_be32s(f, &controller->pib[i].pitar);
> +        qemu_put_be32s(f, &controller->pib[i].piwbar);
> +        qemu_put_be32s(f, &controller->pib[i].piwbear);
> +        qemu_put_be32s(f, &controller->pib[i].piwar);
> +    }
> +    qemu_put_be32s(f, &controller->gasket_time);
> +}
> +
> +static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
> +{
> +    PPCE500PCIState *controller = opaque;
> +    int i;
> +
> +    if (version_id != 1)
> +        return -EINVAL;
> +
> +    pci_device_load(controller->pci_dev, f);
> +
> +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> +        qemu_get_be32s(f, &controller->pob[i].potar);
> +        qemu_get_be32s(f, &controller->pob[i].potear);
> +        qemu_get_be32s(f, &controller->pob[i].powbar);
> +        qemu_get_be32s(f, &controller->pob[i].powar);
> +    }
> +
> +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> +        qemu_get_be32s(f, &controller->pib[i].pitar);
> +        qemu_get_be32s(f, &controller->pib[i].piwbar);
> +        qemu_get_be32s(f, &controller->pib[i].piwbear);
> +        qemu_get_be32s(f, &controller->pib[i].piwar);
> +    }
> +    qemu_get_be32s(f, &controller->gasket_time);
> +
> +    return 0;
> +}

Should have a newline here.

> +PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
> +{
> +    PPCE500PCIState *controller;
> +    PCIDevice *d;
> +    int index;
> +    static int ppce500_pci_id;
> +
> +    controller = qemu_mallocz(sizeof(PPCE500PCIState));
> +    if (!controller)
> +	return NULL;
> +
> +    controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
> +                                                 mpc85xx_pci_map_irq,
> +                                                 pci_irqs, 0x88, 4);
> +    d = pci_register_device(controller->pci_state.bus,
> +                            "host bridge", sizeof(PCIDevice),
> +                            0, NULL, NULL);
> +
> +    d->config[0x00] = 0x57; // vendor_id
> +    d->config[0x01] = 0x19;
> +    d->config[0x02] = 0x30; // device_id
> +    d->config[0x03] = 0x00;
> +    d->config[0x0a] = 0x20; // class_sub = other bridge type
> +    d->config[0x0b] = 0x0B; // class_base = PCI_bridge
> +
> +    controller->pci_dev = d;
> +
> +    /* CFGADDR */
> +    index = cpu_register_io_memory(0, pcie500_cfgaddr_read,
> +                                   pcie500_cfgaddr_write, controller);
> +    if (index < 0)
> +        goto free;
> +    cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
> +
> +    /* CFGDATA */
> +    index = cpu_register_io_memory(0, pcie500_cfgdata_read,
> +                                   pcie500_cfgdata_write,
> +                                   &controller->pci_state);
> +    if (index < 0)
> +        goto free;
> +    cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
> +
> +    index = cpu_register_io_memory(0, e500_pci_reg_read,
> +		                   e500_pci_reg_write, controller);
> +    if (index < 0)
> +	goto free;
> +    cpu_register_physical_memory(registers + PCIE500_REG_BASE,
> +                                   PCIE500_REG_SIZE, index);
> +
> +    /* XXX load/save code not tested. */
> +    register_savevm("ppce500_pci", ppce500_pci_id++, 1,
> +                    ppce500_pci_save, ppce500_pci_load, controller);
> +
> +    return controller->pci_state.bus;
> +
> +free:
> +    printf("%s error\n", __func__);
> +    qemu_free(controller);
> +    return NULL;
> +}

The rest looks pretty good. :)

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] Re: [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
  2009-01-15 12:34 ` Liu Yu
@ 2009-01-15 20:06   ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 20:06 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> This patchset enable the support of MPC85xx platform in qemu/kvm.
> 
> patch 1,2: bug fix
> patch 3: enable mpic for E500 core.
> patch 4: enable E500 mmu in kvm mode.
> patch 5: add E500 pci controller emulation.
> patch 6: add E500 irq support
> patch 7: add E500 core emulation
> patch 8: extern one function for E500 code use
> patch 9: add MPC85xx boards emulation.

(In case it was unclear to any of the Qemu folks, this is another KVM
PowerPC platform. Like the 440 core, the MMU and a few other bits are
not currently emulated in Qemu itself, so right now it's only functional
in conjunction with KVM.)

Looks pretty good, Yu. :)

Patches 1, 2, 4, 8:
	Acked-by: Hollis Blanchard <hollisb@us.ibm.com>
I've either commented on the other patches, or they're in areas of qemu
with which I'm not too familiar.

By the way, I think you forgot patch 9, which will tie it all together
by emulating an 85xx SoC?

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
@ 2009-01-15 20:06   ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-15 20:06 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> This patchset enable the support of MPC85xx platform in qemu/kvm.
> 
> patch 1,2: bug fix
> patch 3: enable mpic for E500 core.
> patch 4: enable E500 mmu in kvm mode.
> patch 5: add E500 pci controller emulation.
> patch 6: add E500 irq support
> patch 7: add E500 core emulation
> patch 8: extern one function for E500 code use
> patch 9: add MPC85xx boards emulation.

(In case it was unclear to any of the Qemu folks, this is another KVM
PowerPC platform. Like the 440 core, the MMU and a few other bits are
not currently emulated in Qemu itself, so right now it's only functional
in conjunction with KVM.)

Looks pretty good, Yu. :)

Patches 1, 2, 4, 8:
	Acked-by: Hollis Blanchard <hollisb@us.ibm.com>
I've either commented on the other patches, or they're in areas of qemu
with which I'm not too familiar.

By the way, I think you forgot patch 9, which will tie it all together
by emulating an 85xx SoC?

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
  2009-01-15 12:34       ` Liu Yu
@ 2009-01-15 21:22         ` Anthony Liguori
  -1 siblings, 0 replies; 52+ messages in thread
From: Anthony Liguori @ 2009-01-15 21:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Liu Yu wrote:
> The modify is based on original author's method
> to switch openpic and mpic by static define,
> like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> (Although the support for intel has broken)
> So they can't be used at the same time.
>
> I guess it's not the correct way to do this.
> but I am not sure is the USE_MPC85xx and openpic are still needed?
>   

Have you tested some of the other (TCG) boards (for instance, with the 
debian image Aurelien recently posted)?

Regards,

Anthony Liguori

> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  hw/openpic.c |  384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  hw/openpic.h |   19 +++
>  hw/ppc_mac.h |   14 +--
>  3 files changed, 389 insertions(+), 28 deletions(-)
>  create mode 100644 hw/openpic.h
>
> diff --git a/hw/openpic.c b/hw/openpic.c
> index b8da4d7..bc5f72b 100644
> --- a/hw/openpic.c
> +++ b/hw/openpic.c
> @@ -35,6 +35,7 @@
>  #include "hw.h"
>  #include "ppc_mac.h"
>  #include "pci.h"
> +#include "openpic.h"
>  
>  //#define DEBUG_OPENPIC
>  
> @@ -45,7 +46,8 @@
>  #endif
>  #define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
>  
> -#define USE_MPCxxx /* Intel model is broken, for now */
> +/*#define USE_MPCxxx |+ Intel model is broken, for now +|*/
> +#define USE_MPC85xx /* Intel model is broken, for now */
>  
>  #if defined (USE_INTEL_GW80314)
>  /* Intel GW80314 I/O Companion chip */
> @@ -84,15 +86,6 @@ enum {
>  #define OPENPIC_LITTLE_ENDIAN 1
>  #define OPENPIC_BIG_ENDIAN    0
>  
> -#else
> -#error "Please select which OpenPic implementation is to be emulated"
> -#endif
> -
> -#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
> -    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
> -#define OPENPIC_SWAP
> -#endif
> -
>  /* Interrupt definitions */
>  #define IRQ_FE     (EXT_IRQ)     /* Internal functional IRQ */
>  #define IRQ_ERR    (EXT_IRQ + 1) /* Error IRQ */
> @@ -105,6 +98,61 @@ enum {
>  #define IRQ_MBX0   (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
>  #endif
>  
> +#elif defined(USE_MPC85xx)
> +
> +#define MPIC_MAP_SIZE	0x40000
> +
> +#define MAX_CPU     1
> +#define MAX_EXT    12
> +#define MAX_INT    64
> +#define MAX_DBL     0
> +#define MAX_MBX     0
> +#define MAX_TMR     4
> +#define MAX_MSG     4
> +#define MAX_MSI     8
> +#define MAX_IPI     4
> +#define MAX_IRQ    (MAX_EXT + MAX_INT + MAX_TMR + MAX_MSG + MAX_MSI + (MAX_IPI * MAX_CPU))
> +
> +#define VECTOR_BITS 8
> +#define VID         0x0 /* MPIC version ID */
> +#define VENI        0x00000000 /* Vendor ID */
> +
> +enum {
> +    IRQ_IPVP = 0,
> +    IRQ_IDE,
> +};
> +
> +enum ide_bits {
> +    IDR_EP     = 0,
> +    IDR_CI0     = 1,
> +    IDR_CI1     = 2,
> +    IDR_P1     = 30,
> +    IDR_P0     = 31,
> +};
> +
> +#define OPENPIC_LITTLE_ENDIAN 0
> +#define OPENPIC_BIG_ENDIAN    1
> +
> +/* Interrupt definitions */
> +#define EXT_IRQ		0
> +#define INT_IRQ		(EXT_IRQ + MAX_EXT)
> +#define TMR_IRQ		(INT_IRQ + MAX_INT)
> +#define MSG_IRQ		(TMR_IRQ + MAX_TMR)
> +#define MSI_IRQ		(MSG_IRQ + MAX_MSG)
> +#define IPI_IRQ		(MSI_IRQ + MAX_MSI)
> +
> +#define IRQ_IPI0        IPI_IRQ
> +#define IRQ_TIM0        TMR_IRQ
> +
> +#else
> +#error "Please select which OpenPic implementation is to be emulated"
> +#endif
> +
> +#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
> +    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
> +#define OPENPIC_SWAP
> +#endif
> +
>  #define BF_WIDTH(_bits_) \
>  (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
>  
> @@ -157,6 +205,7 @@ enum IPVP_bits {
>  #define IPVP_VECTOR(_ipvpr_)   ((_ipvpr_) & IPVP_VECTOR_MASK)
>  
>  typedef struct IRQ_dst_t {
> +    uint32_t tfrr;
>      uint32_t pctp; /* CPU current task priority */
>      uint32_t pcsr; /* CPU sensitivity register */
>      IRQ_queue_t raised;
> @@ -200,6 +249,8 @@ typedef struct openpic_t {
>  #endif
>      /* IRQ out is used when in bypass mode (not implemented) */
>      qemu_irq irq_out;
> +    void (*reset) (struct openpic_t *);
> +    void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *);
>  } openpic_t;
>  
>  static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
> @@ -286,7 +337,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
>          return;
>      }
>      DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
> -    qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
> +    opp->irq_raise(opp, n_CPU, src);
>  }
>  
>  /* update pic state because registers for n_IRQ have changed value */
> @@ -551,8 +602,8 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
>      case 0x00: /* FREP */
>          break;
>      case 0x20: /* GLBC */
> -        if (val & 0x80000000)
> -            openpic_reset(opp);
> +        if (val & 0x80000000 && opp->reset)
> +            opp->reset(opp);
>          opp->glbc = val & ~0x80000000;
>  	break;
>      case 0x80: /* VENI */
> @@ -818,7 +869,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
>               IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
>              DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
>                      idx, n_IRQ);
> -            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
> +            opp->irq_raise(opp, idx, src);
>          }
>  	break;
>      default:
> @@ -1001,6 +1052,11 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
>  #endif
>  }
>  
> +static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
> +{
> +    qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
> +}
> +
>  qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
>                          qemu_irq **irqs, qemu_irq irq_out)
>  {
> @@ -1058,9 +1114,307 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
>      for (i = 0; i < nb_cpus; i++)
>          opp->dst[i].irqs = irqs[i];
>      opp->irq_out = irq_out;
> -    openpic_reset(opp);
> +
> +    opp->irq_raise = openpic_irq_raise;
> +    opp->reset = openpic_reset;
> +
> +    opp->reset(opp);
>      if (pmem_index)
>          *pmem_index = opp->mem_index;
>  
>      return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
>  }
> +
> +static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
> +{
> +    int n_ci = IDR_CI0 - n_CPU;
> +    DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
> +		    n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
> +    if(test_bit(&src->ide, n_ci)) {
> +        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
> +    }
> +    else {
> +        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
> +    }
> +}
> +
> +static void mpic_reset (openpic_t *mpp)
> +{
> +    int i;
> +
> +    mpp->glbc = 0x80000000;
> +    /* Initialise controller registers */
> +    mpp->frep = 0x004f0002;
> +    mpp->veni = VENI;
> +    mpp->pint = 0x00000000;
> +    mpp->spve = 0x0000FFFF;
> +    /* Initialise IRQ sources */
> +    for (i = 0; i < MAX_IRQ; i++) {
> +	mpp->src[i].ipvp = 0x80800000;
> +	mpp->src[i].ide  = 0x00000001;
> +    }
> +    /* Initialise IRQ destinations */
> +    for (i = 0; i < MAX_CPU; i++) {
> +	mpp->dst[i].pctp      = 0x0000000F;
> +        mpp->dst[i].tfrr      = 0x00000000;
> +	memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
> +	mpp->dst[i].raised.next = -1;
> +	memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
> +	mpp->dst[i].servicing.next = -1;
> +    }
> +    /* Initialise timers */
> +    for (i = 0; i < MAX_TMR; i++) {
> +	mpp->timers[i].ticc = 0x00000000;
> +	mpp->timers[i].tibc = 0x80000000;
> +    }
> +    /* Go out of RESET state */
> +    mpp->glbc = 0x00000000;
> +}
> +
> +static void mpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +    int idx, cpu;
> +
> +    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
> +    if (addr & 0xF)
> +        return;
> +#if defined MPIC_SWAP
> +    val = bswap32(val);
> +#endif
> +    addr &= 0xFFFF;
> +    cpu = addr >> 12;
> +    idx = (addr >> 6) & 0x3;
> +    switch (addr & 0x30) {
> +    case 0x00: /* gtccr */
> +        break;
> +    case 0x10: /* gtbcr */
> +	if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
> +	    (val & 0x80000000) == 0 &&
> +            (mpp->timers[idx].tibc & 0x80000000) != 0)
> +	    mpp->timers[idx].ticc &= ~0x80000000;
> +	mpp->timers[idx].tibc = val;
> +	break;
> +    case 0x20: /* GTIVPR */
> +	write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP, val);
> +	break;
> +    case 0x30: /* GTIDR & TFRR */
> +	if ((addr & 0xF0) == 0xF0)
> +            mpp->dst[cpu].tfrr = val;
> +	else
> +	    write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE, val);
> +	break;
> +    }
> +}
> +
> +static uint32_t mpic_timer_read (void *opaque, uint32_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval;
> +    int idx, cpu;
> +
> +    DPRINTF("%s: addr %08x\n", __func__, addr);
> +    retval = 0xFFFFFFFF;
> +    if (addr & 0xF)
> +        return retval;
> +    addr &= 0xFFFF;
> +    cpu = addr >> 12;
> +    idx = (addr >> 6) & 0x3;
> +    switch (addr & 0x30) {
> +    case 0x00: /* gtccr */
> +	retval = mpp->timers[idx].ticc;
> +        break;
> +    case 0x10: /* gtbcr */
> +	retval = mpp->timers[idx].tibc;
> +	break;
> +    case 0x20: /* TIPV */
> +	retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP);
> +	break;
> +    case 0x30: /* TIDR */
> +        if ((addr &0xF0) == 0XF0)
> +	    retval = mpp->dst[cpu].tfrr;
> +	else
> +	    retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE);
> +	break;
> +    }
> +    DPRINTF("%s: => %08x\n", __func__, retval);
> +#if defined MPIC_SWAP
> +    retval = bswap32(retval);
> +#endif
> +
> +    return retval;
> +}
> +
> +static void mpic_src_write (void *opaque, uint32_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +    int idx;
> +
> +    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
> +    if (addr & 0xF)
> +        return;
> +#if defined MPIC_SWAP
> +    val = tswap32(val);
> +#endif
> +    addr = addr & 0xFFF0;
> +    if (addr < 0x180) {
> +	idx = EXT_IRQ;
> +    } else if (addr >= 0x200 && addr < 0xa00) {
> +	idx = INT_IRQ;
> +	addr -= 0x200;
> +    } else if (addr >= 0x1600 && addr < 0x1700) {
> +	idx = MSG_IRQ;
> +	addr -= 0x1600;
> +    } else if (addr >= 0x1C00 && addr < 0x1D00) {
> +	idx = MSI_IRQ;
> +	addr -= 0x1C00;
> +    } else {
> +	return;
> +    }
> +    idx += addr >> 5;
> +    if (addr & 0x10) {
> +        /* EXDE / IFEDE / IEEDE */
> +        write_IRQreg(mpp, idx, IRQ_IDE, val);
> +    } else {
> +        /* EXVP / IFEVP / IEEVP */
> +        write_IRQreg(mpp, idx, IRQ_IPVP, val);
> +    }
> +}
> +
> +static uint32_t mpic_src_read (void *opaque, uint32_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval;
> +    int idx;
> +
> +    DPRINTF("%s: addr %08x\n", __func__, addr);
> +    retval = 0xFFFFFFFF;
> +    if (addr & 0xF)
> +        return retval;
> +    addr = addr & 0xFFF0;
> +    if (addr < 0x180) {
> +	idx = EXT_IRQ;
> +    } else if (addr >= 0x200 && addr < 0xa00) {
> +	idx = INT_IRQ;
> +	addr -= 0x200;
> +    } else if (addr >= 0x1600 && addr < 0x1700) {
> +	idx = MSG_IRQ;
> +	addr -= 0x1600;
> +    } else if (addr >= 0x1C00 && addr < 0x1D00) {
> +	idx = MSI_IRQ;
> +	addr -= 0x1C00;
> +    } else {
> +	return retval;
> +    }
> +    idx += addr >> 5;
> +    if (addr & 0x10) {
> +        /* EXDE / IFEDE / IEEDE */
> +        retval = read_IRQreg(mpp, idx, IRQ_IDE);
> +    } else {
> +        /* EXVP / IFEVP / IEEVP */
> +        retval = read_IRQreg(mpp, idx, IRQ_IPVP);
> +    }
> +    DPRINTF("%s: => %08x\n", __func__, retval);
> +#if defined MPIC_SWAP
> +    retval = tswap32(retval);
> +#endif
> +
> +    return retval;
> +}
> +
> +static void mpic_writel (void *opaque,
> +                            target_phys_addr_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +
> +    addr &= 0x3FFFF;
> +    DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
> +    if (addr < 0x10F0) {
> +        /* Global registers */
> +	openpic_gbl_write(mpp, addr, val);
> +    } else if (addr < 0x10000) {
> +        /* Timers registers */
> +        mpic_timer_write(mpp, addr, val);
> +    } else if (addr < 0x20000) {
> +        /* Source registers */
> +        mpic_src_write(mpp, addr, val);
> +    } else if (addr < 0x30000){
> +        /* CPU registers */
> +	openpic_cpu_write(mpp, addr, val);
> +    } else {
> +    	DPRINTF("wrong mpic write addr %p\n",addr);
> +    }
> +}
> +
> +static uint32_t mpic_readl (void *opaque,target_phys_addr_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval = 0;
> +
> +    addr &= 0x3FFFF;
> +    DPRINTF("%s: offset %08x\n", __func__, (int)addr);
> +    if (addr < 0x10F0) {
> +        /* Global registers */
> +	retval = openpic_gbl_read(mpp, addr);
> +    } else if (addr < 0x10000) {
> +        /* Timers registers */
> +        retval = mpic_timer_read(mpp, addr);
> +    } else if (addr < 0x20000) {
> +        /* Source registers */
> +        retval = mpic_src_read(mpp, addr);
> +    } else if (addr < 0x30000){
> +        /* CPU registers */
> +	retval = openpic_cpu_read(mpp, addr);
> +    } else {
> +    	DPRINTF("wrong mpic read addr %p\n",addr);
> +    }
> +
> +    return retval;
> +}
> +
> +static CPUWriteMemoryFunc *mpic_write[] = {
> +    &openpic_buggy_write,
> +    &openpic_buggy_write,
> +    &mpic_writel,
> +};
> +
> +static CPUReadMemoryFunc *mpic_read[] = {
> +    &openpic_buggy_read,
> +    &openpic_buggy_read,
> +    &mpic_readl,
> +};
> +
> +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out)
> +{
> +    openpic_t *mpp;
> +    int i;
> +
> +    /* XXX: for now, only one CPU is supported */
> +    if (nb_cpus != 1)
> +        return NULL;
> +
> +    mpp = qemu_mallocz(sizeof(openpic_t));
> +
> +    mpp->mem_index = cpu_register_io_memory(0, mpic_read, mpic_write, mpp);
> +    if (mpp->mem_index < 0)
> +	goto free;
> +    cpu_register_physical_memory(base, MPIC_MAP_SIZE, mpp->mem_index);
> +
> +    mpp->nb_cpus = nb_cpus;
> +
> +    for (i = 0; i < nb_cpus; i++)
> +        mpp->dst[i].irqs = irqs[i];
> +    mpp->irq_out = irq_out;
> +
> +    mpp->irq_raise = mpic_irq_raise;
> +    mpp->reset = mpic_reset;
> +
> +    mpp->reset(mpp);
> +
> +    return qemu_allocate_irqs(openpic_set_irq, mpp, MAX_IRQ);
> +
> +free:
> +    qemu_free(mpp);
> +    return NULL;
> +}
> diff --git a/hw/openpic.h b/hw/openpic.h
> new file mode 100644
> index 0000000..2f85e16
> --- /dev/null
> +++ b/hw/openpic.h
> @@ -0,0 +1,19 @@
> +
> +#if !defined(OPENPIC_H)
> +#define OPENPIC_H
> +
> +/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
> +enum {
> +    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
> +    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
> +    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
> +    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
> +    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
> +    OPENPIC_OUTPUT_NB,
> +};
> +
> +qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out);
> +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out);
> +#endif /* OPENPIC_H */
> diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
> index cc70fb7..bf987b1 100644
> --- a/hw/ppc_mac.h
> +++ b/hw/ppc_mac.h
> @@ -113,17 +113,5 @@ void adb_mouse_init(ADBBusState *bus);
>  
>  extern ADBBusState adb_bus;
>  
> -/* openpic.c */
> -/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
> -enum {
> -    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
> -    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
> -    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
> -    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
> -    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
> -    OPENPIC_OUTPUT_NB,
> -};
> -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
> -                        qemu_irq **irqs, qemu_irq irq_out);
> -
> +#include "openpic.h"
>  #endif /* !defined(__PPC_MAC_H__) */
>   

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
@ 2009-01-15 21:22         ` Anthony Liguori
  0 siblings, 0 replies; 52+ messages in thread
From: Anthony Liguori @ 2009-01-15 21:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

Liu Yu wrote:
> The modify is based on original author's method
> to switch openpic and mpic by static define,
> like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> (Although the support for intel has broken)
> So they can't be used at the same time.
>
> I guess it's not the correct way to do this.
> but I am not sure is the USE_MPC85xx and openpic are still needed?
>   

Have you tested some of the other (TCG) boards (for instance, with the 
debian image Aurelien recently posted)?

Regards,

Anthony Liguori

> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
>  hw/openpic.c |  384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  hw/openpic.h |   19 +++
>  hw/ppc_mac.h |   14 +--
>  3 files changed, 389 insertions(+), 28 deletions(-)
>  create mode 100644 hw/openpic.h
>
> diff --git a/hw/openpic.c b/hw/openpic.c
> index b8da4d7..bc5f72b 100644
> --- a/hw/openpic.c
> +++ b/hw/openpic.c
> @@ -35,6 +35,7 @@
>  #include "hw.h"
>  #include "ppc_mac.h"
>  #include "pci.h"
> +#include "openpic.h"
>  
>  //#define DEBUG_OPENPIC
>  
> @@ -45,7 +46,8 @@
>  #endif
>  #define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
>  
> -#define USE_MPCxxx /* Intel model is broken, for now */
> +/*#define USE_MPCxxx |+ Intel model is broken, for now +|*/
> +#define USE_MPC85xx /* Intel model is broken, for now */
>  
>  #if defined (USE_INTEL_GW80314)
>  /* Intel GW80314 I/O Companion chip */
> @@ -84,15 +86,6 @@ enum {
>  #define OPENPIC_LITTLE_ENDIAN 1
>  #define OPENPIC_BIG_ENDIAN    0
>  
> -#else
> -#error "Please select which OpenPic implementation is to be emulated"
> -#endif
> -
> -#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
> -    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
> -#define OPENPIC_SWAP
> -#endif
> -
>  /* Interrupt definitions */
>  #define IRQ_FE     (EXT_IRQ)     /* Internal functional IRQ */
>  #define IRQ_ERR    (EXT_IRQ + 1) /* Error IRQ */
> @@ -105,6 +98,61 @@ enum {
>  #define IRQ_MBX0   (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
>  #endif
>  
> +#elif defined(USE_MPC85xx)
> +
> +#define MPIC_MAP_SIZE	0x40000
> +
> +#define MAX_CPU     1
> +#define MAX_EXT    12
> +#define MAX_INT    64
> +#define MAX_DBL     0
> +#define MAX_MBX     0
> +#define MAX_TMR     4
> +#define MAX_MSG     4
> +#define MAX_MSI     8
> +#define MAX_IPI     4
> +#define MAX_IRQ    (MAX_EXT + MAX_INT + MAX_TMR + MAX_MSG + MAX_MSI + (MAX_IPI * MAX_CPU))
> +
> +#define VECTOR_BITS 8
> +#define VID         0x0 /* MPIC version ID */
> +#define VENI        0x00000000 /* Vendor ID */
> +
> +enum {
> +    IRQ_IPVP = 0,
> +    IRQ_IDE,
> +};
> +
> +enum ide_bits {
> +    IDR_EP     = 0,
> +    IDR_CI0     = 1,
> +    IDR_CI1     = 2,
> +    IDR_P1     = 30,
> +    IDR_P0     = 31,
> +};
> +
> +#define OPENPIC_LITTLE_ENDIAN 0
> +#define OPENPIC_BIG_ENDIAN    1
> +
> +/* Interrupt definitions */
> +#define EXT_IRQ		0
> +#define INT_IRQ		(EXT_IRQ + MAX_EXT)
> +#define TMR_IRQ		(INT_IRQ + MAX_INT)
> +#define MSG_IRQ		(TMR_IRQ + MAX_TMR)
> +#define MSI_IRQ		(MSG_IRQ + MAX_MSG)
> +#define IPI_IRQ		(MSI_IRQ + MAX_MSI)
> +
> +#define IRQ_IPI0        IPI_IRQ
> +#define IRQ_TIM0        TMR_IRQ
> +
> +#else
> +#error "Please select which OpenPic implementation is to be emulated"
> +#endif
> +
> +#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
> +    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
> +#define OPENPIC_SWAP
> +#endif
> +
>  #define BF_WIDTH(_bits_) \
>  (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
>  
> @@ -157,6 +205,7 @@ enum IPVP_bits {
>  #define IPVP_VECTOR(_ipvpr_)   ((_ipvpr_) & IPVP_VECTOR_MASK)
>  
>  typedef struct IRQ_dst_t {
> +    uint32_t tfrr;
>      uint32_t pctp; /* CPU current task priority */
>      uint32_t pcsr; /* CPU sensitivity register */
>      IRQ_queue_t raised;
> @@ -200,6 +249,8 @@ typedef struct openpic_t {
>  #endif
>      /* IRQ out is used when in bypass mode (not implemented) */
>      qemu_irq irq_out;
> +    void (*reset) (struct openpic_t *);
> +    void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *);
>  } openpic_t;
>  
>  static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
> @@ -286,7 +337,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
>          return;
>      }
>      DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ);
> -    qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
> +    opp->irq_raise(opp, n_CPU, src);
>  }
>  
>  /* update pic state because registers for n_IRQ have changed value */
> @@ -551,8 +602,8 @@ static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
>      case 0x00: /* FREP */
>          break;
>      case 0x20: /* GLBC */
> -        if (val & 0x80000000)
> -            openpic_reset(opp);
> +        if (val & 0x80000000 && opp->reset)
> +            opp->reset(opp);
>          opp->glbc = val & ~0x80000000;
>  	break;
>      case 0x80: /* VENI */
> @@ -818,7 +869,7 @@ static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
>               IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {
>              DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
>                      idx, n_IRQ);
> -            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
> +            opp->irq_raise(opp, idx, src);
>          }
>  	break;
>      default:
> @@ -1001,6 +1052,11 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
>  #endif
>  }
>  
> +static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
> +{
> +    qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
> +}
> +
>  qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
>                          qemu_irq **irqs, qemu_irq irq_out)
>  {
> @@ -1058,9 +1114,307 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
>      for (i = 0; i < nb_cpus; i++)
>          opp->dst[i].irqs = irqs[i];
>      opp->irq_out = irq_out;
> -    openpic_reset(opp);
> +
> +    opp->irq_raise = openpic_irq_raise;
> +    opp->reset = openpic_reset;
> +
> +    opp->reset(opp);
>      if (pmem_index)
>          *pmem_index = opp->mem_index;
>  
>      return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
>  }
> +
> +static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src)
> +{
> +    int n_ci = IDR_CI0 - n_CPU;
> +    DPRINTF("%s: cpu:%d irq:%d (testbit idr:%x ci:%d)\n", __func__,
> +		    n_CPU, n_IRQ, mpp->src[n_IRQ].ide, n_ci);
> +    if(test_bit(&src->ide, n_ci)) {
> +        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]);
> +    }
> +    else {
> +        qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
> +    }
> +}
> +
> +static void mpic_reset (openpic_t *mpp)
> +{
> +    int i;
> +
> +    mpp->glbc = 0x80000000;
> +    /* Initialise controller registers */
> +    mpp->frep = 0x004f0002;
> +    mpp->veni = VENI;
> +    mpp->pint = 0x00000000;
> +    mpp->spve = 0x0000FFFF;
> +    /* Initialise IRQ sources */
> +    for (i = 0; i < MAX_IRQ; i++) {
> +	mpp->src[i].ipvp = 0x80800000;
> +	mpp->src[i].ide  = 0x00000001;
> +    }
> +    /* Initialise IRQ destinations */
> +    for (i = 0; i < MAX_CPU; i++) {
> +	mpp->dst[i].pctp      = 0x0000000F;
> +        mpp->dst[i].tfrr      = 0x00000000;
> +	memset(&mpp->dst[i].raised, 0, sizeof(IRQ_queue_t));
> +	mpp->dst[i].raised.next = -1;
> +	memset(&mpp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
> +	mpp->dst[i].servicing.next = -1;
> +    }
> +    /* Initialise timers */
> +    for (i = 0; i < MAX_TMR; i++) {
> +	mpp->timers[i].ticc = 0x00000000;
> +	mpp->timers[i].tibc = 0x80000000;
> +    }
> +    /* Go out of RESET state */
> +    mpp->glbc = 0x00000000;
> +}
> +
> +static void mpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +    int idx, cpu;
> +
> +    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
> +    if (addr & 0xF)
> +        return;
> +#if defined MPIC_SWAP
> +    val = bswap32(val);
> +#endif
> +    addr &= 0xFFFF;
> +    cpu = addr >> 12;
> +    idx = (addr >> 6) & 0x3;
> +    switch (addr & 0x30) {
> +    case 0x00: /* gtccr */
> +        break;
> +    case 0x10: /* gtbcr */
> +	if ((mpp->timers[idx].ticc & 0x80000000) != 0 &&
> +	    (val & 0x80000000) = 0 &&
> +            (mpp->timers[idx].tibc & 0x80000000) != 0)
> +	    mpp->timers[idx].ticc &= ~0x80000000;
> +	mpp->timers[idx].tibc = val;
> +	break;
> +    case 0x20: /* GTIVPR */
> +	write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP, val);
> +	break;
> +    case 0x30: /* GTIDR & TFRR */
> +	if ((addr & 0xF0) = 0xF0)
> +            mpp->dst[cpu].tfrr = val;
> +	else
> +	    write_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE, val);
> +	break;
> +    }
> +}
> +
> +static uint32_t mpic_timer_read (void *opaque, uint32_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval;
> +    int idx, cpu;
> +
> +    DPRINTF("%s: addr %08x\n", __func__, addr);
> +    retval = 0xFFFFFFFF;
> +    if (addr & 0xF)
> +        return retval;
> +    addr &= 0xFFFF;
> +    cpu = addr >> 12;
> +    idx = (addr >> 6) & 0x3;
> +    switch (addr & 0x30) {
> +    case 0x00: /* gtccr */
> +	retval = mpp->timers[idx].ticc;
> +        break;
> +    case 0x10: /* gtbcr */
> +	retval = mpp->timers[idx].tibc;
> +	break;
> +    case 0x20: /* TIPV */
> +	retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IPVP);
> +	break;
> +    case 0x30: /* TIDR */
> +        if ((addr &0xF0) = 0XF0)
> +	    retval = mpp->dst[cpu].tfrr;
> +	else
> +	    retval = read_IRQreg(mpp, TMR_IRQ + idx, IRQ_IDE);
> +	break;
> +    }
> +    DPRINTF("%s: => %08x\n", __func__, retval);
> +#if defined MPIC_SWAP
> +    retval = bswap32(retval);
> +#endif
> +
> +    return retval;
> +}
> +
> +static void mpic_src_write (void *opaque, uint32_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +    int idx;
> +
> +    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
> +    if (addr & 0xF)
> +        return;
> +#if defined MPIC_SWAP
> +    val = tswap32(val);
> +#endif
> +    addr = addr & 0xFFF0;
> +    if (addr < 0x180) {
> +	idx = EXT_IRQ;
> +    } else if (addr >= 0x200 && addr < 0xa00) {
> +	idx = INT_IRQ;
> +	addr -= 0x200;
> +    } else if (addr >= 0x1600 && addr < 0x1700) {
> +	idx = MSG_IRQ;
> +	addr -= 0x1600;
> +    } else if (addr >= 0x1C00 && addr < 0x1D00) {
> +	idx = MSI_IRQ;
> +	addr -= 0x1C00;
> +    } else {
> +	return;
> +    }
> +    idx += addr >> 5;
> +    if (addr & 0x10) {
> +        /* EXDE / IFEDE / IEEDE */
> +        write_IRQreg(mpp, idx, IRQ_IDE, val);
> +    } else {
> +        /* EXVP / IFEVP / IEEVP */
> +        write_IRQreg(mpp, idx, IRQ_IPVP, val);
> +    }
> +}
> +
> +static uint32_t mpic_src_read (void *opaque, uint32_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval;
> +    int idx;
> +
> +    DPRINTF("%s: addr %08x\n", __func__, addr);
> +    retval = 0xFFFFFFFF;
> +    if (addr & 0xF)
> +        return retval;
> +    addr = addr & 0xFFF0;
> +    if (addr < 0x180) {
> +	idx = EXT_IRQ;
> +    } else if (addr >= 0x200 && addr < 0xa00) {
> +	idx = INT_IRQ;
> +	addr -= 0x200;
> +    } else if (addr >= 0x1600 && addr < 0x1700) {
> +	idx = MSG_IRQ;
> +	addr -= 0x1600;
> +    } else if (addr >= 0x1C00 && addr < 0x1D00) {
> +	idx = MSI_IRQ;
> +	addr -= 0x1C00;
> +    } else {
> +	return retval;
> +    }
> +    idx += addr >> 5;
> +    if (addr & 0x10) {
> +        /* EXDE / IFEDE / IEEDE */
> +        retval = read_IRQreg(mpp, idx, IRQ_IDE);
> +    } else {
> +        /* EXVP / IFEVP / IEEVP */
> +        retval = read_IRQreg(mpp, idx, IRQ_IPVP);
> +    }
> +    DPRINTF("%s: => %08x\n", __func__, retval);
> +#if defined MPIC_SWAP
> +    retval = tswap32(retval);
> +#endif
> +
> +    return retval;
> +}
> +
> +static void mpic_writel (void *opaque,
> +                            target_phys_addr_t addr, uint32_t val)
> +{
> +    openpic_t *mpp = opaque;
> +
> +    addr &= 0x3FFFF;
> +    DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
> +    if (addr < 0x10F0) {
> +        /* Global registers */
> +	openpic_gbl_write(mpp, addr, val);
> +    } else if (addr < 0x10000) {
> +        /* Timers registers */
> +        mpic_timer_write(mpp, addr, val);
> +    } else if (addr < 0x20000) {
> +        /* Source registers */
> +        mpic_src_write(mpp, addr, val);
> +    } else if (addr < 0x30000){
> +        /* CPU registers */
> +	openpic_cpu_write(mpp, addr, val);
> +    } else {
> +    	DPRINTF("wrong mpic write addr %p\n",addr);
> +    }
> +}
> +
> +static uint32_t mpic_readl (void *opaque,target_phys_addr_t addr)
> +{
> +    openpic_t *mpp = opaque;
> +    uint32_t retval = 0;
> +
> +    addr &= 0x3FFFF;
> +    DPRINTF("%s: offset %08x\n", __func__, (int)addr);
> +    if (addr < 0x10F0) {
> +        /* Global registers */
> +	retval = openpic_gbl_read(mpp, addr);
> +    } else if (addr < 0x10000) {
> +        /* Timers registers */
> +        retval = mpic_timer_read(mpp, addr);
> +    } else if (addr < 0x20000) {
> +        /* Source registers */
> +        retval = mpic_src_read(mpp, addr);
> +    } else if (addr < 0x30000){
> +        /* CPU registers */
> +	retval = openpic_cpu_read(mpp, addr);
> +    } else {
> +    	DPRINTF("wrong mpic read addr %p\n",addr);
> +    }
> +
> +    return retval;
> +}
> +
> +static CPUWriteMemoryFunc *mpic_write[] = {
> +    &openpic_buggy_write,
> +    &openpic_buggy_write,
> +    &mpic_writel,
> +};
> +
> +static CPUReadMemoryFunc *mpic_read[] = {
> +    &openpic_buggy_read,
> +    &openpic_buggy_read,
> +    &mpic_readl,
> +};
> +
> +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out)
> +{
> +    openpic_t *mpp;
> +    int i;
> +
> +    /* XXX: for now, only one CPU is supported */
> +    if (nb_cpus != 1)
> +        return NULL;
> +
> +    mpp = qemu_mallocz(sizeof(openpic_t));
> +
> +    mpp->mem_index = cpu_register_io_memory(0, mpic_read, mpic_write, mpp);
> +    if (mpp->mem_index < 0)
> +	goto free;
> +    cpu_register_physical_memory(base, MPIC_MAP_SIZE, mpp->mem_index);
> +
> +    mpp->nb_cpus = nb_cpus;
> +
> +    for (i = 0; i < nb_cpus; i++)
> +        mpp->dst[i].irqs = irqs[i];
> +    mpp->irq_out = irq_out;
> +
> +    mpp->irq_raise = mpic_irq_raise;
> +    mpp->reset = mpic_reset;
> +
> +    mpp->reset(mpp);
> +
> +    return qemu_allocate_irqs(openpic_set_irq, mpp, MAX_IRQ);
> +
> +free:
> +    qemu_free(mpp);
> +    return NULL;
> +}
> diff --git a/hw/openpic.h b/hw/openpic.h
> new file mode 100644
> index 0000000..2f85e16
> --- /dev/null
> +++ b/hw/openpic.h
> @@ -0,0 +1,19 @@
> +
> +#if !defined(OPENPIC_H)
> +#define OPENPIC_H
> +
> +/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
> +enum {
> +    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
> +    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
> +    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
> +    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
> +    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
> +    OPENPIC_OUTPUT_NB,
> +};
> +
> +qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out);
> +qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
> +                        qemu_irq **irqs, qemu_irq irq_out);
> +#endif /* OPENPIC_H */
> diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
> index cc70fb7..bf987b1 100644
> --- a/hw/ppc_mac.h
> +++ b/hw/ppc_mac.h
> @@ -113,17 +113,5 @@ void adb_mouse_init(ADBBusState *bus);
>  
>  extern ADBBusState adb_bus;
>  
> -/* openpic.c */
> -/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
> -enum {
> -    OPENPIC_OUTPUT_INT = 0, /* IRQ                       */
> -    OPENPIC_OUTPUT_CINT,    /* critical IRQ              */
> -    OPENPIC_OUTPUT_MCK,     /* Machine check event       */
> -    OPENPIC_OUTPUT_DEBUG,   /* Inconditional debug event */
> -    OPENPIC_OUTPUT_RESET,   /* Core reset event          */
> -    OPENPIC_OUTPUT_NB,
> -};
> -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
> -                        qemu_irq **irqs, qemu_irq irq_out);
> -
> +#include "openpic.h"
>  #endif /* !defined(__PPC_MAC_H__) */
>   


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
  2009-01-15 12:34 ` Liu Yu
@ 2009-01-15 21:26   ` Anthony Liguori
  -1 siblings, 0 replies; 52+ messages in thread
From: Anthony Liguori @ 2009-01-15 21:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm-ppc

Liu Yu wrote:
> This patchset enable the support of MPC85xx platform in qemu/kvm.
>
> patch 1,2: bug fix
> patch 3: enable mpic for E500 core.
> patch 4: enable E500 mmu in kvm mode.
> patch 5: add E500 pci controller emulation.
> patch 6: add E500 irq support
> patch 7: add E500 core emulation
> patch 8: extern one function for E500 code use
> patch 9: add MPC85xx boards emulation.
>   

Applied 1, 2, and 4.  I'll wait for some more review on the rest.

Regards,

Anthony Liguori

>
>
>   

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support
@ 2009-01-15 21:26   ` Anthony Liguori
  0 siblings, 0 replies; 52+ messages in thread
From: Anthony Liguori @ 2009-01-15 21:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm-ppc

Liu Yu wrote:
> This patchset enable the support of MPC85xx platform in qemu/kvm.
>
> patch 1,2: bug fix
> patch 3: enable mpic for E500 core.
> patch 4: enable E500 mmu in kvm mode.
> patch 5: add E500 pci controller emulation.
> patch 6: add E500 irq support
> patch 7: add E500 core emulation
> patch 8: extern one function for E500 code use
> patch 9: add MPC85xx boards emulation.
>   

Applied 1, 2, and 4.  I'll wait for some more review on the rest.

Regards,

Anthony Liguori

>
>
>   


^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
  2009-01-15 21:22         ` Anthony Liguori
@ 2009-01-16  5:34           ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  5:34 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: kvm-ppc



> -----Original Message-----
> From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> Sent: Friday, January 16, 2009 5:23 AM
> To: qemu-devel@nongnu.org
> Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> mpic for E500 platform
> 
> Liu Yu wrote:
> > The modify is based on original author's method
> > to switch openpic and mpic by static define,
> > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > (Although the support for intel has broken)
> > So they can't be used at the same time.
> >
> > I guess it's not the correct way to do this.
> > but I am not sure is the USE_MPC85xx and openpic are still needed?
> >   
> 
> Have you tested some of the other (TCG) boards (for instance, 
> with the 
> debian image Aurelien recently posted)?
> 

You mean test powerpc mac99? No.
I only modified few places to the original code. I think it won't be influenced.
But mpic and openpic couldnot work in the same qemu binary with this patch.
If they should both be supported, then I need to modify more.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
@ 2009-01-16  5:34           ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  5:34 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: kvm-ppc



> -----Original Message-----
> From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> Sent: Friday, January 16, 2009 5:23 AM
> To: qemu-devel@nongnu.org
> Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> mpic for E500 platform
> 
> Liu Yu wrote:
> > The modify is based on original author's method
> > to switch openpic and mpic by static define,
> > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > (Although the support for intel has broken)
> > So they can't be used at the same time.
> >
> > I guess it's not the correct way to do this.
> > but I am not sure is the USE_MPC85xx and openpic are still needed?
> >   
> 
> Have you tested some of the other (TCG) boards (for instance, 
> with the 
> debian image Aurelien recently posted)?
> 

You mean test powerpc mac99? No.
I only modified few places to the original code. I think it won't be influenced.
But mpic and openpic couldnot work in the same qemu binary with this patch.
If they should both be supported, then I need to modify more.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
  2009-01-15 20:02             ` Hollis Blanchard
@ 2009-01-16  7:37               ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  7:37 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Friday, January 16, 2009 4:02 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: Re: [PATCH 5/9] powerpc/kvm: Add freescale pci 
> controller's support
> 
> On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> >  Makefile.target  |    2 +
> >  hw/ppce500_pci.c |  369 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 371 insertions(+), 0 deletions(-)
> >  create mode 100644 hw/ppce500_pci.c
> > 
> > diff --git a/Makefile.target b/Makefile.target
> > index 58fe88f..2079fcb 100644
> > --- a/Makefile.target
> > +++ b/Makefile.target
> > @@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
> >  # PowerPC 4xx boards
> >  OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o 
> ppc405_uc.o ppc405_boards.o
> >  OBJS+= ppc440.o ppc440_bamboo.o
> > +# PowerPC E500 boards
> > +OBJS+= ppce500_pci.o
> >  ifdef FDT_LIBS
> >  OBJS+= device_tree.o
> >  LIBS+= $(FDT_LIBS)
> > diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> > new file mode 100644
> > index 0000000..9077591
> > --- /dev/null
> > +++ b/hw/ppce500_pci.c
> > @@ -0,0 +1,369 @@
> > +/*
> > + * QEMU PowerPC E500 embedded processors pci controller emulation
> > + *
> > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All 
> rights reserved.
> > + *
> > + * Author: Yu Liu,     <yu.liu@freescale.com>
> > + *
> > + * This file is derived from hw/ppc4xx_pci.c,
> > + * the copyright for that material belongs to the original owners.
> > + *
> > + * This is free software; you can redistribute it and/or modify
> > + * it under the terms of  the GNU General  Public License 
> as published by
> > + * the Free Software Foundation;  either version 2 of the  
> License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include "hw.h"
> > +#include "ppc.h"
> > +#include "ppce500.h"
> > +typedef target_phys_addr_t pci_addr_t;
> > +#include "pci.h"
> > +#include "pci_host.h"
> > +#include "bswap.h"
> > +#include "qemu-log.h"
> > +
> > +#ifdef DEBUG_PCI
> > +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
> > +#else
> > +#define pci_debug(fmt, arg...)
> > +#endif
> > +
> > +#define PCIE500_CFGADDR       0x0
> > +#define PCIE500_CFGDATA       0x4
> > +#define PCIE500_REG_BASE      0xC00
> > +#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
> > +
> > +#define PPCE500_PCI_CONFIG_ADDR		0x0
> > +#define PPCE500_PCI_CONFIG_DATA		0x4
> > +#define PPCE500_PCI_INTACK		0x8
> > +
> > +#define PPCE500_PCI_OW1			(0xC20 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW2			(0xC40 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW3			(0xC60 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW4			(0xC80 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW3			(0xDA0 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW2			(0xDC0 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW1			(0xDE0 - 
> PCIE500_REG_BASE)
> > +
> > +#define PPCE500_PCI_GASKET_TIMR		(0xE20 - 
> PCIE500_REG_BASE)
> > +
> > +#define PCI_POTAR		0x0
> > +#define PCI_POTEAR		0x4
> > +#define PCI_POWBAR		0x8
> > +#define PCI_POWAR		0x10
> > +
> > +#define PCI_PITAR		0x0
> > +#define PCI_PIWBAR		0x8
> > +#define PCI_PIWBEAR		0xC
> > +#define PCI_PIWAR		0x10
> > +
> > +#define PPCE500_PCI_NR_POBS 5
> > +#define PPCE500_PCI_NR_PIBS 3
> > +
> > +struct  pci_outbound {
> > +    uint32_t potar;
> > +    uint32_t potear;
> > +    uint32_t powbar;
> > +    uint32_t powar;
> > +};
> > +
> > +struct pci_inbound {
> > +    uint32_t pitar;
> > +    uint32_t piwbar;
> > +    uint32_t piwbear;
> > +    uint32_t piwar;
> > +};
> > +
> > +struct PPCE500PCIState {
> > +    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
> > +    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> > +    uint32_t gasket_time;
> 
> Out of curiosity, is "gasket_time" supposed to be an actual timer, or
> just a scratch register? It looks like you've just implemented it as a
> scratch register.

Just a scratch register I think.
I tried today that if I removed it, virtio-pci cannot be found.

> 
> > +    PCIHostState pci_state;
> > +    PCIDevice *pci_dev;
> > +};
> > +
> > +typedef struct PPCE500PCIState PPCE500PCIState;
> > +
> > +static uint32_t pcie500_cfgaddr_readl(void *opaque, 
> target_phys_addr_t addr)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +
> > +    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
> > +		    pci->pci_state.config_reg);
> > +    return pci->pci_state.config_reg;
> > +}
> > +
> > +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
> > +    &pcie500_cfgaddr_readl,
> > +    &pcie500_cfgaddr_readl,
> > +    &pcie500_cfgaddr_readl,
> > +};
> > +
> > +static void pcie500_cfgaddr_writel(void *opaque, 
> target_phys_addr_t addr,
> > +                                  uint32_t value)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +
> > +    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, 
> value, addr);
> > +    controller->pci_state.config_reg = value & ~0x3;
> > +}
> > +
> > +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
> > +    pcie500_cfgaddr_writel,
> 
> Missing & here.
Fixed. Thanks.

> 
> > +    &pcie500_cfgaddr_writel,
> > +    &pcie500_cfgaddr_writel,
> > +};
> > +
> > +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
> > +    &pci_host_data_readb,
> > +    &pci_host_data_readw,
> > +    &pci_host_data_readl,
> > +};
> > +
> > +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
> > +    &pci_host_data_writeb,
> > +    &pci_host_data_writew,
> > +    &pci_host_data_writel,
> > +};
> > +
> > +static uint32_t pci_reg_read4(void *opaque, 
> target_phys_addr_t addr)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +    unsigned long win;
> > +    uint32_t value = 0;
> > +
> > +    win = addr & 0xfe0;
> > +
> > +    switch (win) {
> > +    case PPCE500_PCI_OW1:
> > +    case PPCE500_PCI_OW2:
> > +    case PPCE500_PCI_OW3:
> > +    case PPCE500_PCI_OW4:
> > +	switch (addr & 0xC) {
> > +	case PCI_POTAR: value = pci->pob[(addr >> 5) & 
> 0x7].potar; break;
> > +	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 
> 0x7].potear; break;
> > +	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 
> 0x7].powbar; break;
> > +	case PCI_POWAR: value = pci->pob[(addr >> 5) & 
> 0x7].powar; break;
> > +	default: break;
> > +	}
> > +	break;
> > +
> > +    case PPCE500_PCI_IW3:
> > +    case PPCE500_PCI_IW2:
> > +    case PPCE500_PCI_IW1:
> > +	switch (addr & 0xC) {
> > +	case PCI_PITAR: value = pci->pib[(addr >> 5) & 
> 0x3].pitar; break;
> > +	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwbar; break;
> > +	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwbear; break;
> > +	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwar; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_GASKET_TIMR:
> > +	value = pci->gasket_time;
> > +	break;
> > +
> > +    default:
> > +	break;
> > +    }
> > +
> > +    pci_debug("%s: win:%lx(addr:%Lx) -> 
> value:%x\n",__func__,win,addr,value);
> > +    return value;
> > +}
> > +
> > +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
> > +    &pci_reg_read4,
> > +    &pci_reg_read4,
> > +    &pci_reg_read4,
> > +};
> > +
> > +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
> > +                               uint32_t value)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +    unsigned long win;
> > +
> > +    win = addr & 0xfe0;
> > +
> > +    pci_debug("%s: value:%x -> 
> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
> > +
> > +    switch (win) {
> > +    case PPCE500_PCI_OW1:
> > +    case PPCE500_PCI_OW2:
> > +    case PPCE500_PCI_OW3:
> > +    case PPCE500_PCI_OW4:
> > +	switch (addr & 0xC) {
> > +	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = 
> value; break;
> > +	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = 
> value; break;
> > +	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = 
> value; break;
> > +	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = 
> value; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_IW3:
> > +    case PPCE500_PCI_IW2:
> > +    case PPCE500_PCI_IW1:
> > +	switch (addr & 0xC) {
> > +	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = 
> value; break;
> > +	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = 
> value; break;
> > +	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = 
> value; break;
> > +	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = 
> value; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_GASKET_TIMR:
> > +	pci->gasket_time = value;
> > +	break;
> > +
> > +    default:
> > +	break;
> > +    };
> > +}
> > +
> > +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
> > +    &pci_reg_write4,
> > +    &pci_reg_write4,
> > +    &pci_reg_write4,
> > +};
> > +
> > +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> > +{
> > +    int devno = pci_dev->devfn >> 3, ret = 0;
> > +
> > +    switch (devno) {
> > +	/* Two PCI slot */
> > +	case 0x11:
> > +	case 0x12:
> > +	    ret = (irq_num + devno - 0x10) % 4;
> > +	    break;
> > +	default:
> > +	    printf("Error:%s:unknow dev number\n", __func__);
> > +    }
> > +
> > +    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
> > +           pci_dev->devfn, irq_num, ret, devno);
> > +
> > +    return ret;
> > +}
> > +
> > +static void mpc85xx_pci_set_irq(qemu_irq *pic, int 
> irq_num, int level)
> > +{
> > +    pci_debug("%s: PCI irq %d, level:%d\n", __func__, 
> irq_num, level);
> > +
> > +    qemu_set_irq(pic[irq_num], level);
> > +}
> > +
> > +static void ppce500_pci_save(QEMUFile *f, void *opaque)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +    int i;
> > +
> > +    pci_device_save(controller->pci_dev, f);
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > +        qemu_put_be32s(f, &controller->pob[i].potar);
> > +        qemu_put_be32s(f, &controller->pob[i].potear);
> > +        qemu_put_be32s(f, &controller->pob[i].powbar);
> > +        qemu_put_be32s(f, &controller->pob[i].powar);
> > +    }
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > +        qemu_put_be32s(f, &controller->pib[i].pitar);
> > +        qemu_put_be32s(f, &controller->pib[i].piwbar);
> > +        qemu_put_be32s(f, &controller->pib[i].piwbear);
> > +        qemu_put_be32s(f, &controller->pib[i].piwar);
> > +    }
> > +    qemu_put_be32s(f, &controller->gasket_time);
> > +}
> > +
> > +static int ppce500_pci_load(QEMUFile *f, void *opaque, int 
> version_id)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +    int i;
> > +
> > +    if (version_id != 1)
> > +        return -EINVAL;
> > +
> > +    pci_device_load(controller->pci_dev, f);
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > +        qemu_get_be32s(f, &controller->pob[i].potar);
> > +        qemu_get_be32s(f, &controller->pob[i].potear);
> > +        qemu_get_be32s(f, &controller->pob[i].powbar);
> > +        qemu_get_be32s(f, &controller->pob[i].powar);
> > +    }
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > +        qemu_get_be32s(f, &controller->pib[i].pitar);
> > +        qemu_get_be32s(f, &controller->pib[i].piwbar);
> > +        qemu_get_be32s(f, &controller->pib[i].piwbear);
> > +        qemu_get_be32s(f, &controller->pib[i].piwar);
> > +    }
> > +    qemu_get_be32s(f, &controller->gasket_time);
> > +
> > +    return 0;
> > +}
> 
> Should have a newline here.
Fixed. Thanks.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support
@ 2009-01-16  7:37               ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  7:37 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Friday, January 16, 2009 4:02 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: Re: [PATCH 5/9] powerpc/kvm: Add freescale pci 
> controller's support
> 
> On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> >  Makefile.target  |    2 +
> >  hw/ppce500_pci.c |  369 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 371 insertions(+), 0 deletions(-)
> >  create mode 100644 hw/ppce500_pci.c
> > 
> > diff --git a/Makefile.target b/Makefile.target
> > index 58fe88f..2079fcb 100644
> > --- a/Makefile.target
> > +++ b/Makefile.target
> > @@ -649,6 +649,8 @@ OBJS+= unin_pci.o ppc_chrp.o
> >  # PowerPC 4xx boards
> >  OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o 
> ppc405_uc.o ppc405_boards.o
> >  OBJS+= ppc440.o ppc440_bamboo.o
> > +# PowerPC E500 boards
> > +OBJS+= ppce500_pci.o
> >  ifdef FDT_LIBS
> >  OBJS+= device_tree.o
> >  LIBS+= $(FDT_LIBS)
> > diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> > new file mode 100644
> > index 0000000..9077591
> > --- /dev/null
> > +++ b/hw/ppce500_pci.c
> > @@ -0,0 +1,369 @@
> > +/*
> > + * QEMU PowerPC E500 embedded processors pci controller emulation
> > + *
> > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All 
> rights reserved.
> > + *
> > + * Author: Yu Liu,     <yu.liu@freescale.com>
> > + *
> > + * This file is derived from hw/ppc4xx_pci.c,
> > + * the copyright for that material belongs to the original owners.
> > + *
> > + * This is free software; you can redistribute it and/or modify
> > + * it under the terms of  the GNU General  Public License 
> as published by
> > + * the Free Software Foundation;  either version 2 of the  
> License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include "hw.h"
> > +#include "ppc.h"
> > +#include "ppce500.h"
> > +typedef target_phys_addr_t pci_addr_t;
> > +#include "pci.h"
> > +#include "pci_host.h"
> > +#include "bswap.h"
> > +#include "qemu-log.h"
> > +
> > +#ifdef DEBUG_PCI
> > +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
> > +#else
> > +#define pci_debug(fmt, arg...)
> > +#endif
> > +
> > +#define PCIE500_CFGADDR       0x0
> > +#define PCIE500_CFGDATA       0x4
> > +#define PCIE500_REG_BASE      0xC00
> > +#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
> > +
> > +#define PPCE500_PCI_CONFIG_ADDR		0x0
> > +#define PPCE500_PCI_CONFIG_DATA		0x4
> > +#define PPCE500_PCI_INTACK		0x8
> > +
> > +#define PPCE500_PCI_OW1			(0xC20 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW2			(0xC40 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW3			(0xC60 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_OW4			(0xC80 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW3			(0xDA0 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW2			(0xDC0 - 
> PCIE500_REG_BASE)
> > +#define PPCE500_PCI_IW1			(0xDE0 - 
> PCIE500_REG_BASE)
> > +
> > +#define PPCE500_PCI_GASKET_TIMR		(0xE20 - 
> PCIE500_REG_BASE)
> > +
> > +#define PCI_POTAR		0x0
> > +#define PCI_POTEAR		0x4
> > +#define PCI_POWBAR		0x8
> > +#define PCI_POWAR		0x10
> > +
> > +#define PCI_PITAR		0x0
> > +#define PCI_PIWBAR		0x8
> > +#define PCI_PIWBEAR		0xC
> > +#define PCI_PIWAR		0x10
> > +
> > +#define PPCE500_PCI_NR_POBS 5
> > +#define PPCE500_PCI_NR_PIBS 3
> > +
> > +struct  pci_outbound {
> > +    uint32_t potar;
> > +    uint32_t potear;
> > +    uint32_t powbar;
> > +    uint32_t powar;
> > +};
> > +
> > +struct pci_inbound {
> > +    uint32_t pitar;
> > +    uint32_t piwbar;
> > +    uint32_t piwbear;
> > +    uint32_t piwar;
> > +};
> > +
> > +struct PPCE500PCIState {
> > +    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
> > +    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> > +    uint32_t gasket_time;
> 
> Out of curiosity, is "gasket_time" supposed to be an actual timer, or
> just a scratch register? It looks like you've just implemented it as a
> scratch register.

Just a scratch register I think.
I tried today that if I removed it, virtio-pci cannot be found.

> 
> > +    PCIHostState pci_state;
> > +    PCIDevice *pci_dev;
> > +};
> > +
> > +typedef struct PPCE500PCIState PPCE500PCIState;
> > +
> > +static uint32_t pcie500_cfgaddr_readl(void *opaque, 
> target_phys_addr_t addr)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +
> > +    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
> > +		    pci->pci_state.config_reg);
> > +    return pci->pci_state.config_reg;
> > +}
> > +
> > +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
> > +    &pcie500_cfgaddr_readl,
> > +    &pcie500_cfgaddr_readl,
> > +    &pcie500_cfgaddr_readl,
> > +};
> > +
> > +static void pcie500_cfgaddr_writel(void *opaque, 
> target_phys_addr_t addr,
> > +                                  uint32_t value)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +
> > +    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, 
> value, addr);
> > +    controller->pci_state.config_reg = value & ~0x3;
> > +}
> > +
> > +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
> > +    pcie500_cfgaddr_writel,
> 
> Missing & here.
Fixed. Thanks.

> 
> > +    &pcie500_cfgaddr_writel,
> > +    &pcie500_cfgaddr_writel,
> > +};
> > +
> > +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
> > +    &pci_host_data_readb,
> > +    &pci_host_data_readw,
> > +    &pci_host_data_readl,
> > +};
> > +
> > +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
> > +    &pci_host_data_writeb,
> > +    &pci_host_data_writew,
> > +    &pci_host_data_writel,
> > +};
> > +
> > +static uint32_t pci_reg_read4(void *opaque, 
> target_phys_addr_t addr)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +    unsigned long win;
> > +    uint32_t value = 0;
> > +
> > +    win = addr & 0xfe0;
> > +
> > +    switch (win) {
> > +    case PPCE500_PCI_OW1:
> > +    case PPCE500_PCI_OW2:
> > +    case PPCE500_PCI_OW3:
> > +    case PPCE500_PCI_OW4:
> > +	switch (addr & 0xC) {
> > +	case PCI_POTAR: value = pci->pob[(addr >> 5) & 
> 0x7].potar; break;
> > +	case PCI_POTEAR: value = pci->pob[(addr >> 5) & 
> 0x7].potear; break;
> > +	case PCI_POWBAR: value = pci->pob[(addr >> 5) & 
> 0x7].powbar; break;
> > +	case PCI_POWAR: value = pci->pob[(addr >> 5) & 
> 0x7].powar; break;
> > +	default: break;
> > +	}
> > +	break;
> > +
> > +    case PPCE500_PCI_IW3:
> > +    case PPCE500_PCI_IW2:
> > +    case PPCE500_PCI_IW1:
> > +	switch (addr & 0xC) {
> > +	case PCI_PITAR: value = pci->pib[(addr >> 5) & 
> 0x3].pitar; break;
> > +	case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwbar; break;
> > +	case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwbear; break;
> > +	case PCI_PIWAR: value = pci->pib[(addr >> 5) & 
> 0x3].piwar; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_GASKET_TIMR:
> > +	value = pci->gasket_time;
> > +	break;
> > +
> > +    default:
> > +	break;
> > +    }
> > +
> > +    pci_debug("%s: win:%lx(addr:%Lx) -> 
> value:%x\n",__func__,win,addr,value);
> > +    return value;
> > +}
> > +
> > +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
> > +    &pci_reg_read4,
> > +    &pci_reg_read4,
> > +    &pci_reg_read4,
> > +};
> > +
> > +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
> > +                               uint32_t value)
> > +{
> > +    PPCE500PCIState *pci = opaque;
> > +    unsigned long win;
> > +
> > +    win = addr & 0xfe0;
> > +
> > +    pci_debug("%s: value:%x -> 
> win:%lx(addr:%Lx)\n",__func__,value,win,addr);
> > +
> > +    switch (win) {
> > +    case PPCE500_PCI_OW1:
> > +    case PPCE500_PCI_OW2:
> > +    case PPCE500_PCI_OW3:
> > +    case PPCE500_PCI_OW4:
> > +	switch (addr & 0xC) {
> > +	case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = 
> value; break;
> > +	case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = 
> value; break;
> > +	case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = 
> value; break;
> > +	case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = 
> value; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_IW3:
> > +    case PPCE500_PCI_IW2:
> > +    case PPCE500_PCI_IW1:
> > +	switch (addr & 0xC) {
> > +	case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = 
> value; break;
> > +	case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = 
> value; break;
> > +	case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = 
> value; break;
> > +	case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = 
> value; break;
> > +	default: break;
> > +	};
> > +	break;
> > +
> > +    case PPCE500_PCI_GASKET_TIMR:
> > +	pci->gasket_time = value;
> > +	break;
> > +
> > +    default:
> > +	break;
> > +    };
> > +}
> > +
> > +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
> > +    &pci_reg_write4,
> > +    &pci_reg_write4,
> > +    &pci_reg_write4,
> > +};
> > +
> > +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> > +{
> > +    int devno = pci_dev->devfn >> 3, ret = 0;
> > +
> > +    switch (devno) {
> > +	/* Two PCI slot */
> > +	case 0x11:
> > +	case 0x12:
> > +	    ret = (irq_num + devno - 0x10) % 4;
> > +	    break;
> > +	default:
> > +	    printf("Error:%s:unknow dev number\n", __func__);
> > +    }
> > +
> > +    pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,
> > +           pci_dev->devfn, irq_num, ret, devno);
> > +
> > +    return ret;
> > +}
> > +
> > +static void mpc85xx_pci_set_irq(qemu_irq *pic, int 
> irq_num, int level)
> > +{
> > +    pci_debug("%s: PCI irq %d, level:%d\n", __func__, 
> irq_num, level);
> > +
> > +    qemu_set_irq(pic[irq_num], level);
> > +}
> > +
> > +static void ppce500_pci_save(QEMUFile *f, void *opaque)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +    int i;
> > +
> > +    pci_device_save(controller->pci_dev, f);
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > +        qemu_put_be32s(f, &controller->pob[i].potar);
> > +        qemu_put_be32s(f, &controller->pob[i].potear);
> > +        qemu_put_be32s(f, &controller->pob[i].powbar);
> > +        qemu_put_be32s(f, &controller->pob[i].powar);
> > +    }
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > +        qemu_put_be32s(f, &controller->pib[i].pitar);
> > +        qemu_put_be32s(f, &controller->pib[i].piwbar);
> > +        qemu_put_be32s(f, &controller->pib[i].piwbear);
> > +        qemu_put_be32s(f, &controller->pib[i].piwar);
> > +    }
> > +    qemu_put_be32s(f, &controller->gasket_time);
> > +}
> > +
> > +static int ppce500_pci_load(QEMUFile *f, void *opaque, int 
> version_id)
> > +{
> > +    PPCE500PCIState *controller = opaque;
> > +    int i;
> > +
> > +    if (version_id != 1)
> > +        return -EINVAL;
> > +
> > +    pci_device_load(controller->pci_dev, f);
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > +        qemu_get_be32s(f, &controller->pob[i].potar);
> > +        qemu_get_be32s(f, &controller->pob[i].potear);
> > +        qemu_get_be32s(f, &controller->pob[i].powbar);
> > +        qemu_get_be32s(f, &controller->pob[i].powar);
> > +    }
> > +
> > +    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > +        qemu_get_be32s(f, &controller->pib[i].pitar);
> > +        qemu_get_be32s(f, &controller->pib[i].piwbar);
> > +        qemu_get_be32s(f, &controller->pib[i].piwbear);
> > +        qemu_get_be32s(f, &controller->pib[i].piwar);
> > +    }
> > +    qemu_get_be32s(f, &controller->gasket_time);
> > +
> > +    return 0;
> > +}
> 
> Should have a newline here.
Fixed. Thanks.


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-15 19:53                 ` Hollis Blanchard
@ 2009-01-16  7:51                   ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  7:51 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Friday, January 16, 2009 3:53 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> >  Makefile.target |    1 +
> >  hw/ppce500.c    |   49 
> +++++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 94 insertions(+), 0 deletions(-)
> >  create mode 100644 hw/ppce500.c
> >  create mode 100644 hw/ppce500.h
> > 
> > diff --git a/Makefile.target b/Makefile.target
> > index 2079fcb..223d294 100644
> > --- a/Makefile.target
> > +++ b/Makefile.target
> > @@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o 
> ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
> >  OBJS+= ppc440.o ppc440_bamboo.o
> >  # PowerPC E500 boards
> >  OBJS+= ppce500_pci.o
> > +OBJS+= ppce500.o
> >  ifdef FDT_LIBS
> >  OBJS+= device_tree.o
> >  LIBS+= $(FDT_LIBS)
> > diff --git a/hw/ppce500.c b/hw/ppce500.c
> > new file mode 100644
> > index 0000000..856cce2
> > --- /dev/null
> > +++ b/hw/ppce500.c
> > @@ -0,0 +1,49 @@
> > +/*
> > + * Qemu PowerPC E500 core emualtion
> 
> "emulation"
Fixed. Thanks.

> 
> > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All 
> rights reserved.
> > + *
> > + * Author: Yu Liu,     <yu.liu@freescale.com>
> > + *
> > + * This file is derived from hw/ppc440.c
> > + * the copyright for that material belongs to the original owners.
> > + *
> > + * This is free software; you can redistribute it and/or modify
> > + * it under the terms of  the GNU General  Public License 
> as published by
> > + * the Free Software Foundation;  either version 2 of the  
> License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include "hw.h"
> > +#include "pc.h"
> > +#include "hw/isa.h"
> > +#include "ppce500.h"
> > +#include "sysemu.h"
> > +
> > +#define bytes_to_mb(a) (a>>20)
> 
> Doesn't look like this is used.
Removed. Thanks.

> 
> > +CPUState *ppce500_init(ram_addr_t *ram_size)
> > +{
> > +    int i;
> > +    ram_addr_t tmp_ram_size;
> > +    CPUState *env;
> > +    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 
> 64<<20}; /* in bytes */
> > +
> > +    /* Setup Memory */
> > +    tmp_ram_size = *ram_size;
> > +
> > +    for (i=0; 
> i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
> > +	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
> > +	    tmp_ram_size -= ram_stick_sizes[i];
> > +
> > +    if (tmp_ram_size)
> > +	*ram_size -= tmp_ram_size;
> 
> Since you said you don't actually have a memory controller you're
> emulating, I think you should completely remove all this 
> ram_size stuff.
> Once you do that, this whole function becomes just cpu_ppc_init(), so
> you can just call that instead.

I still want to fixup guest memory size at certain alignment boundary,
so that KVM can handle the mmu easily.
Anyway, seems I should put them all into hw/ppce500_mpc85xx.c.

> 
> > +    env = cpu_ppc_init("e500v2_v30");
> > +    if (!env) {
> > +	fprintf(stderr, "Unable to initilize CPU!\n");
> 
> "initialize"

Fixed. Thanks.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-16  7:51                   ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  7:51 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Friday, January 16, 2009 3:53 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > ---
> >  Makefile.target |    1 +
> >  hw/ppce500.c    |   49 
> +++++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/ppce500.h    |   44 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 94 insertions(+), 0 deletions(-)
> >  create mode 100644 hw/ppce500.c
> >  create mode 100644 hw/ppce500.h
> > 
> > diff --git a/Makefile.target b/Makefile.target
> > index 2079fcb..223d294 100644
> > --- a/Makefile.target
> > +++ b/Makefile.target
> > @@ -651,6 +651,7 @@ OBJS+= pflash_cfi02.o ppc4xx_devs.o 
> ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
> >  OBJS+= ppc440.o ppc440_bamboo.o
> >  # PowerPC E500 boards
> >  OBJS+= ppce500_pci.o
> > +OBJS+= ppce500.o
> >  ifdef FDT_LIBS
> >  OBJS+= device_tree.o
> >  LIBS+= $(FDT_LIBS)
> > diff --git a/hw/ppce500.c b/hw/ppce500.c
> > new file mode 100644
> > index 0000000..856cce2
> > --- /dev/null
> > +++ b/hw/ppce500.c
> > @@ -0,0 +1,49 @@
> > +/*
> > + * Qemu PowerPC E500 core emualtion
> 
> "emulation"
Fixed. Thanks.

> 
> > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All 
> rights reserved.
> > + *
> > + * Author: Yu Liu,     <yu.liu@freescale.com>
> > + *
> > + * This file is derived from hw/ppc440.c
> > + * the copyright for that material belongs to the original owners.
> > + *
> > + * This is free software; you can redistribute it and/or modify
> > + * it under the terms of  the GNU General  Public License 
> as published by
> > + * the Free Software Foundation;  either version 2 of the  
> License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include "hw.h"
> > +#include "pc.h"
> > +#include "hw/isa.h"
> > +#include "ppce500.h"
> > +#include "sysemu.h"
> > +
> > +#define bytes_to_mb(a) (a>>20)
> 
> Doesn't look like this is used.
Removed. Thanks.

> 
> > +CPUState *ppce500_init(ram_addr_t *ram_size)
> > +{
> > +    int i;
> > +    ram_addr_t tmp_ram_size;
> > +    CPUState *env;
> > +    int ram_stick_sizes[] = {512<<20, 256<<20, 128<<20, 
> 64<<20}; /* in bytes */
> > +
> > +    /* Setup Memory */
> > +    tmp_ram_size = *ram_size;
> > +
> > +    for (i=0; 
> i<(sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); i++)
> > +	while ((tmp_ram_size/ram_stick_sizes[i]) > 0)
> > +	    tmp_ram_size -= ram_stick_sizes[i];
> > +
> > +    if (tmp_ram_size)
> > +	*ram_size -= tmp_ram_size;
> 
> Since you said you don't actually have a memory controller you're
> emulating, I think you should completely remove all this 
> ram_size stuff.
> Once you do that, this whole function becomes just cpu_ppc_init(), so
> you can just call that instead.

I still want to fixup guest memory size at certain alignment boundary,
so that KVM can handle the mmu easily.
Anyway, seems I should put them all into hw/ppce500_mpc85xx.c.

> 
> > +    env = cpu_ppc_init("e500v2_v30");
> > +    if (!env) {
> > +	fprintf(stderr, "Unable to initilize CPU!\n");
> 
> "initialize"

Fixed. Thanks.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
       [not found]                 ` <1232022857-2315-10-git-send-email-yu.liu@freescale.com>
@ 2009-01-16  8:22                     ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  8:22 UTC (permalink / raw)
  To: Liu Yu-B13201, qemu-devel, Hollis Blanchard; +Cc: kvm-ppc


> -----Original Message-----
> From: Liu Yu-B13201 
> Sent: Thursday, January 15, 2009 8:34 PM
> To: qemu-devel@nongnu.org
> Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> 
> MPC85xx adopts E500 core.
> This patch hopes to support all MPC85xx boards.
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> --- /dev/null
> +++ b/hw/ppce500_mpc85xx.c
> +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> +    		const char *boot_device, DisplayState *ds,
> +    		const char *kernel_filename,
> +    		const char *kernel_cmdline,
> +    		const char *initrd_filename,
> +    		const char *cpu_model)
> +{
> +    PCIBus *pci_bus;
> +    CPUState *env;
> +    uint64_t elf_entry;
> +    uint64_t elf_lowaddr;
> +    target_ulong entry=0;
> +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> +    target_long kernel_size=0;
> +    target_ulong dt_base=DTB_LOAD_BASE;
> +    target_ulong initrd_base=INITRD_LOAD_BASE;
> +    target_long initrd_size=0;
> +    void *fdt;
> +    int i=0;
> +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> +    qemu_irq *irqs, *mpic, *pci_irqs;
> +    SerialState * serial[2];
> +
> +    /* Setup CPU */
> +    env = ppce500_init(&ram_size);
> +
> +    /* MPIC */
> +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> *)env->irq_inputs)[PPCE500_INPUT_INT];
> +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> *)env->irq_inputs)[PPCE500_INPUT_CINT];
> +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> +
> +    /* Serial */
> +    if (serial_hds[0])
> +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> +			0, mpic[12+26], 399193,
> +			serial_hds[0], 1);
> +
> +    if (serial_hds[1])
> +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> +			0, mpic[12+26], 399193,
> +			serial_hds[0], 1);
> +
> +    /* PCI */
> +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> +    if (!pci_bus)
> +	printf("couldn't create PCI controller!\n");
> +
> +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> +
> +    /* Register mem */
> +    cpu_register_physical_memory(0, ram_size, 0);

Hollis, I didn't see the memeory register like this in 440 code.
Is that a bug?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
@ 2009-01-16  8:22                     ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-16  8:22 UTC (permalink / raw)
  To: Liu Yu-B13201, qemu-devel, Hollis Blanchard; +Cc: kvm-ppc


> -----Original Message-----
> From: Liu Yu-B13201 
> Sent: Thursday, January 15, 2009 8:34 PM
> To: qemu-devel@nongnu.org
> Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> 
> MPC85xx adopts E500 core.
> This patch hopes to support all MPC85xx boards.
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> --- /dev/null
> +++ b/hw/ppce500_mpc85xx.c
> +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> +    		const char *boot_device, DisplayState *ds,
> +    		const char *kernel_filename,
> +    		const char *kernel_cmdline,
> +    		const char *initrd_filename,
> +    		const char *cpu_model)
> +{
> +    PCIBus *pci_bus;
> +    CPUState *env;
> +    uint64_t elf_entry;
> +    uint64_t elf_lowaddr;
> +    target_ulong entry=0;
> +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> +    target_long kernel_size=0;
> +    target_ulong dt_base=DTB_LOAD_BASE;
> +    target_ulong initrd_base=INITRD_LOAD_BASE;
> +    target_long initrd_size=0;
> +    void *fdt;
> +    int i=0;
> +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> +    qemu_irq *irqs, *mpic, *pci_irqs;
> +    SerialState * serial[2];
> +
> +    /* Setup CPU */
> +    env = ppce500_init(&ram_size);
> +
> +    /* MPIC */
> +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> *)env->irq_inputs)[PPCE500_INPUT_INT];
> +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> *)env->irq_inputs)[PPCE500_INPUT_CINT];
> +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> +
> +    /* Serial */
> +    if (serial_hds[0])
> +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> +			0, mpic[12+26], 399193,
> +			serial_hds[0], 1);
> +
> +    if (serial_hds[1])
> +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> +			0, mpic[12+26], 399193,
> +			serial_hds[0], 1);
> +
> +    /* PCI */
> +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> +    if (!pci_bus)
> +	printf("couldn't create PCI controller!\n");
> +
> +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> +
> +    /* Register mem */
> +    cpu_register_physical_memory(0, ram_size, 0);

Hollis, I didn't see the memeory register like this in 440 code.
Is that a bug?


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-16  7:51                   ` Liu Yu
@ 2009-01-16 18:02                     ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:02 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> 
> I still want to fixup guest memory size at certain alignment boundary,
> so that KVM can handle the mmu easily.

How about "ram_size &= ~(256<<20)" then?

The code that you copied is more complicated because it's trying to fill
in SDRAM banks which can only support a small range of fixed sizes.
Since you don't have that problem, I think you should simplify.

> Anyway, seems I should put them all into hw/ppce500_mpc85xx.c.

Yup.

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-16 18:02                     ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:02 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> 
> I still want to fixup guest memory size at certain alignment boundary,
> so that KVM can handle the mmu easily.

How about "ram_size &= ~(256<<20)" then?

The code that you copied is more complicated because it's trying to fill
in SDRAM banks which can only support a small range of fixed sizes.
Since you don't have that problem, I think you should simplify.

> Anyway, seems I should put them all into hw/ppce500_mpc85xx.c.

Yup.

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
  2009-01-16  8:22                     ` Liu Yu
@ 2009-01-16 18:09                       ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:09 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

Hmm, I have no idea why I didn't see this patch. Maybe it got caught in
a spam filter.

On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > -----Original Message-----
> > From: Liu Yu-B13201 
> > Sent: Thursday, January 15, 2009 8:34 PM
> > To: qemu-devel@nongnu.org
> > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > 
> > MPC85xx adopts E500 core.
> > This patch hopes to support all MPC85xx boards.
> > 
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > --- /dev/null
> > +++ b/hw/ppce500_mpc85xx.c
> > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > +    		const char *boot_device, DisplayState *ds,
> > +    		const char *kernel_filename,
> > +    		const char *kernel_cmdline,
> > +    		const char *initrd_filename,
> > +    		const char *cpu_model)
> > +{
> > +    PCIBus *pci_bus;
> > +    CPUState *env;
> > +    uint64_t elf_entry;
> > +    uint64_t elf_lowaddr;
> > +    target_ulong entry=0;
> > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > +    target_long kernel_size=0;
> > +    target_ulong dt_base=DTB_LOAD_BASE;
> > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > +    target_long initrd_size=0;
> > +    void *fdt;
> > +    int i=0;
> > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > +    SerialState * serial[2];
> > +
> > +    /* Setup CPU */
> > +    env = ppce500_init(&ram_size);
> > +
> > +    /* MPIC */
> > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > +
> > +    /* Serial */
> > +    if (serial_hds[0])
> > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > +			0, mpic[12+26], 399193,
> > +			serial_hds[0], 1);
> > +
> > +    if (serial_hds[1])
> > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > +			0, mpic[12+26], 399193,
> > +			serial_hds[0], 1);
> > +
> > +    /* PCI */
> > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > +    if (!pci_bus)
> > +	printf("couldn't create PCI controller!\n");
> > +
> > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > +
> > +    /* Register mem */
> > +    cpu_register_physical_memory(0, ram_size, 0);
> 
> Hollis, I didn't see the memeory register like this in 440 code.
> Is that a bug?

RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
like you're actually allocating twice the amount of memory you should
be.

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
@ 2009-01-16 18:09                       ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:09 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

Hmm, I have no idea why I didn't see this patch. Maybe it got caught in
a spam filter.

On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > -----Original Message-----
> > From: Liu Yu-B13201 
> > Sent: Thursday, January 15, 2009 8:34 PM
> > To: qemu-devel@nongnu.org
> > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > 
> > MPC85xx adopts E500 core.
> > This patch hopes to support all MPC85xx boards.
> > 
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > --- /dev/null
> > +++ b/hw/ppce500_mpc85xx.c
> > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > +    		const char *boot_device, DisplayState *ds,
> > +    		const char *kernel_filename,
> > +    		const char *kernel_cmdline,
> > +    		const char *initrd_filename,
> > +    		const char *cpu_model)
> > +{
> > +    PCIBus *pci_bus;
> > +    CPUState *env;
> > +    uint64_t elf_entry;
> > +    uint64_t elf_lowaddr;
> > +    target_ulong entry=0;
> > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > +    target_long kernel_size=0;
> > +    target_ulong dt_base=DTB_LOAD_BASE;
> > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > +    target_long initrd_size=0;
> > +    void *fdt;
> > +    int i=0;
> > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > +    SerialState * serial[2];
> > +
> > +    /* Setup CPU */
> > +    env = ppce500_init(&ram_size);
> > +
> > +    /* MPIC */
> > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > +
> > +    /* Serial */
> > +    if (serial_hds[0])
> > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > +			0, mpic[12+26], 399193,
> > +			serial_hds[0], 1);
> > +
> > +    if (serial_hds[1])
> > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > +			0, mpic[12+26], 399193,
> > +			serial_hds[0], 1);
> > +
> > +    /* PCI */
> > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > +    if (!pci_bus)
> > +	printf("couldn't create PCI controller!\n");
> > +
> > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > +
> > +    /* Register mem */
> > +    cpu_register_physical_memory(0, ram_size, 0);
> 
> Hollis, I didn't see the memeory register like this in 440 code.
> Is that a bug?

RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
like you're actually allocating twice the amount of memory you should
be.

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
  2009-01-16  5:34           ` Liu Yu
@ 2009-01-16 18:17             ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:17 UTC (permalink / raw)
  To: Liu Yu; +Cc: kvm-ppc, qemu-devel

On Fri, 2009-01-16 at 13:34 +0800, Liu Yu wrote:
> 
> > -----Original Message-----
> > From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> > Sent: Friday, January 16, 2009 5:23 AM
> > To: qemu-devel@nongnu.org
> > Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> > Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> > mpic for E500 platform
> > 
> > Liu Yu wrote:
> > > The modify is based on original author's method
> > > to switch openpic and mpic by static define,
> > > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > > (Although the support for intel has broken)
> > > So they can't be used at the same time.
> > >
> > > I guess it's not the correct way to do this.
> > > but I am not sure is the USE_MPC85xx and openpic are still needed?
> > >   
> > 
> > Have you tested some of the other (TCG) boards (for instance, 
> > with the 
> > debian image Aurelien recently posted)?
> > 
> 
> You mean test powerpc mac99? No.

It doesn't sound like mac99 works right now anyways, so that may not be
possible to test.

> I only modified few places to the original code. I think it won't be influenced.
> But mpic and openpic couldnot work in the same qemu binary with this patch.
> If they should both be supported, then I need to modify more.

Due to the (artificial) "ppc" vs "ppcemb" split, I'm not sure this is a
requirement.

The only issue I can see is if there are "ppc" targets (e.g. 970) that
use the same[1] MPIC as found on e500, and that is different from and
not supported by the current OpenPIC emulation.

[1] By "same" I mean "substantially similar". As I understand it,
OpenPIC and MPIC are very similar designs, but there are different
bugs/quirks to different implementations. So even if e500's MPIC isn't
*exactly* the same as 970 chipsets' MPIC, if they're close enough that
the code could be shared, it should be.

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500
@ 2009-01-16 18:17             ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-16 18:17 UTC (permalink / raw)
  To: Liu Yu; +Cc: kvm-ppc, qemu-devel

On Fri, 2009-01-16 at 13:34 +0800, Liu Yu wrote:
> 
> > -----Original Message-----
> > From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> > Sent: Friday, January 16, 2009 5:23 AM
> > To: qemu-devel@nongnu.org
> > Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> > Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> > mpic for E500 platform
> > 
> > Liu Yu wrote:
> > > The modify is based on original author's method
> > > to switch openpic and mpic by static define,
> > > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > > (Although the support for intel has broken)
> > > So they can't be used at the same time.
> > >
> > > I guess it's not the correct way to do this.
> > > but I am not sure is the USE_MPC85xx and openpic are still needed?
> > >   
> > 
> > Have you tested some of the other (TCG) boards (for instance, 
> > with the 
> > debian image Aurelien recently posted)?
> > 
> 
> You mean test powerpc mac99? No.

It doesn't sound like mac99 works right now anyways, so that may not be
possible to test.

> I only modified few places to the original code. I think it won't be influenced.
> But mpic and openpic couldnot work in the same qemu binary with this patch.
> If they should both be supported, then I need to modify more.

Due to the (artificial) "ppc" vs "ppcemb" split, I'm not sure this is a
requirement.

The only issue I can see is if there are "ppc" targets (e.g. 970) that
use the same[1] MPIC as found on e500, and that is different from and
not supported by the current OpenPIC emulation.

[1] By "same" I mean "substantially similar". As I understand it,
OpenPIC and MPIC are very similar designs, but there are different
bugs/quirks to different implementations. So even if e500's MPIC isn't
*exactly* the same as 970 chipsets' MPIC, if they're close enough that
the code could be shared, it should be.

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform
  2009-01-16 18:17             ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 Hollis Blanchard
@ 2009-01-16 21:20               ` Aurelien Jarno
  -1 siblings, 0 replies; 52+ messages in thread
From: Aurelien Jarno @ 2009-01-16 21:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

On Fri, Jan 16, 2009 at 12:17:40PM -0600, Hollis Blanchard wrote:
> On Fri, 2009-01-16 at 13:34 +0800, Liu Yu wrote:
> > 
> > > -----Original Message-----
> > > From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> > > Sent: Friday, January 16, 2009 5:23 AM
> > > To: qemu-devel@nongnu.org
> > > Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> > > Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> > > mpic for E500 platform
> > > 
> > > Liu Yu wrote:
> > > > The modify is based on original author's method
> > > > to switch openpic and mpic by static define,
> > > > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > > > (Although the support for intel has broken)
> > > > So they can't be used at the same time.
> > > >
> > > > I guess it's not the correct way to do this.
> > > > but I am not sure is the USE_MPC85xx and openpic are still needed?
> > > >   
> > > 
> > > Have you tested some of the other (TCG) boards (for instance, 
> > > with the 
> > > debian image Aurelien recently posted)?
> > > 

This image is only for g3beige, it won't work on mac99 which is moreover
broken.

> > You mean test powerpc mac99? No.
> 
> It doesn't sound like mac99 works right now anyways, so that may not be
> possible to test.

Confirmed. We hope to get it working in the next few weeks/months using
OpenBIOS, the same way as for the g3beige machine.

> > I only modified few places to the original code. I think it won't be influenced.
> > But mpic and openpic couldnot work in the same qemu binary with this patch.
> > If they should both be supported, then I need to modify more.
> 
> Due to the (artificial) "ppc" vs "ppcemb" split, I'm not sure this is a
> requirement.

Agreed. I am fine with some changes if they are only done for the ppcemb
binary.

> The only issue I can see is if there are "ppc" targets (e.g. 970) that
> use the same[1] MPIC as found on e500, and that is different from and
> not supported by the current OpenPIC emulation.

The person adding support for those "ppc" targets, will have to modify
the code to support both versions at runtime.

> [1] By "same" I mean "substantially similar". As I understand it,
> OpenPIC and MPIC are very similar designs, but there are different
> bugs/quirks to different implementations. So even if e500's MPIC isn't
> *exactly* the same as 970 chipsets' MPIC, if they're close enough that
> the code could be shared, it should be.
> 
> -- 
> Hollis Blanchard
> IBM Linux Technology Center
> 
> 
> 
> 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500
@ 2009-01-16 21:20               ` Aurelien Jarno
  0 siblings, 0 replies; 52+ messages in thread
From: Aurelien Jarno @ 2009-01-16 21:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: Liu Yu, kvm-ppc

On Fri, Jan 16, 2009 at 12:17:40PM -0600, Hollis Blanchard wrote:
> On Fri, 2009-01-16 at 13:34 +0800, Liu Yu wrote:
> > 
> > > -----Original Message-----
> > > From: Anthony Liguori [mailto:anthony@codemonkey.ws] 
> > > Sent: Friday, January 16, 2009 5:23 AM
> > > To: qemu-devel@nongnu.org
> > > Cc: Liu Yu-B13201; kvm-ppc@vger.kernel.org
> > > Subject: Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable 
> > > mpic for E500 platform
> > > 
> > > Liu Yu wrote:
> > > > The modify is based on original author's method
> > > > to switch openpic and mpic by static define,
> > > > like the switch between USE_INTEL_GW80314 and USE_MPCxxx.
> > > > (Although the support for intel has broken)
> > > > So they can't be used at the same time.
> > > >
> > > > I guess it's not the correct way to do this.
> > > > but I am not sure is the USE_MPC85xx and openpic are still needed?
> > > >   
> > > 
> > > Have you tested some of the other (TCG) boards (for instance, 
> > > with the 
> > > debian image Aurelien recently posted)?
> > > 

This image is only for g3beige, it won't work on mac99 which is moreover
broken.

> > You mean test powerpc mac99? No.
> 
> It doesn't sound like mac99 works right now anyways, so that may not be
> possible to test.

Confirmed. We hope to get it working in the next few weeks/months using
OpenBIOS, the same way as for the g3beige machine.

> > I only modified few places to the original code. I think it won't be influenced.
> > But mpic and openpic couldnot work in the same qemu binary with this patch.
> > If they should both be supported, then I need to modify more.
> 
> Due to the (artificial) "ppc" vs "ppcemb" split, I'm not sure this is a
> requirement.

Agreed. I am fine with some changes if they are only done for the ppcemb
binary.

> The only issue I can see is if there are "ppc" targets (e.g. 970) that
> use the same[1] MPIC as found on e500, and that is different from and
> not supported by the current OpenPIC emulation.

The person adding support for those "ppc" targets, will have to modify
the code to support both versions at runtime.

> [1] By "same" I mean "substantially similar". As I understand it,
> OpenPIC and MPIC are very similar designs, but there are different
> bugs/quirks to different implementations. So even if e500's MPIC isn't
> *exactly* the same as 970 chipsets' MPIC, if they're close enough that
> the code could be shared, it should be.
> 
> -- 
> Hollis Blanchard
> IBM Linux Technology Center
> 
> 
> 
> 

-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-16 18:02                     ` Hollis Blanchard
@ 2009-01-19 10:54                       ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-19 10:54 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Saturday, January 17, 2009 2:03 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> > 
> > I still want to fixup guest memory size at certain 
> alignment boundary,
> > so that KVM can handle the mmu easily.
> 
> How about "ram_size &= ~(256<<20)" then?
> 
> The code that you copied is more complicated because it's 
> trying to fill
> in SDRAM banks which can only support a small range of fixed sizes.
> Since you don't have that problem, I think you should simplify.
> 

I am not sure should I support more complicated sizes such as 256 + 128
+ 64 = 448 MB

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-19 10:54                       ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-19 10:54 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Saturday, January 17, 2009 2:03 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> > 
> > I still want to fixup guest memory size at certain 
> alignment boundary,
> > so that KVM can handle the mmu easily.
> 
> How about "ram_size &= ~(256<<20)" then?
> 
> The code that you copied is more complicated because it's 
> trying to fill
> in SDRAM banks which can only support a small range of fixed sizes.
> Since you don't have that problem, I think you should simplify.
> 

I am not sure should I support more complicated sizes such as 256 + 128
+ 64 = 448 MB

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
  2009-01-19 10:54                       ` Liu Yu
@ 2009-01-19 10:59                         ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-19 10:59 UTC (permalink / raw)
  To: Liu Yu-B13201, Hollis Blanchard; +Cc: qemu-devel, kvm-ppc



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Liu Yu-B13201
> Sent: Monday, January 19, 2009 6:55 PM
> To: Hollis Blanchard
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> 
> > -----Original Message-----
> > From: kvm-ppc-owner@vger.kernel.org 
> > [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> > Sent: Saturday, January 17, 2009 2:03 AM
> > To: Liu Yu-B13201
> > Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> > Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> > 
> > On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> > > 
> > > I still want to fixup guest memory size at certain 
> > alignment boundary,
> > > so that KVM can handle the mmu easily.
> > 
> > How about "ram_size &= ~(256<<20)" then?
> > 
> > The code that you copied is more complicated because it's 
> > trying to fill
> > in SDRAM banks which can only support a small range of fixed sizes.
> > Since you don't have that problem, I think you should simplify.
> > 
> 
> I am not sure should I support more complicated sizes such as 
> 256 + 128
> + 64 = 448 MB

Hmm...,  I could use "ram_size &= ~(64<<20)"

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
@ 2009-01-19 10:59                         ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-19 10:59 UTC (permalink / raw)
  To: Liu Yu-B13201, Hollis Blanchard; +Cc: qemu-devel, kvm-ppc



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Liu Yu-B13201
> Sent: Monday, January 19, 2009 6:55 PM
> To: Hollis Blanchard
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> 
> 
> > -----Original Message-----
> > From: kvm-ppc-owner@vger.kernel.org 
> > [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> > Sent: Saturday, January 17, 2009 2:03 AM
> > To: Liu Yu-B13201
> > Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> > Subject: RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation
> > 
> > On Fri, 2009-01-16 at 15:51 +0800, Liu Yu wrote:
> > > 
> > > I still want to fixup guest memory size at certain 
> > alignment boundary,
> > > so that KVM can handle the mmu easily.
> > 
> > How about "ram_size &= ~(256<<20)" then?
> > 
> > The code that you copied is more complicated because it's 
> > trying to fill
> > in SDRAM banks which can only support a small range of fixed sizes.
> > Since you don't have that problem, I think you should simplify.
> > 
> 
> I am not sure should I support more complicated sizes such as 
> 256 + 128
> + 64 = 448 MB

Hmm...,  I could use "ram_size &= ~(64<<20)"

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
  2009-01-16 18:09                       ` Hollis Blanchard
@ 2009-01-20  3:09                         ` Liu Yu
  -1 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-20  3:09 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Saturday, January 17, 2009 2:10 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> 
> Hmm, I have no idea why I didn't see this patch. Maybe it got 
> caught in
> a spam filter.

I should have cc to you...

> 
> On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > > -----Original Message-----
> > > From: Liu Yu-B13201 
> > > Sent: Thursday, January 15, 2009 8:34 PM
> > > To: qemu-devel@nongnu.org
> > > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > > 
> > > MPC85xx adopts E500 core.
> > > This patch hopes to support all MPC85xx boards.
> > > 
> > > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > > --- /dev/null
> > > +++ b/hw/ppce500_mpc85xx.c
> > > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > > +    		const char *boot_device, DisplayState *ds,
> > > +    		const char *kernel_filename,
> > > +    		const char *kernel_cmdline,
> > > +    		const char *initrd_filename,
> > > +    		const char *cpu_model)
> > > +{
> > > +    PCIBus *pci_bus;
> > > +    CPUState *env;
> > > +    uint64_t elf_entry;
> > > +    uint64_t elf_lowaddr;
> > > +    target_ulong entry=0;
> > > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > > +    target_long kernel_size=0;
> > > +    target_ulong dt_base=DTB_LOAD_BASE;
> > > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > > +    target_long initrd_size=0;
> > > +    void *fdt;
> > > +    int i=0;
> > > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > > +    SerialState * serial[2];
> > > +
> > > +    /* Setup CPU */
> > > +    env = ppce500_init(&ram_size);
> > > +
> > > +    /* MPIC */
> > > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > > +
> > > +    /* Serial */
> > > +    if (serial_hds[0])
> > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > > +			0, mpic[12+26], 399193,
> > > +			serial_hds[0], 1);
> > > +
> > > +    if (serial_hds[1])
> > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > > +			0, mpic[12+26], 399193,
> > > +			serial_hds[0], 1);
> > > +
> > > +    /* PCI */
> > > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > > +    if (!pci_bus)
> > > +	printf("couldn't create PCI controller!\n");
> > > +
> > > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > > +
> > > +    /* Register mem */
> > > +    cpu_register_physical_memory(0, ram_size, 0);
> > 
> > Hollis, I didn't see the memeory register like this in 440 code.
> > Is that a bug?
> 
> RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
> like you're actually allocating twice the amount of memory you should
> be.
> 

It's odd.
I cannot make it work without cpu_register_physical_memory() which
ultimately call kvm_set_phys_mem().
But qemu_vmalloc() seems just to call mmap().
Did I miss anything?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
@ 2009-01-20  3:09                         ` Liu Yu
  0 siblings, 0 replies; 52+ messages in thread
From: Liu Yu @ 2009-01-20  3:09 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: qemu-devel, kvm-ppc


> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org 
> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> Sent: Saturday, January 17, 2009 2:10 AM
> To: Liu Yu-B13201
> Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> Subject: RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> 
> Hmm, I have no idea why I didn't see this patch. Maybe it got 
> caught in
> a spam filter.

I should have cc to you...

> 
> On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > > -----Original Message-----
> > > From: Liu Yu-B13201 
> > > Sent: Thursday, January 15, 2009 8:34 PM
> > > To: qemu-devel@nongnu.org
> > > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > > 
> > > MPC85xx adopts E500 core.
> > > This patch hopes to support all MPC85xx boards.
> > > 
> > > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > > --- /dev/null
> > > +++ b/hw/ppce500_mpc85xx.c
> > > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > > +    		const char *boot_device, DisplayState *ds,
> > > +    		const char *kernel_filename,
> > > +    		const char *kernel_cmdline,
> > > +    		const char *initrd_filename,
> > > +    		const char *cpu_model)
> > > +{
> > > +    PCIBus *pci_bus;
> > > +    CPUState *env;
> > > +    uint64_t elf_entry;
> > > +    uint64_t elf_lowaddr;
> > > +    target_ulong entry=0;
> > > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > > +    target_long kernel_size=0;
> > > +    target_ulong dt_base=DTB_LOAD_BASE;
> > > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > > +    target_long initrd_size=0;
> > > +    void *fdt;
> > > +    int i=0;
> > > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > > +    SerialState * serial[2];
> > > +
> > > +    /* Setup CPU */
> > > +    env = ppce500_init(&ram_size);
> > > +
> > > +    /* MPIC */
> > > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > > +
> > > +    /* Serial */
> > > +    if (serial_hds[0])
> > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > > +			0, mpic[12+26], 399193,
> > > +			serial_hds[0], 1);
> > > +
> > > +    if (serial_hds[1])
> > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > > +			0, mpic[12+26], 399193,
> > > +			serial_hds[0], 1);
> > > +
> > > +    /* PCI */
> > > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > > +    if (!pci_bus)
> > > +	printf("couldn't create PCI controller!\n");
> > > +
> > > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > > +
> > > +    /* Register mem */
> > > +    cpu_register_physical_memory(0, ram_size, 0);
> > 
> > Hollis, I didn't see the memeory register like this in 440 code.
> > Is that a bug?
> 
> RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
> like you're actually allocating twice the amount of memory you should
> be.
> 

It's odd.
I cannot make it work without cpu_register_physical_memory() which
ultimately call kvm_set_phys_mem().
But qemu_vmalloc() seems just to call mmap().
Did I miss anything?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
  2009-01-20  3:09                         ` Liu Yu
@ 2009-01-20 17:23                           ` Hollis Blanchard
  -1 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-20 17:23 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Tue, 2009-01-20 at 11:09 +0800, Liu Yu wrote:
> > -----Original Message-----
> > From: kvm-ppc-owner@vger.kernel.org 
> > [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> > Sent: Saturday, January 17, 2009 2:10 AM
> > To: Liu Yu-B13201
> > Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> > Subject: RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > 
> > Hmm, I have no idea why I didn't see this patch. Maybe it got 
> > caught in
> > a spam filter.
> 
> I should have cc to you...
> 
> > 
> > On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > > > -----Original Message-----
> > > > From: Liu Yu-B13201 
> > > > Sent: Thursday, January 15, 2009 8:34 PM
> > > > To: qemu-devel@nongnu.org
> > > > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > > > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > > > 
> > > > MPC85xx adopts E500 core.
> > > > This patch hopes to support all MPC85xx boards.
> > > > 
> > > > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > > > --- /dev/null
> > > > +++ b/hw/ppce500_mpc85xx.c
> > > > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > > > +    		const char *boot_device, DisplayState *ds,
> > > > +    		const char *kernel_filename,
> > > > +    		const char *kernel_cmdline,
> > > > +    		const char *initrd_filename,
> > > > +    		const char *cpu_model)
> > > > +{
> > > > +    PCIBus *pci_bus;
> > > > +    CPUState *env;
> > > > +    uint64_t elf_entry;
> > > > +    uint64_t elf_lowaddr;
> > > > +    target_ulong entry=0;
> > > > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > > > +    target_long kernel_size=0;
> > > > +    target_ulong dt_base=DTB_LOAD_BASE;
> > > > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > > > +    target_long initrd_size=0;
> > > > +    void *fdt;
> > > > +    int i=0;
> > > > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > > > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > > > +    SerialState * serial[2];
> > > > +
> > > > +    /* Setup CPU */
> > > > +    env = ppce500_init(&ram_size);
> > > > +
> > > > +    /* MPIC */
> > > > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > > > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > > > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > > > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > > > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > > > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > > > +
> > > > +    /* Serial */
> > > > +    if (serial_hds[0])
> > > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > > > +			0, mpic[12+26], 399193,
> > > > +			serial_hds[0], 1);
> > > > +
> > > > +    if (serial_hds[1])
> > > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > > > +			0, mpic[12+26], 399193,
> > > > +			serial_hds[0], 1);
> > > > +
> > > > +    /* PCI */
> > > > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > > > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > > > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > > > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > > > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > > > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > > > +    if (!pci_bus)
> > > > +	printf("couldn't create PCI controller!\n");
> > > > +
> > > > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > > > +
> > > > +    /* Register mem */
> > > > +    cpu_register_physical_memory(0, ram_size, 0);
> > > 
> > > Hollis, I didn't see the memeory register like this in 440 code.
> > > Is that a bug?
> > 
> > RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
> > like you're actually allocating twice the amount of memory you should
> > be.
> > 
> 
> It's odd.
> I cannot make it work without cpu_register_physical_memory() which
> ultimately call kvm_set_phys_mem().
> But qemu_vmalloc() seems just to call mmap().
> Did I miss anything?

OK, I was *really* confused on this one for a while... you're correct,
you must call cpu_register_physical_memory().

On 4xx, that is done by the memory controller emulation
(sdram_set_bcr()). Since you aren't using that code, you do need to call
it yourself.

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
@ 2009-01-20 17:23                           ` Hollis Blanchard
  0 siblings, 0 replies; 52+ messages in thread
From: Hollis Blanchard @ 2009-01-20 17:23 UTC (permalink / raw)
  To: Liu Yu; +Cc: qemu-devel, kvm-ppc

On Tue, 2009-01-20 at 11:09 +0800, Liu Yu wrote:
> > -----Original Message-----
> > From: kvm-ppc-owner@vger.kernel.org 
> > [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Hollis Blanchard
> > Sent: Saturday, January 17, 2009 2:10 AM
> > To: Liu Yu-B13201
> > Cc: qemu-devel@nongnu.org; kvm-ppc@vger.kernel.org
> > Subject: RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > 
> > Hmm, I have no idea why I didn't see this patch. Maybe it got 
> > caught in
> > a spam filter.
> 
> I should have cc to you...
> 
> > 
> > On Fri, 2009-01-16 at 16:22 +0800, Liu Yu wrote:
> > > > -----Original Message-----
> > > > From: Liu Yu-B13201 
> > > > Sent: Thursday, January 15, 2009 8:34 PM
> > > > To: qemu-devel@nongnu.org
> > > > Cc: kvm-ppc@vger.kernel.org; Liu Yu-B13201
> > > > Subject: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support
> > > > 
> > > > MPC85xx adopts E500 core.
> > > > This patch hopes to support all MPC85xx boards.
> > > > 
> > > > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > > > --- /dev/null
> > > > +++ b/hw/ppce500_mpc85xx.c
> > > > +static void mpc85xx_init(ram_addr_t ram_size, int vga_ram_size,
> > > > +    		const char *boot_device, DisplayState *ds,
> > > > +    		const char *kernel_filename,
> > > > +    		const char *kernel_cmdline,
> > > > +    		const char *initrd_filename,
> > > > +    		const char *cpu_model)
> > > > +{
> > > > +    PCIBus *pci_bus;
> > > > +    CPUState *env;
> > > > +    uint64_t elf_entry;
> > > > +    uint64_t elf_lowaddr;
> > > > +    target_ulong entry=0;
> > > > +    target_ulong loadaddr=UIMAGE_LOAD_BASE;
> > > > +    target_long kernel_size=0;
> > > > +    target_ulong dt_base=DTB_LOAD_BASE;
> > > > +    target_ulong initrd_base=INITRD_LOAD_BASE;
> > > > +    target_long initrd_size=0;
> > > > +    void *fdt;
> > > > +    int i=0;
> > > > +    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
> > > > +    qemu_irq *irqs, *mpic, *pci_irqs;
> > > > +    SerialState * serial[2];
> > > > +
> > > > +    /* Setup CPU */
> > > > +    env = ppce500_init(&ram_size);
> > > > +
> > > > +    /* MPIC */
> > > > +    irqs = qemu_mallocz(sizeof(qemu_irq) * MPIC_OUTPUT_NB);
> > > > +    irqs[MPIC_OUTPUT_INT] = ((qemu_irq 
> > > > *)env->irq_inputs)[PPCE500_INPUT_INT];
> > > > +    irqs[MPIC_OUTPUT_CINT] = ((qemu_irq 
> > > > *)env->irq_inputs)[PPCE500_INPUT_CINT];
> > > > +    mpic = mpic_init(MPC85xx_MPIC_REGS_BASE, 1, &irqs, NULL);
> > > > +
> > > > +    /* Serial */
> > > > +    if (serial_hds[0])
> > > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL0_REGS_BASE,
> > > > +			0, mpic[12+26], 399193,
> > > > +			serial_hds[0], 1);
> > > > +
> > > > +    if (serial_hds[1])
> > > > +	serial[0] = serial_mm_init(MPC85xx_SERIAL1_REGS_BASE,
> > > > +			0, mpic[12+26], 399193,
> > > > +			serial_hds[0], 1);
> > > > +
> > > > +    /* PCI */
> > > > +    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
> > > > +    pci_irqs[0] = mpic[pci_irq_nrs[0]];
> > > > +    pci_irqs[1] = mpic[pci_irq_nrs[1]];
> > > > +    pci_irqs[2] = mpic[pci_irq_nrs[2]];
> > > > +    pci_irqs[3] = mpic[pci_irq_nrs[3]];
> > > > +    pci_bus = ppce500_pci_init(pci_irqs, MPC85xx_PCI_REGS_BASE);
> > > > +    if (!pci_bus)
> > > > +	printf("couldn't create PCI controller!\n");
> > > > +
> > > > +    isa_mmio_init(MPC85xx_PCI_IO, MPC85xx_PCI_IOLEN);
> > > > +
> > > > +    /* Register mem */
> > > > +    cpu_register_physical_memory(0, ram_size, 0);
> > > 
> > > Hollis, I didn't see the memeory register like this in 440 code.
> > > Is that a bug?
> > 
> > RAM is allocated in vl.c (see the call to qemu_vmalloc()), so it looks
> > like you're actually allocating twice the amount of memory you should
> > be.
> > 
> 
> It's odd.
> I cannot make it work without cpu_register_physical_memory() which
> ultimately call kvm_set_phys_mem().
> But qemu_vmalloc() seems just to call mmap().
> Did I miss anything?

OK, I was *really* confused on this one for a while... you're correct,
you must call cpu_register_physical_memory().

On 4xx, that is done by the memory controller emulation
(sdram_set_bcr()). Since you aren't using that code, you do need to call
it yourself.

-- 
Hollis Blanchard
IBM Linux Technology Center


^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2009-01-20 17:23 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-15 12:34 [Qemu-devel] [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support Liu Yu
2009-01-15 12:34 ` Liu Yu
2009-01-15 12:34 ` [Qemu-devel] [PATCH 1/9] powerpc/kvm: Fix a uninitialized bug Liu Yu
2009-01-15 12:34   ` Liu Yu
2009-01-15 12:34   ` [Qemu-devel] [PATCH 2/9] powerpc/kvm: fix a openpic bug Liu Yu
2009-01-15 12:34     ` Liu Yu
2009-01-15 12:34     ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform Liu Yu
2009-01-15 12:34       ` Liu Yu
2009-01-15 12:34       ` [Qemu-devel] [PATCH 4/9] powerpc/kvm: enable POWERPC_MMU_BOOKE_FSL when kvm is enabled Liu Yu
2009-01-15 12:34         ` Liu Yu
2009-01-15 12:34         ` [Qemu-devel] [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support Liu Yu
2009-01-15 12:34           ` Liu Yu
2009-01-15 12:34           ` [Qemu-devel] [PATCH 6/9] powerpc/kvm: Add E500 irq support Liu Yu
2009-01-15 12:34             ` Liu Yu
2009-01-15 12:34             ` [Qemu-devel] [PATCH 7/9] powerpc/kvm: Add E500 core emulation Liu Yu
2009-01-15 12:34               ` Liu Yu
2009-01-15 12:34               ` [Qemu-devel] [PATCH 8/9] powerpc/kvm: extern one function for E500 code use Liu Yu
2009-01-15 12:34                 ` Liu Yu
     [not found]                 ` <1232022857-2315-10-git-send-email-yu.liu@freescale.com>
2009-01-16  8:22                   ` [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support Liu Yu
2009-01-16  8:22                     ` Liu Yu
2009-01-16 18:09                     ` [Qemu-devel] " Hollis Blanchard
2009-01-16 18:09                       ` Hollis Blanchard
2009-01-20  3:09                       ` [Qemu-devel] " Liu Yu
2009-01-20  3:09                         ` Liu Yu
2009-01-20 17:23                         ` [Qemu-devel] " Hollis Blanchard
2009-01-20 17:23                           ` Hollis Blanchard
2009-01-15 19:53               ` [Qemu-devel] Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation Hollis Blanchard
2009-01-15 19:53                 ` Hollis Blanchard
2009-01-16  7:51                 ` [Qemu-devel] " Liu Yu
2009-01-16  7:51                   ` Liu Yu
2009-01-16 18:02                   ` [Qemu-devel] " Hollis Blanchard
2009-01-16 18:02                     ` Hollis Blanchard
2009-01-19 10:54                     ` [Qemu-devel] " Liu Yu
2009-01-19 10:54                       ` Liu Yu
2009-01-19 10:59                       ` [Qemu-devel] " Liu Yu
2009-01-19 10:59                         ` Liu Yu
2009-01-15 20:02           ` [Qemu-devel] Re: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support Hollis Blanchard
2009-01-15 20:02             ` Hollis Blanchard
2009-01-16  7:37             ` [Qemu-devel] " Liu Yu
2009-01-16  7:37               ` Liu Yu
2009-01-15 21:22       ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform Anthony Liguori
2009-01-15 21:22         ` Anthony Liguori
2009-01-16  5:34         ` Liu Yu
2009-01-16  5:34           ` Liu Yu
2009-01-16 18:17           ` Hollis Blanchard
2009-01-16 18:17             ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 Hollis Blanchard
2009-01-16 21:20             ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform Aurelien Jarno
2009-01-16 21:20               ` [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 Aurelien Jarno
2009-01-15 20:06 ` [Qemu-devel] Re: [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support Hollis Blanchard
2009-01-15 20:06   ` Hollis Blanchard
2009-01-15 21:26 ` [Qemu-devel] " Anthony Liguori
2009-01-15 21:26   ` Anthony Liguori

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.