All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] various ARM fixes
@ 2011-12-22 18:20 Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers Mark Langsdorf
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, paul

This is a collection of fixes and additions to the models for various ARM
devices. These changes are needed to support the forthcoming Calxeda 
Highbank SoC model.


 Makefile.target     |    2 +
 hw/a9mpcore.c       |   36 ++++-
 hw/arm_gic.c        |    6 +
 hw/arm_l2x0.c       |  173 +++++++++++++++++++++
 hw/arm_timer.c      |   26 +++-
 hw/ide/ahci.c       |   49 +++++-
 hw/ide/ich.c        |    4 +-
 hw/xgmac.c          |  418 +++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h    |    1 +
 target-arm/helper.c |   14 ++
 10 files changed, 712 insertions(+), 17 deletions(-)

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

* [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:23   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer Mark Langsdorf
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

Add power control and non-secure access ctrl registers

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1:
	Added VMState support
	Checked alignment of writes to the power control register

 hw/a9mpcore.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index cd2985f..875ae98 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -29,6 +29,7 @@ gic_get_current_cpu(void)
 typedef struct a9mp_priv_state {
     gic_state gic;
     uint32_t scu_control;
+    uint32_t scu_status;
     uint32_t old_timer_status[8];
     uint32_t num_cpu;
     qemu_irq *timer_irq;
@@ -48,7 +49,13 @@ static uint64_t a9_scu_read(void *opaque, target_phys_addr_t offset,
     case 0x04: /* Configuration */
         return (((1 << s->num_cpu) - 1) << 4) | (s->num_cpu - 1);
     case 0x08: /* CPU Power Status */
-        return 0;
+        return s->scu_status;
+    case 0x09: /* CPU status.  */
+        return s->scu_status >> 8;
+    case 0x0a: /* CPU status.  */
+        return s->scu_status >> 16;
+    case 0x0b: /* CPU status.  */
+        return s->scu_status >> 24;
     case 0x0c: /* Invalidate All Registers In Secure State */
         return 0;
     case 0x40: /* Filtering Start Address Register */
@@ -73,6 +80,29 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
         break;
     case 0x4: /* Configuration: RO */
         break;
+    case 0x08: /* Power Control  */
+        s->scu_status = value;
+        break;
+    case 0x09: /* Power Control  */
+        s->scu_status &= ~(0xff << 8);
+        s->scu_status |= (value & 0xff) << 8;
+        break;
+    case 0x0A: /* Power Control  */
+        if (size == 1) {
+            s->scu_status &= ~(0xff << 16);
+            s->scu_status |= (value & 0xff) << 16;
+        } else if (size == 2) {
+            s->scu_status &= ~(0xffff << 16);
+            s->scu_status |= (value & 0xffff) << 16;
+        } else {
+            /* illegal number of bytes */
+            break;
+        }
+        break;
+    case 0x0B: /* Power Control  */
+        s->scu_status &= ~(0xff << 24);
+        s->scu_status |= (value & 0xff) << 24;
+        break;
     case 0x0c: /* Invalidate All Registers In Secure State */
         /* no-op as we do not implement caches */
         break;
@@ -80,7 +110,6 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
     case 0x44: /* Filtering End Address Register */
         /* RAZ/WI, like an implementation with only one AXI master */
         break;
-    case 0x8: /* CPU Power Status */
     case 0x50: /* SCU Access Control Register */
     case 0x54: /* SCU Non-secure Access Control Register */
         /* unimplemented, fall through */
@@ -173,6 +202,7 @@ static const VMStateDescription vmstate_a9mp_priv = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(scu_control, a9mp_priv_state),
+        VMSTATE_UINT32(scu_status, a9mp_priv_state),
         VMSTATE_UINT32_ARRAY(old_timer_status, a9mp_priv_state, 8),
         VMSTATE_END_OF_LIST()
     }
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:26   ` Peter Maydell
  2011-12-24  9:19   ` Andreas Färber
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, paul, Mark Langsdorf

Use qdev properties to allow board modelers to set the frequencies
for the sp804 timer. Each of the sp804's timers can have an
individual frequency. The timers default to 1MHz.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1
	Simplified multiple timer frequency handling
	Removed the shared default
 hw/arm_timer.c |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 0a5b9d2..d2738c7 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -9,6 +9,8 @@
 
 #include "sysbus.h"
 #include "qemu-timer.h"
+#include "qemu-common.h"
+#include "qdev.h"
 
 /* Common timer implementation.  */
 
@@ -178,6 +180,7 @@ typedef struct {
     SysBusDevice busdev;
     MemoryRegion iomem;
     arm_timer_state *timer[2];
+    int freq0, freq1;
     int level[2];
     qemu_irq irq;
 } sp804_state;
@@ -269,10 +272,13 @@ static int sp804_init(SysBusDevice *dev)
 
     qi = qemu_allocate_irqs(sp804_set_irq, s, 2);
     sysbus_init_irq(dev, &s->irq);
-    /* ??? The timers are actually configurable between 32kHz and 1MHz, but
-       we don't implement that.  */
-    s->timer[0] = arm_timer_init(1000000);
-    s->timer[1] = arm_timer_init(1000000);
+    /* The timers are configurable between 32kHz and 1MHz
+     * defaulting to 1MHz but overrideable as a property
+     * They can be configured individually as a property
+     * but default is shared frequency */
+    s->timer[0] = arm_timer_init(s->freq0);
+    s->timer[1] = arm_timer_init(s->freq1);
+
     s->timer[0]->irq = qi[0];
     s->timer[1]->irq = qi[1];
     memory_region_init_io(&s->iomem, &sp804_ops, s, "sp804", 0x1000);
@@ -281,6 +287,16 @@ static int sp804_init(SysBusDevice *dev)
     return 0;
 }
 
+static SysBusDeviceInfo sp804_info = {
+    .init = sp804_init,
+    .qdev.name = "sp804",
+    .qdev.size = sizeof(sp804_state),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_INT32("freq0", sp804_state, freq0, 1000000),
+        DEFINE_PROP_INT32("freq1", sp804_state, freq1, 1000000),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
 
 /* Integrator/CP timer module.  */
 
@@ -349,7 +365,7 @@ static int icp_pit_init(SysBusDevice *dev)
 static void arm_timer_register_devices(void)
 {
     sysbus_register_dev("integrator_pit", sizeof(icp_pit_state), icp_pit_init);
-    sysbus_register_dev("sp804", sizeof(sp804_state), sp804_init);
+    sysbus_register_withprop(&sp804_info);
 }
 
 device_init(arm_timer_register_devices)
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:30   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers Mark Langsdorf
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, paul, Mark Langsdorf

Add a cp15 config_base_register that currently defaults to 0.
After the QOM CPU support is added, the value will be properly
set to the periphal base value.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1
	renamed the register
	added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h    |    1 +
 target-arm/helper.c |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..449e620 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -149,6 +149,7 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..3899a43 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2111,6 +2111,20 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                /* The config_base_address should hold the value of
+                 * the peripheral base. ARM should get this from a CPU
+                 * object property, but that support isn't available in
+                 * December 2011. Default to 0 for now and board models
+                 * that care can set it by a private hook */
+                if (op1 == 4) {
+                    return env->cp15.c15_config_base_address;
+                }
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (2 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:32   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState Mark Langsdorf
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

Implement handling for the RAZ/WI gic security registers.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1
	Moved handling back inside the 0-0x100 block
	Added more clarifying comments

 hw/arm_gic.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 9b52119..0339cf5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -282,6 +282,10 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
             return ((GIC_NIRQ / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
         if (offset < 0x08)
             return 0;
+        if (offset >= 0x80) {
+            /* Interrupt Security , RAZ/WI */
+            return 0;
+        }
 #endif
         goto bad_reg;
     } else if (offset < 0x200) {
@@ -413,6 +417,8 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
             DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
         } else if (offset < 4) {
             /* ignored.  */
+        } else if (offset >= 0x80) {
+            /* Interrupt Security Registers, RAZ/WI */
         } else {
             goto bad_reg;
         }
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (3 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:35   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers Mark Langsdorf
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

Use AHCIState instead of AHCIPCIState so the function can be used for
non-PCI based AHCI controllers.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
 hw/ide/ahci.c |   14 +++++++-------
 hw/ide/ich.c  |    4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 0af201d..135d0ee 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -336,7 +336,7 @@ static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
             case HOST_CTL: /* R/W */
                 if (val & HOST_CTL_RESET) {
                     DPRINTF(-1, "HBA Reset\n");
-                    ahci_reset(container_of(s, AHCIPCIState, ahci));
+                    ahci_reset(s);
                 } else {
                     s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                     ahci_check_irq(s);
@@ -1199,18 +1199,18 @@ void ahci_uninit(AHCIState *s)
 
 void ahci_reset(void *opaque)
 {
-    struct AHCIPCIState *d = opaque;
+    struct AHCIState *s = opaque;
     AHCIPortRegs *pr;
     int i;
 
-    d->ahci.control_regs.irqstatus = 0;
-    d->ahci.control_regs.ghc = 0;
+    s->control_regs.irqstatus = 0;
+    s->control_regs.ghc = 0;
 
-    for (i = 0; i < d->ahci.ports; i++) {
-        pr = &d->ahci.dev[i].port_regs;
+    for (i = 0; i < s->ports; i++) {
+        pr = &s->dev[i].port_regs;
         pr->irq_stat = 0;
         pr->irq_mask = 0;
         pr->scr_ctl = 0;
-        ahci_reset_port(&d->ahci, i);
+        ahci_reset_port(s, i);
     }
 }
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 3f7510f..44363ec 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -102,7 +102,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     /* XXX Software should program this register */
     d->card.config[0x90]   = 1 << 6; /* Address Map Register - AHCI mode */
 
-    qemu_register_reset(ahci_reset, d);
+    qemu_register_reset(ahci_reset, &d->ahci);
 
     msi_init(dev, 0x50, 1, true, false);
     d->ahci.irq = d->card.irq[0];
@@ -133,7 +133,7 @@ static int pci_ich9_uninit(PCIDevice *dev)
     d = DO_UPCAST(struct AHCIPCIState, card, dev);
 
     msi_uninit(dev);
-    qemu_unregister_reset(ahci_reset, d);
+    qemu_unregister_reset(ahci_reset, &d->ahci);
     ahci_uninit(&d->ahci);
 
     return 0;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (4 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:39   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device Mark Langsdorf
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

Add support for ahci on sysbus.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
 hw/ide/ahci.c |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 135d0ee..8b56509 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -25,6 +25,7 @@
 #include <hw/msi.h>
 #include <hw/pc.h>
 #include <hw/pci.h>
+#include <hw/sysbus.h>
 
 #include "monitor.h"
 #include "dma.h"
@@ -1214,3 +1215,37 @@ void ahci_reset(void *opaque)
         ahci_reset_port(s, i);
     }
 }
+
+typedef struct PlatAHCIState {
+        SysBusDevice busdev;
+        AHCIState ahci;
+} PlatAHCIState;
+
+static int plat_ahci_init(SysBusDevice *dev)
+{
+    PlatAHCIState *s = FROM_SYSBUS(PlatAHCIState, dev);
+    ahci_init(&s->ahci, &dev->qdev, 1);
+
+    sysbus_init_mmio(dev, &s->ahci.mem);
+    sysbus_init_irq(dev, &s->ahci.irq);
+
+    qemu_register_reset(ahci_reset, &s->ahci);
+    return 0;
+}
+
+static SysBusDeviceInfo plat_ahci_info[] = {
+    {
+        .qdev.name    = "plat-ahci",
+        .qdev.size    = sizeof(PlatAHCIState),
+        .init         = plat_ahci_init,
+    },{
+        /* end of list */
+    }
+};
+
+static void plat_ahci_register(void)
+{
+    sysbus_register_withprop(plat_ahci_info);
+}
+device_init(plat_ahci_register);
+
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (5 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:53   ` Peter Maydell
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 8/9] Add xgmac ethernet model Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160 Mark Langsdorf
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

This is just a dummy device for ARM L2 cache controllers, based on the
pl310. The cache type parameter can be defined by a property value
and has a meaningful default.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1
	Corrected formatting
	Clarified the copyrights
	Clarified GPL revision
	Clarified model version
	Removed hw_error() calls
	Added a reset function
	Restructed everything as switch/case statements
	Added a type cache property

 Makefile.target |    1 +
 hw/arm_l2x0.c   |  173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 174 insertions(+), 0 deletions(-)
 create mode 100644 hw/arm_l2x0.c

diff --git a/Makefile.target b/Makefile.target
index 3261383..db5e44c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -336,6 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
 obj-arm-y += versatile_pci.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
+obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
new file mode 100644
index 0000000..84f6c5a
--- /dev/null
+++ b/hw/arm_l2x0.c
@@ -0,0 +1,173 @@
+/*
+ * ARM dummy L210, L220, PL310 cache controller.
+ *
+ * Copyright (c) 2010-2012 Calxeda
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysbus.h"
+
+/* L2C-310 r3p1 */
+#define CACHE_ID 0x410000c6
+#define DEFAULT_CACHE_TYPE 0x19080800
+
+typedef struct l2x0_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    uint32_t cache_type;
+    uint32_t ctrl;
+    uint32_t aux_ctrl;
+    uint32_t data_ctrl;
+    uint32_t tag_ctrl;
+    uint32_t filter_start;
+    uint32_t filter_end;
+} l2x0_state;
+
+static const VMStateDescription vmstate_l2x0 = {
+    .name = "l2x0",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ctrl, l2x0_state),
+        VMSTATE_UINT32(aux_ctrl, l2x0_state),
+        VMSTATE_UINT32(data_ctrl, l2x0_state),
+        VMSTATE_UINT32(tag_ctrl, l2x0_state),
+        VMSTATE_UINT32(filter_start, l2x0_state),
+        VMSTATE_UINT32(filter_end, l2x0_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
+static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset, unsigned size)
+{
+    l2x0_state *s = (l2x0_state *)opaque;
+    offset &= 0xfff;
+    if (offset >= 0x730 && offset < 0x800) {
+        return 0; /* cache ops complete */
+    }
+    switch (offset) {
+    case 0:
+        return CACHE_ID;
+    case 0x4:
+        return s->cache_type;
+    case 0x100:
+        return s->ctrl;
+    case 0x104:
+        return s->aux_ctrl;
+    case 0x108:
+        return s->tag_ctrl;
+    case 0x10C:
+        return s->data_ctrl;
+    case 0xC00:
+        return s->filter_start;
+    case 0xC04:
+        return s->filter_end;
+    case 0xF40:
+        return 0;
+    case 0xF60:
+        return 0;
+    case 0xF80:
+        return 0;
+    default:
+        fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
+        break;
+    }
+    return 0;
+}
+
+static void l2x0_priv_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size)
+{
+    l2x0_state *s = (l2x0_state *)opaque;
+    offset &= 0xfff;
+    if (offset >= 0x730 && offset < 0x800) {
+        /* ignore */
+        return;
+    }
+    switch (offset) {
+    case 0x100:
+        s->ctrl = value & 1;
+        break;
+    case 0x104:
+        s->aux_ctrl = value;
+        break;
+    case 0x108:
+        s->tag_ctrl = value;
+        break;
+    case 0x10C:
+        s->data_ctrl = value;
+        break;
+    case 0xC00:
+        s->filter_start = value;
+        break;
+    case 0xC04:
+        s->filter_end = value;
+        break;
+    case 0xF40:
+        return;
+    case 0xF60:
+        return;
+    case 0xF80:
+        return;
+    default:
+        fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset);
+        break;
+    }
+}
+
+static int l2x0_priv_reset(SysBusDevice *dev)
+{
+    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
+
+    s->aux_ctrl = 0x00020000;
+    return 0;
+}
+
+static const MemoryRegionOps l2x0_mem_ops = {
+    .read = l2x0_priv_read,
+    .write = l2x0_priv_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+ };
+
+static int l2x0_priv_init(SysBusDevice *dev)
+{
+    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
+
+    l2x0_priv_reset(dev);
+
+    memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
+    sysbus_init_mmio(dev, &s->iomem);
+    return 0;
+}
+
+static SysBusDeviceInfo l2x0_info = {
+    .init = l2x0_priv_init,
+    .qdev.name = "l2x0",
+    .qdev.size = sizeof(l2x0_state),
+    .qdev.vmsd = &vmstate_l2x0,
+    .qdev.no_user = 1,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, DEFAULT_CACHE_TYPE),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void l2x0_register_device(void)
+{
+    sysbus_register_withprop(&l2x0_info);
+}
+
+device_init(l2x0_register_device)
+
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v2 8/9] Add xgmac ethernet model
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (6 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160 Mark Langsdorf
  8 siblings, 0 replies; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

This adds very basic support for XG-mac ethernet core from Synopsis and
others. Missing things include:

- statistics counters
- WoL support
- rx checksum offload
- chained descriptors (only linear descriptor ring)
- broadcast and multicast handling

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v1
	Reformated most lines to fit within 80 columns
	Removed a bunch of unused variables in the state structures
	Got rid of some camelcase structure names
	Added vmstate support

 Makefile.target |    1 +
 hw/xgmac.c      |  418 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 419 insertions(+), 0 deletions(-)
 create mode 100644 hw/xgmac.c

diff --git a/Makefile.target b/Makefile.target
index db5e44c..94cb9ff 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -340,6 +340,7 @@ obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
+obj-arm-y += xgmac.o
 obj-arm-y += arm-semi.o
 obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
 obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
diff --git a/hw/xgmac.c b/hw/xgmac.c
new file mode 100644
index 0000000..a496b31
--- /dev/null
+++ b/hw/xgmac.c
@@ -0,0 +1,418 @@
+/*
+ * QEMU model of XGMAC Ethernet.
+ *
+ * derived from the Xilinx AXI-Ethernet by Edgar E. Iglesias.
+ *
+ * Copyright (c) 2011 Calxeda, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysbus.h"
+#include "qemu-char.h"
+#include "qemu-log.h"
+#include "net.h"
+#include "net/checksum.h"
+
+#define XGMAC_CONTROL           0x00000000   /* MAC Configuration */
+#define XGMAC_FRAME_FILTER      0x00000001   /* MAC Frame Filter */
+#define XGMAC_FLOW_CTRL         0x00000006   /* MAC Flow Control */
+#define XGMAC_VLAN_TAG          0x00000007   /* VLAN Tags */
+#define XGMAC_VERSION           0x00000008   /* Version */
+/* VLAN tag for insertion or replacement into tx frames */
+#define XGMAC_VLAN_INCL         0x00000009
+#define XGMAC_LPI_CTRL          0x0000000a   /* LPI Control and Status */
+#define XGMAC_LPI_TIMER         0x0000000b   /* LPI Timers Control */
+#define XGMAC_TX_PACE           0x0000000c   /* Transmit Pace and Stretch */
+#define XGMAC_VLAN_HASH         0x0000000d   /* VLAN Hash Table */
+#define XGMAC_DEBUG             0x0000000e   /* Debug */
+#define XGMAC_INT_STATUS        0x0000000f   /* Interrupt and Control */
+/* HASH table registers */
+#define XGMAC_HASH(n)           ((0x00000300/4) + (n))
+#define XGMAC_NUM_HASH          16
+/* Operation Mode */
+#define XGMAC_OPMODE            (0x00000400/4)
+/* Remote Wake-Up Frame Filter */
+#define XGMAC_REMOTE_WAKE       (0x00000700/4)
+/* PMT Control and Status */
+#define XGMAC_PMT               (0x00000704/4)
+
+#define XGMAC_ADDR_HIGH(reg)    (0x00000010+((reg) * 2))
+#define XGMAC_ADDR_LOW(reg)     (0x00000011+((reg) * 2))
+
+#define DMA_BUS_MODE            0x000003c0   /* Bus Mode */
+#define DMA_XMT_POLL_DEMAND     0x000003c1   /* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND     0x000003c2   /* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR       0x000003c3   /* Receive List Base */
+#define DMA_TX_BASE_ADDR        0x000003c4   /* Transmit List Base */
+#define DMA_STATUS              0x000003c5   /* Status Register */
+#define DMA_CONTROL             0x000003c6   /* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA            0x000003c7   /* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR    0x000003c8   /* Missed Frame Counter */
+/* Receive Interrupt Watchdog Timer */
+#define DMA_RI_WATCHDOG_TIMER   0x000003c9
+#define DMA_AXI_BUS             0x000003ca   /* AXI Bus Mode */
+#define DMA_AXI_STATUS          0x000003cb   /* AXI Status */
+#define DMA_CUR_TX_DESC_ADDR    0x000003d2   /* Current Host Tx Descriptor */
+#define DMA_CUR_RX_DESC_ADDR    0x000003d3   /* Current Host Rx Descriptor */
+#define DMA_CUR_TX_BUF_ADDR     0x000003d4   /* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR     0x000003d5   /* Current Host Rx Buffer */
+#define DMA_HW_FEATURE          0x000003d6   /* Enabled Hardware Features */
+
+/* DMA Status register defines */
+#define DMA_STATUS_GMI          0x08000000   /* MMC interrupt */
+#define DMA_STATUS_GLI          0x04000000   /* GMAC Line interface int */
+#define DMA_STATUS_EB_MASK      0x00380000   /* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT  0x00080000   /* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT  0x00100000   /* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK      0x00700000   /* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT     20
+#define DMA_STATUS_RS_MASK      0x000e0000   /* Receive Process State */
+#define DMA_STATUS_RS_SHIFT     17
+#define DMA_STATUS_NIS          0x00010000   /* Normal Interrupt Summary */
+#define DMA_STATUS_AIS          0x00008000   /* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI          0x00004000   /* Early Receive Interrupt */
+#define DMA_STATUS_FBI          0x00002000   /* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI          0x00000400   /* Early Transmit Interrupt */
+#define DMA_STATUS_RWT          0x00000200   /* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS          0x00000100   /* Receive Process Stopped */
+#define DMA_STATUS_RU           0x00000080   /* Receive Buffer Unavailable */
+#define DMA_STATUS_RI           0x00000040   /* Receive Interrupt */
+#define DMA_STATUS_UNF          0x00000020   /* Transmit Underflow */
+#define DMA_STATUS_OVF          0x00000010   /* Receive Overflow */
+#define DMA_STATUS_TJT          0x00000008   /* Transmit Jabber Timeout */
+#define DMA_STATUS_TU           0x00000004   /* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS          0x00000002   /* Transmit Process Stopped */
+#define DMA_STATUS_TI           0x00000001   /* Transmit Interrupt */
+
+/* DMA Control register defines */
+#define DMA_CONTROL_ST          0x00002000   /* Start/Stop Transmission */
+#define DMA_CONTROL_SR          0x00000002   /* Start/Stop Receive */
+#define DMA_CONTROL_DFF         0x01000000   /* Disable flush of rx frames */
+
+struct desc {
+    uint32_t ctl_stat;
+    uint16_t buffer1_size;
+    uint16_t buffer2_size;
+    uint32_t buffer1_addr;
+    uint32_t buffer2_addr;
+    uint32_t ext_stat;
+    uint32_t res[3];
+};
+
+#define R_MAX 0x400
+
+typedef struct rxtx_stats {
+    uint64_t rx_bytes;
+    uint64_t tx_bytes;
+
+    uint64_t rx;
+    uint64_t rx_bcast;
+    uint64_t rx_mcast;
+} rxtx_stats;
+
+typedef struct xgmac_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    qemu_irq sbd_irq;
+    qemu_irq pmt_irq;
+    qemu_irq mci_irq;
+    NICState *nic;
+    NICConf conf;
+
+    uint32_t c_phyaddr;
+    struct rxtx_stats stats;
+    uint32_t regs[R_MAX];
+} xgmac_state;
+
+const VMStateDescription vmstate_rxtx_stats = {
+    .name = "xgmac_stats",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT64(rx_bytes, rxtx_stats),
+        VMSTATE_UINT64(tx_bytes, rxtx_stats),
+        VMSTATE_UINT64(rx, rxtx_stats),
+        VMSTATE_UINT64(rx_bcast, rxtx_stats),
+        VMSTATE_UINT64(rx_mcast, rxtx_stats),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_xgmac = {
+    .name = "xgmac",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(c_phyaddr, xgmac_state),
+        VMSTATE_STRUCT(stats, xgmac_state, 0, vmstate_rxtx_stats, rxtx_stats),
+        VMSTATE_UINT32_ARRAY(regs, xgmac_state, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void xgmac_read_desc(struct xgmac_state *s, struct desc *d, int rx)
+{
+    uint32_t addr = rx ? s->regs[DMA_CUR_RX_DESC_ADDR] :
+        s->regs[DMA_CUR_TX_DESC_ADDR];
+    cpu_physical_memory_read(addr, d, sizeof(*d));
+}
+
+static void xgmac_write_desc(struct xgmac_state *s, struct desc *d, int rx)
+{
+    int reg = rx ? DMA_CUR_RX_DESC_ADDR : DMA_CUR_TX_DESC_ADDR;
+    uint32_t addr = s->regs[reg];
+
+    if (!rx && (d->ctl_stat & 0x00200000)) {
+        s->regs[reg] = s->regs[DMA_TX_BASE_ADDR];
+    } else if (rx && (d->buffer1_size & 0x8000)) {
+        s->regs[reg] = s->regs[DMA_RCV_BASE_ADDR];
+    } else {
+        s->regs[reg] += sizeof(*d);
+    }
+    cpu_physical_memory_write(addr, d, sizeof(*d));
+}
+
+static void xgmac_enet_send(struct xgmac_state *s)
+{
+    struct desc bd;
+    int frame_size;
+    int len;
+    uint8_t frame[8192];
+    uint8_t *ptr;
+
+    ptr = frame;
+    frame_size = 0;
+    while (1) {
+        xgmac_read_desc(s, &bd, 0);
+        if ((bd.ctl_stat & 0x80000000) == 0) {
+            /* Run out of descriptors to transmit.  */
+            break;
+        }
+        len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
+
+        if ((bd.buffer1_size & 0xfff) > 2048) {
+            fprintf(stdout, "qemu:%s:ERROR...ERROR...ERROR... -- "
+                        "xgmac buffer 1 len on send > 2048 (0x%x)\n",
+                         __func__, bd.buffer1_size & 0xfff);
+            fflush(stdout);
+        }
+        if ((bd.buffer2_size & 0xfff) != 0) {
+            fprintf(stdout, "qemu:%s:ERROR...ERROR...ERROR... -- "
+                        "xgmac buffer 2 len on send != 0 (0x%x)\n",
+                        __func__, bd.buffer2_size & 0xfff);
+            fflush(stdout);
+        }
+        if (len >= sizeof(frame)) {
+            fprintf(stdout, "qemu:%s: buffer overflow %d read into %zu "
+                        "buffer\n" , __func__, len, sizeof(frame));
+            fprintf(stdout, "qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
+                        __func__, bd.buffer1_size, bd.buffer2_size);
+            fflush(stdout);
+        }
+
+        cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
+        ptr += len;
+        frame_size += len;
+        if (bd.ctl_stat & 0x20000000) {
+            /* Last buffer in frame.  */
+            qemu_send_packet(&s->nic->nc, frame, len);
+            ptr = frame;
+            frame_size = 0;
+            s->regs[DMA_STATUS] |= DMA_STATUS_TI | DMA_STATUS_NIS;
+        }
+        bd.ctl_stat &= ~0x80000000;
+        /* Write back the modified descriptor.  */
+        xgmac_write_desc(s, &bd, 0);
+    }
+}
+
+static void enet_update_irq(struct xgmac_state *s)
+{
+    int stat = s->regs[DMA_STATUS] & s->regs[DMA_INTR_ENA];
+    qemu_set_irq(s->sbd_irq, !!stat);
+}
+
+static uint64_t enet_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    struct xgmac_state *s = opaque;
+    uint64_t r = 0;
+    addr >>= 2;
+
+    switch (addr) {
+    case XGMAC_VERSION:
+        r = 0x1012;
+        break;
+    default:
+        if (addr < ARRAY_SIZE(s->regs)) {
+            r = s->regs[addr];
+        }
+        break;
+    }
+    return r;
+}
+
+static void enet_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size)
+{
+    struct xgmac_state *s = opaque;
+
+    addr >>= 2;
+    switch (addr) {
+    case DMA_BUS_MODE:
+        s->regs[DMA_BUS_MODE] = value & ~0x1;
+        break;
+    case DMA_XMT_POLL_DEMAND:
+        xgmac_enet_send(s);
+        break;
+    case DMA_STATUS:
+        s->regs[DMA_STATUS] = s->regs[DMA_STATUS] & ~value;
+        break;
+    case DMA_RCV_BASE_ADDR:
+        s->regs[DMA_RCV_BASE_ADDR] = s->regs[DMA_CUR_RX_DESC_ADDR] = value;
+        break;
+    case DMA_TX_BASE_ADDR:
+        s->regs[DMA_TX_BASE_ADDR] = s->regs[DMA_CUR_TX_DESC_ADDR] = value;
+        break;
+    default:
+        if (addr < ARRAY_SIZE(s->regs)) {
+            s->regs[addr] = value;
+        }
+        break;
+    }
+    enet_update_irq(s);
+}
+
+static const MemoryRegionOps enet_mem_ops = {
+    .read = enet_read,
+    .write = enet_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int eth_can_rx(VLANClientState *nc)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    /* RX enabled?  */
+    return s->regs[DMA_CONTROL] & DMA_CONTROL_SR;
+}
+
+static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
+                                              0xff, 0xff, 0xff};
+    int unicast, broadcast, multicast;
+    struct desc bd;
+    ssize_t ret;
+
+    unicast = ~buf[0] & 0x1;
+    broadcast = memcmp(buf, sa_bcast, 6) == 0;
+    multicast = !unicast && !broadcast;
+    if (size < 12) {
+        s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
+        ret = -1;
+        goto out;
+    }
+
+    xgmac_read_desc(s, &bd, 1);
+    if ((bd.ctl_stat & 0x80000000) == 0) {
+        s->regs[DMA_STATUS] |= DMA_STATUS_RU | DMA_STATUS_AIS;
+        ret = size;
+        goto out;
+    }
+
+    cpu_physical_memory_write(bd.buffer1_addr, buf, size);
+
+    /* Add in the 4 bytes for crc (the real hw returns length incl crc) */
+    size += 4;
+    bd.ctl_stat = (size << 16) | 0x300;
+    xgmac_write_desc(s, &bd, 1);
+
+    s->stats.rx_bytes += size;
+    s->stats.rx++;
+    if (multicast) {
+        s->stats.rx_mcast++;
+    } else if (broadcast) {
+        s->stats.rx_bcast++;
+    }
+
+    s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
+    ret = size;
+
+out:
+    enet_update_irq(s);
+    return ret;
+}
+
+static void eth_cleanup(VLANClientState *nc)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    s->nic = NULL;
+}
+
+static NetClientInfo net_xgmac_enet_info = {
+    .type = NET_CLIENT_TYPE_NIC,
+    .size = sizeof(NICState),
+    .can_receive = eth_can_rx,
+    .receive = eth_rx,
+    .cleanup = eth_cleanup,
+};
+
+static int xgmac_enet_init(SysBusDevice *dev)
+{
+    struct xgmac_state *s = FROM_SYSBUS(typeof(*s), dev);
+
+    memory_region_init_io(&s->iomem, &enet_mem_ops, s, "xgmac", 0x1000);
+    sysbus_init_mmio(dev, &s->iomem);
+    sysbus_init_irq(dev, &s->sbd_irq);
+    sysbus_init_irq(dev, &s->pmt_irq);
+    sysbus_init_irq(dev, &s->mci_irq);
+
+    qemu_macaddr_default_if_unset(&s->conf.macaddr);
+    s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf,
+                          dev->qdev.info->name, dev->qdev.id, s);
+    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
+
+    s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) |
+                                   s->conf.macaddr.a[4];
+    s->regs[XGMAC_ADDR_LOW(0)] = (s->conf.macaddr.a[3] << 24) |
+                                 (s->conf.macaddr.a[2] << 16) |
+                                 (s->conf.macaddr.a[1] << 8) |
+                                  s->conf.macaddr.a[0];
+
+    return 0;
+}
+
+static SysBusDeviceInfo xgmac_enet_info = {
+    .init = xgmac_enet_init,
+    .qdev.name  = "xgmac",
+    .qdev.size  = sizeof(struct xgmac_state),
+    .qdev.vmsd = &vmstate_xgmac,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("phyaddr", struct xgmac_state, c_phyaddr, 7),
+        DEFINE_NIC_PROPERTIES(struct xgmac_state, conf),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+static void xgmac_enet_register(void)
+{
+    sysbus_register_withprop(&xgmac_enet_info);
+}
+
+device_init(xgmac_enet_register)
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160
  2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
                   ` (7 preceding siblings ...)
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 8/9] Add xgmac ethernet model Mark Langsdorf
@ 2011-12-22 18:20 ` Mark Langsdorf
  2011-12-24  0:54   ` Rob Herring
  8 siblings, 1 reply; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-22 18:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, peter.maydell, Rob Herring, paul, Mark Langsdorf

From: Rob Herring <rob.herring@calxeda.com>

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
 hw/a9mpcore.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 875ae98..93b0498 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -13,7 +13,7 @@
 /* Configuration for arm_gic.c:
  * number of external IRQ lines, max number of CPUs, how to ID current CPU
  */
-#define GIC_NIRQ 96
+#define GIC_NIRQ 160
 #define NCPU 4
 
 static inline int
-- 
1.7.5.4

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

* Re: [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers Mark Langsdorf
@ 2011-12-24  0:23   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:23 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, Rob Herring, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add power control and non-secure access ctrl registers

Commit message says it's adding the non-secure
access control register, but the patch is only
doing power control.

>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> ---
> Changes from v1:
>        Added VMState support
>        Checked alignment of writes to the power control register
>
>  hw/a9mpcore.c |   34 ++++++++++++++++++++++++++++++++--
>  1 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index cd2985f..875ae98 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -29,6 +29,7 @@ gic_get_current_cpu(void)
>  typedef struct a9mp_priv_state {
>     gic_state gic;
>     uint32_t scu_control;
> +    uint32_t scu_status;
>     uint32_t old_timer_status[8];
>     uint32_t num_cpu;
>     qemu_irq *timer_irq;
> @@ -48,7 +49,13 @@ static uint64_t a9_scu_read(void *opaque, target_phys_addr_t offset,
>     case 0x04: /* Configuration */
>         return (((1 << s->num_cpu) - 1) << 4) | (s->num_cpu - 1);
>     case 0x08: /* CPU Power Status */
> -        return 0;
> +        return s->scu_status;
> +    case 0x09: /* CPU status.  */
> +        return s->scu_status >> 8;
> +    case 0x0a: /* CPU status.  */
> +        return s->scu_status >> 16;
> +    case 0x0b: /* CPU status.  */
> +        return s->scu_status >> 24;
>     case 0x0c: /* Invalidate All Registers In Secure State */
>         return 0;
>     case 0x40: /* Filtering Start Address Register */
> @@ -73,6 +80,29 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
>         break;
>     case 0x4: /* Configuration: RO */
>         break;
> +    case 0x08: /* Power Control  */
> +        s->scu_status = value;
> +        break;

This does the wrong thing for a byte or halfword
write to 0x8. (Byte writes in particular are going to be the
common case for this register for obvious reasons.)

> +    case 0x09: /* Power Control  */
> +        s->scu_status &= ~(0xff << 8);
> +        s->scu_status |= (value & 0xff) << 8;
> +        break;
> +    case 0x0A: /* Power Control  */
> +        if (size == 1) {
> +            s->scu_status &= ~(0xff << 16);
> +            s->scu_status |= (value & 0xff) << 16;
> +        } else if (size == 2) {
> +            s->scu_status &= ~(0xffff << 16);
> +            s->scu_status |= (value & 0xffff) << 16;
> +        } else {
> +            /* illegal number of bytes */
> +            break;
> +        }
> +        break;
> +    case 0x0B: /* Power Control  */
> +        s->scu_status &= ~(0xff << 24);
> +        s->scu_status |= (value & 0xff) << 24;
> +        break;

How about:
 switch (size) {
     case 1:
        mask = 0xff;
        break;
     case 2:
        mask = 0xffff;
        break;
     case 4:
        mask = 0xffffffff;
        break;
 }

Then the register write code simplifies to:
   case 0x08: case 0x09: case 0xa: case 0xb:
      shift = (offset - 0x8) * 8;
      s->scu_status &= ~(mask << shift);
      s->scu_status |= ((value & mask) << shift);
      break;

(written on the hoof and untested!)

>     case 0x0c: /* Invalidate All Registers In Secure State */
>         /* no-op as we do not implement caches */
>         break;
> @@ -80,7 +110,6 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
>     case 0x44: /* Filtering End Address Register */
>         /* RAZ/WI, like an implementation with only one AXI master */
>         break;
> -    case 0x8: /* CPU Power Status */
>     case 0x50: /* SCU Access Control Register */
>     case 0x54: /* SCU Non-secure Access Control Register */
>         /* unimplemented, fall through */
> @@ -173,6 +202,7 @@ static const VMStateDescription vmstate_a9mp_priv = {
>     .minimum_version_id = 1,
>     .fields = (VMStateField[]) {
>         VMSTATE_UINT32(scu_control, a9mp_priv_state),
> +        VMSTATE_UINT32(scu_status, a9mp_priv_state),
>         VMSTATE_UINT32_ARRAY(old_timer_status, a9mp_priv_state, 8),
>         VMSTATE_END_OF_LIST()
>     }

This breaks migration compatibility. You want:
 * set .version_id to 2
 * leave .minimum_version_id as 1
 * the new field should go at the end of the list and be:
 VMSTATE_UINT32_V(scu_status, a9mp_priv_state, 2),
(which says it only exists in version 2).

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer Mark Langsdorf
@ 2011-12-24  0:26   ` Peter Maydell
  2011-12-24  9:19   ` Andreas Färber
  1 sibling, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:26 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> Use qdev properties to allow board modelers to set the frequencies
> for the sp804 timer. Each of the sp804's timers can have an
> individual frequency. The timers default to 1MHz.
>
> +    /* The timers are configurable between 32kHz and 1MHz
> +     * defaulting to 1MHz but overrideable as a property
> +     * They can be configured individually as a property
> +     * but default is shared frequency */

You've forgotten to update this comment when you dropped the
shared-frequency property. Patch looks good otherwise.

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
@ 2011-12-24  0:30   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:30 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                /* The config_base_address should hold the value of
> +                 * the peripheral base. ARM should get this from a CPU
> +                 * object property, but that support isn't available in
> +                 * December 2011. Default to 0 for now and board models
> +                 * that care can set it by a private hook */
> +                if (op1 == 4) {
> +                    return env->cp15.c15_config_base_address;
> +                }

Still underdecoded -- op2 must be 0 as well.
Otherwise OK.

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers Mark Langsdorf
@ 2011-12-24  0:32   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:32 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, Rob Herring, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Implement handling for the RAZ/WI gic security registers.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

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

* Re: [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState Mark Langsdorf
@ 2011-12-24  0:35   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:35 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, Rob Herring, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Use AHCIState instead of AHCIPCIState so the function can be used for
> non-PCI based AHCI controllers.

Just a note that I'm assuming Kevin will review the IDE
related patches.

-- PMM

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

* Re: [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers Mark Langsdorf
@ 2011-12-24  0:39   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:39 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, Rob Herring, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add support for ahci on sysbus.

Again, IDE isn't my domain, but some minor points:
> +typedef struct PlatAHCIState {
> +        SysBusDevice busdev;
> +        AHCIState ahci;
> +} PlatAHCIState;

Indentation is wrong here.

> +static SysBusDeviceInfo plat_ahci_info[] = {
> +    {
> +        .qdev.name    = "plat-ahci",
> +        .qdev.size    = sizeof(PlatAHCIState),
> +        .init         = plat_ahci_init,
> +    },{
> +        /* end of list */
> +    }
> +};
> +
> +static void plat_ahci_register(void)
> +{
> +    sysbus_register_withprop(plat_ahci_info);
> +}

sysbus_register_withprop() takes a single SysBusDeviceInfo,
not a list.

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device Mark Langsdorf
@ 2011-12-24  0:53   ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  0:53 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, qemu-devel, Rob Herring, paul

On 22 December 2011 18:20, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

scripts/checkpatch.pl complains about a couple of overlong lines;
please fix.

> ---
> Changes from v1
>        Corrected formatting
>        Clarified the copyrights
>        Clarified GPL revision
>        Clarified model version
>        Removed hw_error() calls
>        Added a reset function
>        Restructed everything as switch/case statements
>        Added a type cache property
>
>  Makefile.target |    1 +
>  hw/arm_l2x0.c   |  173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 174 insertions(+), 0 deletions(-)
>  create mode 100644 hw/arm_l2x0.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 3261383..db5e44c 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -336,6 +336,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
>  obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
>  obj-arm-y += versatile_pci.o
>  obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> +obj-arm-y += arm_l2x0.o
>  obj-arm-y += arm_mptimer.o
>  obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
>  obj-arm-y += pl061.o
> diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
> new file mode 100644
> index 0000000..84f6c5a
> --- /dev/null
> +++ b/hw/arm_l2x0.c
> @@ -0,0 +1,173 @@
> +/*
> + * ARM dummy L210, L220, PL310 cache controller.
> + *
> + * Copyright (c) 2010-2012 Calxeda
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.

"Or any later version". We're trying to avoid new v2-only code, please.

> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include "sysbus.h"
> +
> +/* L2C-310 r3p1 */
> +#define CACHE_ID 0x410000c6

Why not r3p2 ?

> +#define DEFAULT_CACHE_TYPE 0x19080800
> +
> +typedef struct l2x0_state {
> +    SysBusDevice busdev;
> +    MemoryRegion iomem;
> +    uint32_t cache_type;
> +    uint32_t ctrl;
> +    uint32_t aux_ctrl;
> +    uint32_t data_ctrl;
> +    uint32_t tag_ctrl;
> +    uint32_t filter_start;
> +    uint32_t filter_end;
> +} l2x0_state;
> +
> +static const VMStateDescription vmstate_l2x0 = {
> +    .name = "l2x0",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32(ctrl, l2x0_state),
> +        VMSTATE_UINT32(aux_ctrl, l2x0_state),
> +        VMSTATE_UINT32(data_ctrl, l2x0_state),
> +        VMSTATE_UINT32(tag_ctrl, l2x0_state),
> +        VMSTATE_UINT32(filter_start, l2x0_state),
> +        VMSTATE_UINT32(filter_end, l2x0_state),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +
> +static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset, unsigned size)
> +{
> +    l2x0_state *s = (l2x0_state *)opaque;
> +    offset &= 0xfff;
> +    if (offset >= 0x730 && offset < 0x800) {
> +        return 0; /* cache ops complete */
> +    }
> +    switch (offset) {
> +    case 0:
> +        return CACHE_ID;
> +    case 0x4:
> +        return s->cache_type;
> +    case 0x100:
> +        return s->ctrl;
> +    case 0x104:
> +        return s->aux_ctrl;
> +    case 0x108:
> +        return s->tag_ctrl;
> +    case 0x10C:
> +        return s->data_ctrl;
> +    case 0xC00:
> +        return s->filter_start;
> +    case 0xC04:
> +        return s->filter_end;
> +    case 0xF40:
> +        return 0;
> +    case 0xF60:
> +        return 0;
> +    case 0xF80:
> +        return 0;
> +    default:
> +        fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
> +        break;
> +    }
> +    return 0;
> +}
> +
> +static void l2x0_priv_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size)
> +{
> +    l2x0_state *s = (l2x0_state *)opaque;
> +    offset &= 0xfff;
> +    if (offset >= 0x730 && offset < 0x800) {
> +        /* ignore */
> +        return;
> +    }
> +    switch (offset) {
> +    case 0x100:
> +        s->ctrl = value & 1;
> +        break;
> +    case 0x104:
> +        s->aux_ctrl = value;
> +        break;
> +    case 0x108:
> +        s->tag_ctrl = value;
> +        break;
> +    case 0x10C:
> +        s->data_ctrl = value;
> +        break;
> +    case 0xC00:
> +        s->filter_start = value;
> +        break;
> +    case 0xC04:
> +        s->filter_end = value;
> +        break;
> +    case 0xF40:
> +        return;
> +    case 0xF60:
> +        return;
> +    case 0xF80:
> +        return;
> +    default:
> +        fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset);
> +        break;
> +    }
> +}
> +
> +static int l2x0_priv_reset(SysBusDevice *dev)
> +{
> +    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
> +
> +    s->aux_ctrl = 0x00020000;

TRM says the aux ctrl reset value is 0x02020000.
This should be a qdev reset function for the device
(registered via .qdev.reset in the SysBusDeviceInfo).
You'll need to reset the other registers too.

> +    return 0;
> +}
> +
> +static const MemoryRegionOps l2x0_mem_ops = {
> +    .read = l2x0_priv_read,
> +    .write = l2x0_priv_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> + };
> +
> +static int l2x0_priv_init(SysBusDevice *dev)
> +{
> +    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
> +
> +    l2x0_priv_reset(dev);

If you make this a qdev reset function you don't need to
explicitly call it from your init function.

> +
> +    memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
> +    sysbus_init_mmio(dev, &s->iomem);
> +    return 0;
> +}
> +
> +static SysBusDeviceInfo l2x0_info = {
> +    .init = l2x0_priv_init,
> +    .qdev.name = "l2x0",
> +    .qdev.size = sizeof(l2x0_state),
> +    .qdev.vmsd = &vmstate_l2x0,
> +    .qdev.no_user = 1,
> +    .qdev.props = (Property[]) {
> +        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, DEFAULT_CACHE_TYPE),
> +        DEFINE_PROP_END_OF_LIST(),
> +    }
> +};
> +
> +static void l2x0_register_device(void)
> +{
> +    sysbus_register_withprop(&l2x0_info);
> +}
> +
> +device_init(l2x0_register_device)
> +
> --
> 1.7.5.4
>

-- PMM

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

* Re: [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160
  2011-12-22 18:20 ` [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160 Mark Langsdorf
@ 2011-12-24  0:54   ` Rob Herring
  2011-12-24  1:10     ` Peter Maydell
  0 siblings, 1 reply; 21+ messages in thread
From: Rob Herring @ 2011-12-24  0:54 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, peter.maydell, qemu-devel, paul

Mark,

On 12/22/2011 12:20 PM, Mark Langsdorf wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> ---
>  hw/a9mpcore.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index 875ae98..93b0498 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -13,7 +13,7 @@
>  /* Configuration for arm_gic.c:
>   * number of external IRQ lines, max number of CPUs, how to ID current CPU
>   */
> -#define GIC_NIRQ 96
> +#define GIC_NIRQ 160
>  #define NCPU 4

This needs to be run-time. The value gets put in a register and read by
the OS. It breaks platforms expecting 96 irqs.

Rob

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

* Re: [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160
  2011-12-24  0:54   ` Rob Herring
@ 2011-12-24  1:10     ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2011-12-24  1:10 UTC (permalink / raw)
  To: Rob Herring; +Cc: kwolf, qemu-devel, Mark Langsdorf, paul

On 24 December 2011 00:54, Rob Herring <rob.herring@calxeda.com> wrote:
> Mark,
>
> On 12/22/2011 12:20 PM, Mark Langsdorf wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
>> ---
>>  hw/a9mpcore.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
>> index 875ae98..93b0498 100644
>> --- a/hw/a9mpcore.c
>> +++ b/hw/a9mpcore.c
>> @@ -13,7 +13,7 @@
>>  /* Configuration for arm_gic.c:
>>   * number of external IRQ lines, max number of CPUs, how to ID current CPU
>>   */
>> -#define GIC_NIRQ 96
>> +#define GIC_NIRQ 160
>>  #define NCPU 4
>
> This needs to be run-time. The value gets put in a register and read by
> the OS. It breaks platforms expecting 96 irqs.

Also the hardware maximum for the A9 is 256, so bumping the compile
time maximum to only 160 wouldn't make sense. (The GIC architectural
limit is 1020 interrupts.)

FYI: In the long term the place I would like to get to is to have
the GIC be a properly separated out qdev device, rather than a bit
of code which is #included by various different source files which
do this kind of compile-time configuration for it. Having the
private peripheral qdev devices be subclasses of the GIC is also
a bit of a workaround for limitations of our current device object
model which I hope QOM will let us rearrange.

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer
  2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer Mark Langsdorf
  2011-12-24  0:26   ` Peter Maydell
@ 2011-12-24  9:19   ` Andreas Färber
  1 sibling, 0 replies; 21+ messages in thread
From: Andreas Färber @ 2011-12-24  9:19 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: kwolf, peter.maydell, qemu-devel, paul

Am 22.12.2011 19:20, schrieb Mark Langsdorf:
> Use qdev properties to allow board modelers to set the frequencies
> for the sp804 timer. Each of the sp804's timers can have an
> individual frequency. The timers default to 1MHz.
> 
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> ---
> Changes from v1
> 	Simplified multiple timer frequency handling
> 	Removed the shared default
>  hw/arm_timer.c |   26 +++++++++++++++++++++-----
>  1 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/arm_timer.c b/hw/arm_timer.c
> index 0a5b9d2..d2738c7 100644
> --- a/hw/arm_timer.c
> +++ b/hw/arm_timer.c

> @@ -178,6 +180,7 @@ typedef struct {
>      SysBusDevice busdev;
>      MemoryRegion iomem;
>      arm_timer_state *timer[2];
> +    int freq0, freq1;
>      int level[2];
>      qemu_irq irq;
>  } sp804_state;

> @@ -281,6 +287,16 @@ static int sp804_init(SysBusDevice *dev)
>      return 0;
>  }
>  
> +static SysBusDeviceInfo sp804_info = {
> +    .init = sp804_init,
> +    .qdev.name = "sp804",
> +    .qdev.size = sizeof(sp804_state),
> +    .qdev.props = (Property[]) {
> +        DEFINE_PROP_INT32("freq0", sp804_state, freq0, 1000000),
> +        DEFINE_PROP_INT32("freq1", sp804_state, freq1, 1000000),

Since you're using INT32 here, please declare it as int32_t above.
Or uint32_t and UINT32 if there's no negative frequency.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

* [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState
@ 2011-12-20 19:12 Mark Langsdorf
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Langsdorf @ 2011-12-20 19:12 UTC (permalink / raw)
  To: qemu-devel, kwolf

From: Rob Herring <rob.herring@calxeda.com>

Use AHCIState instead of AHCIPCIState so the function can be used for
non-PCI based AHCI controllers.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
  hw/ide/ahci.c |   14 +++++++-------
  hw/ide/ich.c  |    4 ++--
  2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 0af201d..135d0ee 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -336,7 +336,7 @@ static void ahci_mem_write(void *opaque, 
target_phys_addr_t addr,
              case HOST_CTL: /* R/W */
                  if (val & HOST_CTL_RESET) {
                      DPRINTF(-1, "HBA Reset\n");
-                    ahci_reset(container_of(s, AHCIPCIState, ahci));
+                    ahci_reset(s);
                  } else {
                      s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
                      ahci_check_irq(s);
@@ -1199,18 +1199,18 @@ void ahci_uninit(AHCIState *s)

  void ahci_reset(void *opaque)
  {
-    struct AHCIPCIState *d = opaque;
+    struct AHCIState *s = opaque;
      AHCIPortRegs *pr;
      int i;

-    d->ahci.control_regs.irqstatus = 0;
-    d->ahci.control_regs.ghc = 0;
+    s->control_regs.irqstatus = 0;
+    s->control_regs.ghc = 0;

-    for (i = 0; i < d->ahci.ports; i++) {
-        pr = &d->ahci.dev[i].port_regs;
+    for (i = 0; i < s->ports; i++) {
+        pr = &s->dev[i].port_regs;
          pr->irq_stat = 0;
          pr->irq_mask = 0;
          pr->scr_ctl = 0;
-        ahci_reset_port(&d->ahci, i);
+        ahci_reset_port(s, i);
      }
  }
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 3f7510f..44363ec 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -102,7 +102,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
      /* XXX Software should program this register */
      d->card.config[0x90]   = 1 << 6; /* Address Map Register - AHCI 
mode */

-    qemu_register_reset(ahci_reset, d);
+    qemu_register_reset(ahci_reset, &d->ahci);

      msi_init(dev, 0x50, 1, true, false);
      d->ahci.irq = d->card.irq[0];
@@ -133,7 +133,7 @@ static int pci_ich9_uninit(PCIDevice *dev)
      d = DO_UPCAST(struct AHCIPCIState, card, dev);

      msi_uninit(dev);
-    qemu_unregister_reset(ahci_reset, d);
+    qemu_unregister_reset(ahci_reset, &d->ahci);
      ahci_uninit(&d->ahci);

      return 0;
-- 
1.7.5.4

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

end of thread, other threads:[~2011-12-24  9:21 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-22 18:20 [Qemu-devel] [PATCH v2 0/9] various ARM fixes Mark Langsdorf
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 1/9] arm: add missing scu registers Mark Langsdorf
2011-12-24  0:23   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 2/9] arm: Set frequencies for arm_timer Mark Langsdorf
2011-12-24  0:26   ` Peter Maydell
2011-12-24  9:19   ` Andreas Färber
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 3/9] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
2011-12-24  0:30   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 4/9] arm: add dummy gic security registers Mark Langsdorf
2011-12-24  0:32   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState Mark Langsdorf
2011-12-24  0:35   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH 6/9] ahci: add support for non-PCI based controllers Mark Langsdorf
2011-12-24  0:39   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 7/9] add L2x0/PL310 cache controller device Mark Langsdorf
2011-12-24  0:53   ` Peter Maydell
2011-12-22 18:20 ` [Qemu-devel] [PATCH v2 8/9] Add xgmac ethernet model Mark Langsdorf
2011-12-22 18:20 ` [Qemu-devel] [PATCH 9/9] arm: increase a9mp interrupts to 160 Mark Langsdorf
2011-12-24  0:54   ` Rob Herring
2011-12-24  1:10     ` Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2011-12-20 19:12 [Qemu-devel] [PATCH 5/9] ahci: convert ahci_reset to use AHCIState Mark Langsdorf

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.