* [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.