* [Qemu-devel] [PULL 0/8] arm-devs queue
@ 2011-12-12 10:47 Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 1/8] Fix sp804 dual-timer Peter Maydell
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
The following changes since commit f18318eef8b4b263f4e82a5338c9b2875a6c73c8:
Merge branch 'master' of git://git.qemu.org/qemu (2011-12-12 04:12:31 +0400)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git arm-devs.for-upstream
Peter Chubb (1):
Fix sp804 dual-timer
Peter Maydell (7):
hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices
hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions
hw/mpcore.c: Use the GIC memory regions for the CPU interface
hw/realview_gic: Use GIC memory region for the CPU interface
hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only
hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones
hw/mpcore.c: Merge with hw/arm11mpcore.c
Makefile.target | 1 +
hw/a9mpcore.c | 189 ++++++++++++++++++++++++++++--
hw/arm11mpcore.c | 130 +++++++++++++++++++++-
hw/arm_gic.c | 75 ++++++++++++-
hw/arm_mptimer.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/arm_timer.c | 41 ++++++-
hw/mpcore.c | 283 ---------------------------------------------
hw/realview_gic.c | 25 +----
8 files changed, 751 insertions(+), 325 deletions(-)
create mode 100644 hw/arm_mptimer.c
delete mode 100644 hw/mpcore.c
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 1/8] Fix sp804 dual-timer
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 2/8] hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices Peter Maydell
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
From: Peter Chubb <peter.chubb@nicta.com.au>
Properly implement dual-timer read/write for the sp804 dual timer module.
Based on ARM specs at
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html
Signed-off-by: Hans Jang <hsjang@ok-labs.com>
Signed-off-by: David Mirabito <david.mirabito@nicta.com.au>
Signed-off-by: Peter Chubb <peter.chubb@nicta.com.au>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_timer.c | 41 +++++++++++++++++++++++++++++++++++------
1 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 518bad2..0a5b9d2 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -170,9 +170,9 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
}
/* ARM PrimeCell SP804 dual timer module.
- Docs for this device don't seem to be publicly available. This
- implementation is based on guesswork, the linux kernel sources and the
- Integrator/CP timer modules. */
+ * Docs at
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html
+*/
typedef struct {
SysBusDevice busdev;
@@ -182,6 +182,13 @@ typedef struct {
qemu_irq irq;
} sp804_state;
+static const uint8_t sp804_ids[] = {
+ /* Timer ID */
+ 0x04, 0x18, 0x14, 0,
+ /* PrimeCell ID */
+ 0xd, 0xf0, 0x05, 0xb1
+};
+
/* Merge the IRQs from the two component devices. */
static void sp804_set_irq(void *opaque, int irq, int level)
{
@@ -196,12 +203,27 @@ static uint64_t sp804_read(void *opaque, target_phys_addr_t offset,
{
sp804_state *s = (sp804_state *)opaque;
- /* ??? Don't know the PrimeCell ID for this device. */
if (offset < 0x20) {
return arm_timer_read(s->timer[0], offset);
- } else {
+ }
+ if (offset < 0x40) {
return arm_timer_read(s->timer[1], offset - 0x20);
}
+
+ /* TimerPeriphID */
+ if (offset >= 0xfe0 && offset <= 0xffc) {
+ return sp804_ids[(offset - 0xfe0) >> 2];
+ }
+
+ switch (offset) {
+ /* Integration Test control registers, which we won't support */
+ case 0xf00: /* TimerITCR */
+ case 0xf04: /* TimerITOP (strictly write only but..) */
+ return 0;
+ }
+
+ hw_error("%s: Bad offset %x\n", __func__, (int)offset);
+ return 0;
}
static void sp804_write(void *opaque, target_phys_addr_t offset,
@@ -211,9 +233,16 @@ static void sp804_write(void *opaque, target_phys_addr_t offset,
if (offset < 0x20) {
arm_timer_write(s->timer[0], offset, value);
- } else {
+ return;
+ }
+
+ if (offset < 0x40) {
arm_timer_write(s->timer[1], offset - 0x20, value);
+ return;
}
+
+ /* Technically we could be writing to the Test Registers, but not likely */
+ hw_error("%s: Bad offset %x\n", __func__, (int)offset);
}
static const MemoryRegionOps sp804_ops = {
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 2/8] hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 1/8] Fix sp804 dual-timer Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 3/8] hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions Peter Maydell
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Turn the ARM MPcore private timer/watchdog blocks into separate
qdev devices. This will allow us to share them neatly between
11MPCore and A9MPcore.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Makefile.target | 1 +
hw/arm_mptimer.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/mpcore.c | 184 +++++-------------------------
3 files changed, 365 insertions(+), 152 deletions(-)
create mode 100644 hw/arm_mptimer.c
diff --git a/Makefile.target b/Makefile.target
index a111521..39b2e5a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -344,6 +344,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_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 += arm-semi.o
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
new file mode 100644
index 0000000..455a0aa
--- /dev/null
+++ b/hw/arm_mptimer.c
@@ -0,0 +1,332 @@
+/*
+ * Private peripheral timer/watchdog blocks for ARM 11MPCore and A9MP
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2011 Linaro Limited
+ * Written by Paul Brook, Peter Maydell
+ *
+ * This program 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.
+ *
+ * This program is distributed in the hope that 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"
+#include "qemu-timer.h"
+
+/* This device implements the per-cpu private timer and watchdog block
+ * which is used in both the ARM11MPCore and Cortex-A9MP.
+ */
+
+#define MAX_CPUS 4
+
+/* State of a single timer or watchdog block */
+typedef struct {
+ uint32_t count;
+ uint32_t load;
+ uint32_t control;
+ uint32_t status;
+ int64_t tick;
+ QEMUTimer *timer;
+ qemu_irq irq;
+ MemoryRegion iomem;
+} timerblock;
+
+typedef struct {
+ SysBusDevice busdev;
+ uint32_t num_cpu;
+ timerblock timerblock[MAX_CPUS * 2];
+ MemoryRegion iomem[2];
+} arm_mptimer_state;
+
+static inline int get_current_cpu(arm_mptimer_state *s)
+{
+ if (cpu_single_env->cpu_index >= s->num_cpu) {
+ hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
+ s->num_cpu, cpu_single_env->cpu_index);
+ }
+ return cpu_single_env->cpu_index;
+}
+
+static inline void timerblock_update_irq(timerblock *tb)
+{
+ qemu_set_irq(tb->irq, tb->status);
+}
+
+/* Return conversion factor from mpcore timer ticks to qemu timer ticks. */
+static inline uint32_t timerblock_scale(timerblock *tb)
+{
+ return (((tb->control >> 8) & 0xff) + 1) * 10;
+}
+
+static void timerblock_reload(timerblock *tb, int restart)
+{
+ if (tb->count == 0) {
+ return;
+ }
+ if (restart) {
+ tb->tick = qemu_get_clock_ns(vm_clock);
+ }
+ tb->tick += (int64_t)tb->count * timerblock_scale(tb);
+ qemu_mod_timer(tb->timer, tb->tick);
+}
+
+static void timerblock_tick(void *opaque)
+{
+ timerblock *tb = (timerblock *)opaque;
+ tb->status = 1;
+ if (tb->control & 2) {
+ tb->count = tb->load;
+ timerblock_reload(tb, 0);
+ } else {
+ tb->count = 0;
+ }
+ timerblock_update_irq(tb);
+}
+
+static uint64_t timerblock_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ timerblock *tb = (timerblock *)opaque;
+ int64_t val;
+ addr &= 0x1f;
+ switch (addr) {
+ case 0: /* Load */
+ return tb->load;
+ case 4: /* Counter. */
+ if (((tb->control & 1) == 0) || (tb->count == 0)) {
+ return 0;
+ }
+ /* Slow and ugly, but hopefully won't happen too often. */
+ val = tb->tick - qemu_get_clock_ns(vm_clock);
+ val /= timerblock_scale(tb);
+ if (val < 0) {
+ val = 0;
+ }
+ return val;
+ case 8: /* Control. */
+ return tb->control;
+ case 12: /* Interrupt status. */
+ return tb->status;
+ default:
+ return 0;
+ }
+}
+
+static void timerblock_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ timerblock *tb = (timerblock *)opaque;
+ int64_t old;
+ addr &= 0x1f;
+ switch (addr) {
+ case 0: /* Load */
+ tb->load = value;
+ /* Fall through. */
+ case 4: /* Counter. */
+ if ((tb->control & 1) && tb->count) {
+ /* Cancel the previous timer. */
+ qemu_del_timer(tb->timer);
+ }
+ tb->count = value;
+ if (tb->control & 1) {
+ timerblock_reload(tb, 1);
+ }
+ break;
+ case 8: /* Control. */
+ old = tb->control;
+ tb->control = value;
+ if (((old & 1) == 0) && (value & 1)) {
+ if (tb->count == 0 && (tb->control & 2)) {
+ tb->count = tb->load;
+ }
+ timerblock_reload(tb, 1);
+ }
+ break;
+ case 12: /* Interrupt status. */
+ tb->status &= ~value;
+ timerblock_update_irq(tb);
+ break;
+ }
+}
+
+/* Wrapper functions to implement the "read timer/watchdog for
+ * the current CPU" memory regions.
+ */
+static uint64_t arm_thistimer_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ arm_mptimer_state *s = (arm_mptimer_state *)opaque;
+ int id = get_current_cpu(s);
+ return timerblock_read(&s->timerblock[id * 2], addr, size);
+}
+
+static void arm_thistimer_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ arm_mptimer_state *s = (arm_mptimer_state *)opaque;
+ int id = get_current_cpu(s);
+ timerblock_write(&s->timerblock[id * 2], addr, value, size);
+}
+
+static uint64_t arm_thiswdog_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ arm_mptimer_state *s = (arm_mptimer_state *)opaque;
+ int id = get_current_cpu(s);
+ return timerblock_read(&s->timerblock[id * 2 + 1], addr, size);
+}
+
+static void arm_thiswdog_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ arm_mptimer_state *s = (arm_mptimer_state *)opaque;
+ int id = get_current_cpu(s);
+ timerblock_write(&s->timerblock[id * 2 + 1], addr, value, size);
+}
+
+static const MemoryRegionOps arm_thistimer_ops = {
+ .read = arm_thistimer_read,
+ .write = arm_thistimer_write,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const MemoryRegionOps arm_thiswdog_ops = {
+ .read = arm_thiswdog_read,
+ .write = arm_thiswdog_write,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const MemoryRegionOps timerblock_ops = {
+ .read = timerblock_read,
+ .write = timerblock_write,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void timerblock_reset(timerblock *tb)
+{
+ tb->count = 0;
+ tb->load = 0;
+ tb->control = 0;
+ tb->status = 0;
+ tb->tick = 0;
+}
+
+static void arm_mptimer_reset(DeviceState *dev)
+{
+ arm_mptimer_state *s =
+ FROM_SYSBUS(arm_mptimer_state, sysbus_from_qdev(dev));
+ int i;
+ /* We reset every timer in the array, not just the ones we're using,
+ * because vmsave will look at every array element.
+ */
+ for (i = 0; i < ARRAY_SIZE(s->timerblock); i++) {
+ timerblock_reset(&s->timerblock[i]);
+ }
+}
+
+static int arm_mptimer_init(SysBusDevice *dev)
+{
+ arm_mptimer_state *s = FROM_SYSBUS(arm_mptimer_state, dev);
+ int i;
+ if (s->num_cpu < 1 || s->num_cpu > MAX_CPUS) {
+ hw_error("%s: num-cpu must be between 1 and %d\n", __func__, MAX_CPUS);
+ }
+ /* We implement one timer and one watchdog block per CPU, and
+ * expose multiple MMIO regions:
+ * * region 0 is "timer for this core"
+ * * region 1 is "watchdog for this core"
+ * * region 2 is "timer for core 0"
+ * * region 3 is "watchdog for core 0"
+ * * region 4 is "timer for core 1"
+ * * region 5 is "watchdog for core 1"
+ * and so on.
+ * The outgoing interrupt lines are
+ * * timer for core 0
+ * * watchdog for core 0
+ * * timer for core 1
+ * * watchdog for core 1
+ * and so on.
+ */
+ memory_region_init_io(&s->iomem[0], &arm_thistimer_ops, s,
+ "arm_mptimer_timer", 0x20);
+ sysbus_init_mmio(dev, &s->iomem[0]);
+ memory_region_init_io(&s->iomem[1], &arm_thiswdog_ops, s,
+ "arm_mptimer_wdog", 0x20);
+ sysbus_init_mmio(dev, &s->iomem[1]);
+ for (i = 0; i < (s->num_cpu * 2); i++) {
+ timerblock *tb = &s->timerblock[i];
+ tb->timer = qemu_new_timer_ns(vm_clock, timerblock_tick, tb);
+ sysbus_init_irq(dev, &tb->irq);
+ memory_region_init_io(&tb->iomem, &timerblock_ops, tb,
+ "arm_mptimer_timerblock", 0x20);
+ sysbus_init_mmio(dev, &tb->iomem);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_timerblock = {
+ .name = "arm_mptimer_timerblock",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(count, timerblock),
+ VMSTATE_UINT32(load, timerblock),
+ VMSTATE_UINT32(control, timerblock),
+ VMSTATE_UINT32(status, timerblock),
+ VMSTATE_INT64(tick, timerblock),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_arm_mptimer = {
+ .name = "arm_mptimer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_ARRAY(timerblock, arm_mptimer_state, (MAX_CPUS * 2),
+ 1, vmstate_timerblock, timerblock),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static SysBusDeviceInfo arm_mptimer_info = {
+ .init = arm_mptimer_init,
+ .qdev.name = "arm_mptimer",
+ .qdev.size = sizeof(arm_mptimer_state),
+ .qdev.vmsd = &vmstate_arm_mptimer,
+ .qdev.reset = arm_mptimer_reset,
+ .qdev.no_user = 1,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_UINT32("num-cpu", arm_mptimer_state, num_cpu, 0),
+ DEFINE_PROP_END_OF_LIST()
+ }
+};
+
+static void arm_mptimer_register_devices(void)
+{
+ sysbus_register_withprop(&arm_mptimer_info);
+}
+
+device_init(arm_mptimer_register_devices)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index 4357d12..3d64609 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -22,135 +22,18 @@ gic_get_current_cpu(void)
/* MPCore private memory region. */
-typedef struct {
- uint32_t count;
- uint32_t load;
- uint32_t control;
- uint32_t status;
- uint32_t old_status;
- int64_t tick;
- QEMUTimer *timer;
- struct mpcore_priv_state *mpcore;
- int id; /* Encodes both timer/watchdog and CPU. */
-} mpcore_timer_state;
-
typedef struct mpcore_priv_state {
gic_state gic;
uint32_t scu_control;
int iomemtype;
- mpcore_timer_state timer[8];
+ uint32_t old_timer_status[8];
uint32_t num_cpu;
+ qemu_irq *timer_irq;
MemoryRegion iomem;
MemoryRegion container;
+ DeviceState *mptimer;
} mpcore_priv_state;
-/* Per-CPU Timers. */
-
-static inline void mpcore_timer_update_irq(mpcore_timer_state *s)
-{
- if (s->status & ~s->old_status) {
- gic_set_pending_private(&s->mpcore->gic, s->id >> 1, 29 + (s->id & 1));
- }
- s->old_status = s->status;
-}
-
-/* Return conversion factor from mpcore timer ticks to qemu timer ticks. */
-static inline uint32_t mpcore_timer_scale(mpcore_timer_state *s)
-{
- return (((s->control >> 8) & 0xff) + 1) * 10;
-}
-
-static void mpcore_timer_reload(mpcore_timer_state *s, int restart)
-{
- if (s->count == 0)
- return;
- if (restart)
- s->tick = qemu_get_clock_ns(vm_clock);
- s->tick += (int64_t)s->count * mpcore_timer_scale(s);
- qemu_mod_timer(s->timer, s->tick);
-}
-
-static void mpcore_timer_tick(void *opaque)
-{
- mpcore_timer_state *s = (mpcore_timer_state *)opaque;
- s->status = 1;
- if (s->control & 2) {
- s->count = s->load;
- mpcore_timer_reload(s, 0);
- } else {
- s->count = 0;
- }
- mpcore_timer_update_irq(s);
-}
-
-static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset)
-{
- int64_t val;
- switch (offset) {
- case 0: /* Load */
- return s->load;
- /* Fall through. */
- case 4: /* Counter. */
- if (((s->control & 1) == 0) || (s->count == 0))
- return 0;
- /* Slow and ugly, but hopefully won't happen too often. */
- val = s->tick - qemu_get_clock_ns(vm_clock);
- val /= mpcore_timer_scale(s);
- if (val < 0)
- val = 0;
- return val;
- case 8: /* Control. */
- return s->control;
- case 12: /* Interrupt status. */
- return s->status;
- default:
- return 0;
- }
-}
-
-static void mpcore_timer_write(mpcore_timer_state *s, int offset,
- uint32_t value)
-{
- int64_t old;
- switch (offset) {
- case 0: /* Load */
- s->load = value;
- /* Fall through. */
- case 4: /* Counter. */
- if ((s->control & 1) && s->count) {
- /* Cancel the previous timer. */
- qemu_del_timer(s->timer);
- }
- s->count = value;
- if (s->control & 1) {
- mpcore_timer_reload(s, 1);
- }
- break;
- case 8: /* Control. */
- old = s->control;
- s->control = value;
- if (((old & 1) == 0) && (value & 1)) {
- if (s->count == 0 && (s->control & 2))
- s->count = s->load;
- mpcore_timer_reload(s, 1);
- }
- break;
- case 12: /* Interrupt status. */
- s->status &= ~value;
- mpcore_timer_update_irq(s);
- break;
- }
-}
-
-static void mpcore_timer_init(mpcore_priv_state *mpcore,
- mpcore_timer_state *s, int id)
-{
- s->id = id;
- s->mpcore = mpcore;
- s->timer = qemu_new_timer_ns(vm_clock, mpcore_timer_tick, s);
-}
-
-
/* Per-CPU private memory mapped IO. */
static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
@@ -185,20 +68,6 @@ static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
}
}
return gic_cpu_read(&s->gic, id, offset & 0xff);
- } else if (offset < 0xb00) {
- /* Timers. */
- if (offset < 0x700) {
- id = gic_get_current_cpu();
- } else {
- id = (offset - 0x700) >> 8;
- if (id >= s->num_cpu) {
- return 0;
- }
- }
- id <<= 1;
- if (offset & 0x20)
- id++;
- return mpcore_timer_read(&s->timer[id], offset & 0xf);
}
bad_reg:
hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
@@ -233,20 +102,6 @@ static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
if (id < s->num_cpu) {
gic_cpu_write(&s->gic, id, offset & 0xff, value);
}
- } else if (offset < 0xb00) {
- /* Timers. */
- if (offset < 0x700) {
- id = gic_get_current_cpu();
- } else {
- id = (offset - 0x700) >> 8;
- }
- if (id < s->num_cpu) {
- id <<= 1;
- if (offset & 0x20)
- id++;
- mpcore_timer_write(&s->timer[id], offset & 0xf, value);
- }
- return;
}
return;
bad_reg:
@@ -259,25 +114,50 @@ static const MemoryRegionOps mpcore_priv_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static void mpcore_timer_irq_handler(void *opaque, int irq, int level)
+{
+ mpcore_priv_state *s = (mpcore_priv_state *)opaque;
+ if (level && !s->old_timer_status[irq]) {
+ gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
+ }
+ s->old_timer_status[irq] = level;
+}
+
static void mpcore_priv_map_setup(mpcore_priv_state *s)
{
+ int i;
+ SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv",
0x1000);
memory_region_add_subregion(&s->container, 0, &s->iomem);
+ /* Add the regions for timer and watchdog for "current CPU" and
+ * for each specific CPU.
+ */
+ s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler,
+ s, (s->num_cpu + 1) * 2);
+ for (i = 0; i < (s->num_cpu + 1) * 2; i++) {
+ /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
+ target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20;
+ memory_region_add_subregion(&s->container, offset,
+ sysbus_mmio_get_region(busdev, i));
+ }
memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+ /* Wire up the interrupt from each watchdog and timer. */
+ for (i = 0; i < s->num_cpu * 2; i++) {
+ sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+ }
}
static int mpcore_priv_init(SysBusDevice *dev)
{
mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
- int i;
gic_init(&s->gic, s->num_cpu);
+ s->mptimer = qdev_create(NULL, "arm_mptimer");
+ qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
+ qdev_init_nofail(s->mptimer);
mpcore_priv_map_setup(s);
sysbus_init_mmio(dev, &s->container);
- for (i = 0; i < s->num_cpu * 2; i++) {
- mpcore_timer_init(s, &s->timer[i], i);
- }
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 3/8] hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 1/8] Fix sp804 dual-timer Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 2/8] hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 4/8] hw/mpcore.c: Use the GIC memory regions for the CPU interface Peter Maydell
` (5 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Expose the ARM GIC CPU interfaces as memory regions, rather than
just providing read and write functions for them.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 527c9ce..66c48fd 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -103,7 +103,14 @@ typedef struct gic_state
int num_cpu;
#endif
- MemoryRegion iomem;
+ MemoryRegion iomem; /* Distributor */
+#ifndef NVIC
+ /* This is just so we can have an opaque pointer which identifies
+ * both this GIC and which CPU interface we should be accessing.
+ */
+ struct gic_state *backref[NCPU];
+ MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
+#endif
} gic_state;
/* TODO: Many places that call this routine could be optimized. */
@@ -633,6 +640,54 @@ static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
}
gic_update(s);
}
+
+/* Wrappers to read/write the GIC CPU interface for the current CPU */
+static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ gic_state *s = (gic_state *)opaque;
+ return gic_cpu_read(s, gic_get_current_cpu(), addr & 0xff);
+}
+
+static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ gic_state *s = (gic_state *)opaque;
+ gic_cpu_write(s, gic_get_current_cpu(), addr & 0xff, value);
+}
+
+/* Wrappers to read/write the GIC CPU interface for a specific CPU.
+ * These just decode the opaque pointer into gic_state* + cpu id.
+ */
+static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ gic_state **backref = (gic_state **)opaque;
+ gic_state *s = *backref;
+ int id = (backref - s->backref);
+ return gic_cpu_read(s, id, addr & 0xff);
+}
+
+static void gic_do_cpu_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
+{
+ gic_state **backref = (gic_state **)opaque;
+ gic_state *s = *backref;
+ int id = (backref - s->backref);
+ gic_cpu_write(s, id, addr & 0xff, value);
+}
+
+static const MemoryRegionOps gic_thiscpu_ops = {
+ .read = gic_thiscpu_read,
+ .write = gic_thiscpu_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const MemoryRegionOps gic_cpu_ops = {
+ .read = gic_do_cpu_read,
+ .write = gic_do_cpu_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
#endif
static void gic_reset(gic_state *s)
@@ -752,6 +807,24 @@ static void gic_init(gic_state *s)
sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
}
memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
+#ifndef NVIC
+ /* Memory regions for the CPU interfaces (NVIC doesn't have these):
+ * a region for "CPU interface for this core", then a region for
+ * "CPU interface for core 0", "for core 1", ...
+ * NB that the memory region size of 0x100 applies for the 11MPCore
+ * and also cores following the GIC v1 spec (ie A9).
+ * GIC v2 defines a larger memory region (0x1000) so this will need
+ * to be extended when we implement A15.
+ */
+ memory_region_init_io(&s->cpuiomem[0], &gic_thiscpu_ops, s,
+ "gic_cpu", 0x100);
+ for (i = 0; i < NUM_CPU(s); i++) {
+ s->backref[i] = s;
+ memory_region_init_io(&s->cpuiomem[i+1], &gic_cpu_ops, &s->backref[i],
+ "gic_cpu", 0x100);
+ }
+#endif
+
gic_reset(s);
register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 4/8] hw/mpcore.c: Use the GIC memory regions for the CPU interface
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (2 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 3/8] hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 5/8] hw/realview_gic: Use GIC memory region " Peter Maydell
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Switch to using the GIC memory regions for the CPU interface
rather than hand implementing them as a subcase of mpcore_priv_read()
and mpcore_priv_write().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/mpcore.c | 35 ++++++++++-------------------------
1 files changed, 10 insertions(+), 25 deletions(-)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index 3d64609..a0af1ad 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -41,7 +41,7 @@ static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
int id;
- offset &= 0xfff;
+ offset &= 0xff;
if (offset < 0x100) {
/* SCU */
switch (offset) {
@@ -57,17 +57,6 @@ static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
default:
goto bad_reg;
}
- } else if (offset < 0x600) {
- /* Interrupt controller. */
- if (offset < 0x200) {
- id = gic_get_current_cpu();
- } else {
- id = (offset - 0x200) >> 8;
- if (id >= s->num_cpu) {
- return 0;
- }
- }
- return gic_cpu_read(&s->gic, id, offset & 0xff);
}
bad_reg:
hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
@@ -78,8 +67,7 @@ static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
uint64_t value, unsigned size)
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
- int id;
- offset &= 0xfff;
+ offset &= 0xff;
if (offset < 0x100) {
/* SCU */
switch (offset) {
@@ -92,16 +80,6 @@ static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
default:
goto bad_reg;
}
- } else if (offset < 0x600) {
- /* Interrupt controller. */
- if (offset < 0x200) {
- id = gic_get_current_cpu();
- } else {
- id = (offset - 0x200) >> 8;
- }
- if (id < s->num_cpu) {
- gic_cpu_write(&s->gic, id, offset & 0xff, value);
- }
}
return;
bad_reg:
@@ -129,8 +107,15 @@ static void mpcore_priv_map_setup(mpcore_priv_state *s)
SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv",
- 0x1000);
+ 0x100);
memory_region_add_subregion(&s->container, 0, &s->iomem);
+ /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
+ * at 0x200, 0x300...
+ */
+ for (i = 0; i < (s->num_cpu + 1); i++) {
+ target_phys_addr_t offset = 0x100 + (i * 0x100);
+ memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]);
+ }
/* Add the regions for timer and watchdog for "current CPU" and
* for each specific CPU.
*/
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 5/8] hw/realview_gic: Use GIC memory region for the CPU interface
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (3 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 4/8] hw/mpcore.c: Use the GIC memory regions for the CPU interface Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 6/8] hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only Peter Maydell
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Use the GIC provided memory region for the CPU interface rather
than implementing our own.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/realview_gic.c | 25 +------------------------
1 files changed, 1 insertions(+), 24 deletions(-)
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 479f939..8c4d509 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -23,36 +23,13 @@ gic_get_current_cpu(void)
typedef struct {
gic_state gic;
- MemoryRegion iomem;
MemoryRegion container;
} RealViewGICState;
-static uint64_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset,
- unsigned size)
-{
- gic_state *s = (gic_state *)opaque;
- return gic_cpu_read(s, gic_get_current_cpu(), offset);
-}
-
-static void realview_gic_cpu_write(void *opaque, target_phys_addr_t offset,
- uint64_t value, unsigned size)
-{
- gic_state *s = (gic_state *)opaque;
- gic_cpu_write(s, gic_get_current_cpu(), offset, value);
-}
-
-static const MemoryRegionOps realview_gic_cpu_ops = {
- .read = realview_gic_cpu_read,
- .write = realview_gic_cpu_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
static void realview_gic_map_setup(RealViewGICState *s)
{
memory_region_init(&s->container, "realview-gic-container", 0x2000);
- memory_region_init_io(&s->iomem, &realview_gic_cpu_ops, &s->gic,
- "realview-gic", 0x1000);
- memory_region_add_subregion(&s->container, 0, &s->iomem);
+ memory_region_add_subregion(&s->container, 0, &s->gic.cpuiomem[0]);
memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 6/8] hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (4 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 5/8] hw/realview_gic: Use GIC memory region " Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 7/8] hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones Peter Maydell
` (2 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
The only code left in mpcore_priv_read and mpcore_priv_write is now
the implementation of the SCU registers. Clean up by renaming functions
and removing some unnecessary conditionals to make this clearer.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/mpcore.c | 73 +++++++++++++++++++++++++----------------------------------
1 files changed, 31 insertions(+), 42 deletions(-)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index a0af1ad..670d7e5 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -36,59 +36,49 @@ typedef struct mpcore_priv_state {
/* Per-CPU private memory mapped IO. */
-static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
- unsigned size)
+static uint64_t mpcore_scu_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
int id;
offset &= 0xff;
- if (offset < 0x100) {
- /* SCU */
- switch (offset) {
- case 0x00: /* Control. */
- return s->scu_control;
- case 0x04: /* Configuration. */
- id = ((1 << s->num_cpu) - 1) << 4;
- return id | (s->num_cpu - 1);
- case 0x08: /* CPU status. */
- return 0;
- case 0x0c: /* Invalidate all. */
- return 0;
- default:
- goto bad_reg;
- }
+ /* SCU */
+ switch (offset) {
+ case 0x00: /* Control. */
+ return s->scu_control;
+ case 0x04: /* Configuration. */
+ id = ((1 << s->num_cpu) - 1) << 4;
+ return id | (s->num_cpu - 1);
+ case 0x08: /* CPU status. */
+ return 0;
+ case 0x0c: /* Invalidate all. */
+ return 0;
+ default:
+ hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
}
-bad_reg:
- hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
- return 0;
}
-static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
- uint64_t value, unsigned size)
+static void mpcore_scu_write(void *opaque, target_phys_addr_t offset,
+ uint64_t value, unsigned size)
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
offset &= 0xff;
- if (offset < 0x100) {
- /* SCU */
- switch (offset) {
- case 0: /* Control register. */
- s->scu_control = value & 1;
- break;
- case 0x0c: /* Invalidate all. */
- /* This is a no-op as cache is not emulated. */
- break;
- default:
- goto bad_reg;
- }
+ /* SCU */
+ switch (offset) {
+ case 0: /* Control register. */
+ s->scu_control = value & 1;
+ break;
+ case 0x0c: /* Invalidate all. */
+ /* This is a no-op as cache is not emulated. */
+ break;
+ default:
+ hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
}
- return;
-bad_reg:
- hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
}
-static const MemoryRegionOps mpcore_priv_ops = {
- .read = mpcore_priv_read,
- .write = mpcore_priv_write,
+static const MemoryRegionOps mpcore_scu_ops = {
+ .read = mpcore_scu_read,
+ .write = mpcore_scu_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
@@ -106,8 +96,7 @@ static void mpcore_priv_map_setup(mpcore_priv_state *s)
int i;
SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
- memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv",
- 0x100);
+ memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100);
memory_region_add_subregion(&s->container, 0, &s->iomem);
/* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
* at 0x200, 0x300...
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 7/8] hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (5 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 6/8] hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 8/8] hw/mpcore.c: Merge with hw/arm11mpcore.c Peter Maydell
2011-12-12 16:34 ` [Qemu-devel] [PULL 0/8] arm-devs queue Anthony Liguori
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Implement the A9MP private peripheral region correctly, rather
than piggybacking on the 11MPCore code; the two CPUs are not the
same in this area.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/a9mpcore.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 179 insertions(+), 10 deletions(-)
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 6f108f4..cd2985f 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -2,28 +2,197 @@
* Cortex-A9MPCore internal peripheral emulation.
*
* Copyright (c) 2009 CodeSourcery.
- * Written by Paul Brook
+ * Copyright (c) 2011 Linaro Limited.
+ * Written by Paul Brook, Peter Maydell.
*
* This code is licensed under the GPL.
*/
-/* 64 external IRQ lines. */
+#include "sysbus.h"
+
+/* Configuration for arm_gic.c:
+ * number of external IRQ lines, max number of CPUs, how to ID current CPU
+ */
#define GIC_NIRQ 96
-#include "mpcore.c"
+#define NCPU 4
+
+static inline int
+gic_get_current_cpu(void)
+{
+ return cpu_single_env->cpu_index;
+}
+
+#include "arm_gic.c"
+
+/* A9MP private memory region. */
+
+typedef struct a9mp_priv_state {
+ gic_state gic;
+ uint32_t scu_control;
+ uint32_t old_timer_status[8];
+ uint32_t num_cpu;
+ qemu_irq *timer_irq;
+ MemoryRegion scu_iomem;
+ MemoryRegion ptimer_iomem;
+ MemoryRegion container;
+ DeviceState *mptimer;
+} a9mp_priv_state;
+
+static uint64_t a9_scu_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
+{
+ a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+ switch (offset) {
+ case 0x00: /* Control */
+ return s->scu_control;
+ case 0x04: /* Configuration */
+ return (((1 << s->num_cpu) - 1) << 4) | (s->num_cpu - 1);
+ case 0x08: /* CPU Power Status */
+ return 0;
+ case 0x0c: /* Invalidate All Registers In Secure State */
+ return 0;
+ case 0x40: /* Filtering Start Address Register */
+ case 0x44: /* Filtering End Address Register */
+ /* RAZ/WI, like an implementation with only one AXI master */
+ return 0;
+ case 0x50: /* SCU Access Control Register */
+ case 0x54: /* SCU Non-secure Access Control Register */
+ /* unimplemented, fall through */
+ default:
+ return 0;
+ }
+}
+
+static void a9_scu_write(void *opaque, target_phys_addr_t offset,
+ uint64_t value, unsigned size)
+{
+ a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+ switch (offset) {
+ case 0x00: /* Control */
+ s->scu_control = value & 1;
+ break;
+ case 0x4: /* Configuration: RO */
+ break;
+ case 0x0c: /* Invalidate All Registers In Secure State */
+ /* no-op as we do not implement caches */
+ break;
+ case 0x40: /* Filtering Start Address Register */
+ 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 */
+ default:
+ break;
+ }
+}
+
+static const MemoryRegionOps a9_scu_ops = {
+ .read = a9_scu_read,
+ .write = a9_scu_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void a9mpcore_timer_irq_handler(void *opaque, int irq, int level)
+{
+ a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+ if (level && !s->old_timer_status[irq]) {
+ gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
+ }
+ s->old_timer_status[irq] = level;
+}
+
+static void a9mp_priv_reset(DeviceState *dev)
+{
+ a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, sysbus_from_qdev(dev));
+ int i;
+ s->scu_control = 0;
+ for (i = 0; i < ARRAY_SIZE(s->old_timer_status); i++) {
+ s->old_timer_status[i] = 0;
+ }
+}
+
+static int a9mp_priv_init(SysBusDevice *dev)
+{
+ a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, dev);
+ SysBusDevice *busdev;
+ int i;
+
+ if (s->num_cpu > NCPU) {
+ hw_error("a9mp_priv_init: num-cpu may not be more than %d\n", NCPU);
+ }
+
+ gic_init(&s->gic, s->num_cpu);
+
+ s->mptimer = qdev_create(NULL, "arm_mptimer");
+ qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
+ qdev_init_nofail(s->mptimer);
+ busdev = sysbus_from_qdev(s->mptimer);
+
+ /* Memory map (addresses are offsets from PERIPHBASE):
+ * 0x0000-0x00ff -- Snoop Control Unit
+ * 0x0100-0x01ff -- GIC CPU interface
+ * 0x0200-0x02ff -- Global Timer
+ * 0x0300-0x05ff -- nothing
+ * 0x0600-0x06ff -- private timers and watchdogs
+ * 0x0700-0x0fff -- nothing
+ * 0x1000-0x1fff -- GIC Distributor
+ *
+ * We should implement the global timer but don't currently do so.
+ */
+ memory_region_init(&s->container, "a9mp-priv-container", 0x2000);
+ memory_region_init_io(&s->scu_iomem, &a9_scu_ops, s, "a9mp-scu", 0x100);
+ memory_region_add_subregion(&s->container, 0, &s->scu_iomem);
+ /* GIC CPU interface */
+ memory_region_add_subregion(&s->container, 0x100, &s->gic.cpuiomem[0]);
+ /* Note that the A9 exposes only the "timer/watchdog for this core"
+ * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
+ */
+ memory_region_add_subregion(&s->container, 0x600,
+ sysbus_mmio_get_region(busdev, 0));
+ memory_region_add_subregion(&s->container, 0x620,
+ sysbus_mmio_get_region(busdev, 1));
+ memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+
+ sysbus_init_mmio(dev, &s->container);
+
+ /* Wire up the interrupt from each watchdog and timer. */
+ s->timer_irq = qemu_allocate_irqs(a9mpcore_timer_irq_handler,
+ s, (s->num_cpu + 1) * 2);
+ for (i = 0; i < s->num_cpu * 2; i++) {
+ sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+ }
+ return 0;
+}
+
+static const VMStateDescription vmstate_a9mp_priv = {
+ .name = "a9mpcore_priv",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(scu_control, a9mp_priv_state),
+ VMSTATE_UINT32_ARRAY(old_timer_status, a9mp_priv_state, 8),
+ VMSTATE_END_OF_LIST()
+ }
+};
-static SysBusDeviceInfo mpcore_priv_info = {
- .init = mpcore_priv_init,
+static SysBusDeviceInfo a9mp_priv_info = {
+ .init = a9mp_priv_init,
.qdev.name = "a9mpcore_priv",
- .qdev.size = sizeof(mpcore_priv_state),
+ .qdev.size = sizeof(a9mp_priv_state),
+ .qdev.vmsd = &vmstate_a9mp_priv,
+ .qdev.reset = a9mp_priv_reset,
.qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
+ DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
DEFINE_PROP_END_OF_LIST(),
}
};
-static void a9mpcore_register_devices(void)
+static void a9mp_register_devices(void)
{
- sysbus_register_withprop(&mpcore_priv_info);
+ sysbus_register_withprop(&a9mp_priv_info);
}
-device_init(a9mpcore_register_devices)
+device_init(a9mp_register_devices)
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 8/8] hw/mpcore.c: Merge with hw/arm11mpcore.c
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (6 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 7/8] hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones Peter Maydell
@ 2011-12-12 10:47 ` Peter Maydell
2011-12-12 16:34 ` [Qemu-devel] [PULL 0/8] arm-devs queue Anthony Liguori
8 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2011-12-12 10:47 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
hw/mpcore.c is now implementing only ARM11MPCore specific peripherals,
and is #included only from hw/arm11mpcore.c, so just merge it into that
file.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm11mpcore.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++-
hw/mpcore.c | 137 ------------------------------------------------------
2 files changed, 129 insertions(+), 138 deletions(-)
delete mode 100644 hw/mpcore.c
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 32ecf98..bc0457e 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -7,11 +7,139 @@
* This code is licensed under the GPL.
*/
+#include "sysbus.h"
+#include "qemu-timer.h"
+
/* ??? The MPCore TRM says the on-chip controller has 224 external IRQ lines
(+ 32 internal). However my test chip only exposes/reports 32.
More importantly Linux falls over if more than 32 are present! */
#define GIC_NIRQ 64
-#include "mpcore.c"
+
+#define NCPU 4
+
+static inline int
+gic_get_current_cpu(void)
+{
+ return cpu_single_env->cpu_index;
+}
+
+#include "arm_gic.c"
+
+/* MPCore private memory region. */
+
+typedef struct mpcore_priv_state {
+ gic_state gic;
+ uint32_t scu_control;
+ int iomemtype;
+ uint32_t old_timer_status[8];
+ uint32_t num_cpu;
+ qemu_irq *timer_irq;
+ MemoryRegion iomem;
+ MemoryRegion container;
+ DeviceState *mptimer;
+} mpcore_priv_state;
+
+/* Per-CPU private memory mapped IO. */
+
+static uint64_t mpcore_scu_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
+{
+ mpcore_priv_state *s = (mpcore_priv_state *)opaque;
+ int id;
+ offset &= 0xff;
+ /* SCU */
+ switch (offset) {
+ case 0x00: /* Control. */
+ return s->scu_control;
+ case 0x04: /* Configuration. */
+ id = ((1 << s->num_cpu) - 1) << 4;
+ return id | (s->num_cpu - 1);
+ case 0x08: /* CPU status. */
+ return 0;
+ case 0x0c: /* Invalidate all. */
+ return 0;
+ default:
+ hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
+ }
+}
+
+static void mpcore_scu_write(void *opaque, target_phys_addr_t offset,
+ uint64_t value, unsigned size)
+{
+ mpcore_priv_state *s = (mpcore_priv_state *)opaque;
+ offset &= 0xff;
+ /* SCU */
+ switch (offset) {
+ case 0: /* Control register. */
+ s->scu_control = value & 1;
+ break;
+ case 0x0c: /* Invalidate all. */
+ /* This is a no-op as cache is not emulated. */
+ break;
+ default:
+ hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
+ }
+}
+
+static const MemoryRegionOps mpcore_scu_ops = {
+ .read = mpcore_scu_read,
+ .write = mpcore_scu_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void mpcore_timer_irq_handler(void *opaque, int irq, int level)
+{
+ mpcore_priv_state *s = (mpcore_priv_state *)opaque;
+ if (level && !s->old_timer_status[irq]) {
+ gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
+ }
+ s->old_timer_status[irq] = level;
+}
+
+static void mpcore_priv_map_setup(mpcore_priv_state *s)
+{
+ int i;
+ SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
+ memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
+ memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100);
+ memory_region_add_subregion(&s->container, 0, &s->iomem);
+ /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
+ * at 0x200, 0x300...
+ */
+ for (i = 0; i < (s->num_cpu + 1); i++) {
+ target_phys_addr_t offset = 0x100 + (i * 0x100);
+ memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]);
+ }
+ /* Add the regions for timer and watchdog for "current CPU" and
+ * for each specific CPU.
+ */
+ s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler,
+ s, (s->num_cpu + 1) * 2);
+ for (i = 0; i < (s->num_cpu + 1) * 2; i++) {
+ /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
+ target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20;
+ memory_region_add_subregion(&s->container, offset,
+ sysbus_mmio_get_region(busdev, i));
+ }
+ memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+ /* Wire up the interrupt from each watchdog and timer. */
+ for (i = 0; i < s->num_cpu * 2; i++) {
+ sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+ }
+}
+
+static int mpcore_priv_init(SysBusDevice *dev)
+{
+ mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
+
+ gic_init(&s->gic, s->num_cpu);
+ s->mptimer = qdev_create(NULL, "arm_mptimer");
+ qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
+ qdev_init_nofail(s->mptimer);
+ mpcore_priv_map_setup(s);
+ sysbus_init_mmio(dev, &s->container);
+ return 0;
+}
/* Dummy PIC to route IRQ lines. The baseboard has 4 independent IRQ
controllers. The output of these, plus some of the raw input lines
diff --git a/hw/mpcore.c b/hw/mpcore.c
deleted file mode 100644
index 670d7e5..0000000
--- a/hw/mpcore.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * ARM MPCore internal peripheral emulation (common code).
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "sysbus.h"
-#include "qemu-timer.h"
-
-#define NCPU 4
-
-static inline int
-gic_get_current_cpu(void)
-{
- return cpu_single_env->cpu_index;
-}
-
-#include "arm_gic.c"
-
-/* MPCore private memory region. */
-
-typedef struct mpcore_priv_state {
- gic_state gic;
- uint32_t scu_control;
- int iomemtype;
- uint32_t old_timer_status[8];
- uint32_t num_cpu;
- qemu_irq *timer_irq;
- MemoryRegion iomem;
- MemoryRegion container;
- DeviceState *mptimer;
-} mpcore_priv_state;
-
-/* Per-CPU private memory mapped IO. */
-
-static uint64_t mpcore_scu_read(void *opaque, target_phys_addr_t offset,
- unsigned size)
-{
- mpcore_priv_state *s = (mpcore_priv_state *)opaque;
- int id;
- offset &= 0xff;
- /* SCU */
- switch (offset) {
- case 0x00: /* Control. */
- return s->scu_control;
- case 0x04: /* Configuration. */
- id = ((1 << s->num_cpu) - 1) << 4;
- return id | (s->num_cpu - 1);
- case 0x08: /* CPU status. */
- return 0;
- case 0x0c: /* Invalidate all. */
- return 0;
- default:
- hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
- }
-}
-
-static void mpcore_scu_write(void *opaque, target_phys_addr_t offset,
- uint64_t value, unsigned size)
-{
- mpcore_priv_state *s = (mpcore_priv_state *)opaque;
- offset &= 0xff;
- /* SCU */
- switch (offset) {
- case 0: /* Control register. */
- s->scu_control = value & 1;
- break;
- case 0x0c: /* Invalidate all. */
- /* This is a no-op as cache is not emulated. */
- break;
- default:
- hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
- }
-}
-
-static const MemoryRegionOps mpcore_scu_ops = {
- .read = mpcore_scu_read,
- .write = mpcore_scu_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void mpcore_timer_irq_handler(void *opaque, int irq, int level)
-{
- mpcore_priv_state *s = (mpcore_priv_state *)opaque;
- if (level && !s->old_timer_status[irq]) {
- gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
- }
- s->old_timer_status[irq] = level;
-}
-
-static void mpcore_priv_map_setup(mpcore_priv_state *s)
-{
- int i;
- SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
- memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
- memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100);
- memory_region_add_subregion(&s->container, 0, &s->iomem);
- /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
- * at 0x200, 0x300...
- */
- for (i = 0; i < (s->num_cpu + 1); i++) {
- target_phys_addr_t offset = 0x100 + (i * 0x100);
- memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]);
- }
- /* Add the regions for timer and watchdog for "current CPU" and
- * for each specific CPU.
- */
- s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler,
- s, (s->num_cpu + 1) * 2);
- for (i = 0; i < (s->num_cpu + 1) * 2; i++) {
- /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
- target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20;
- memory_region_add_subregion(&s->container, offset,
- sysbus_mmio_get_region(busdev, i));
- }
- memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
- /* Wire up the interrupt from each watchdog and timer. */
- for (i = 0; i < s->num_cpu * 2; i++) {
- sysbus_connect_irq(busdev, i, s->timer_irq[i]);
- }
-}
-
-static int mpcore_priv_init(SysBusDevice *dev)
-{
- mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
-
- gic_init(&s->gic, s->num_cpu);
- s->mptimer = qdev_create(NULL, "arm_mptimer");
- qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
- qdev_init_nofail(s->mptimer);
- mpcore_priv_map_setup(s);
- sysbus_init_mmio(dev, &s->container);
- return 0;
-}
--
1.7.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] arm-devs queue
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
` (7 preceding siblings ...)
2011-12-12 10:47 ` [Qemu-devel] [PATCH 8/8] hw/mpcore.c: Merge with hw/arm11mpcore.c Peter Maydell
@ 2011-12-12 16:34 ` Anthony Liguori
8 siblings, 0 replies; 15+ messages in thread
From: Anthony Liguori @ 2011-12-12 16:34 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
On 12/12/2011 04:47 AM, Peter Maydell wrote:
> The following changes since commit f18318eef8b4b263f4e82a5338c9b2875a6c73c8:
>
> Merge branch 'master' of git://git.qemu.org/qemu (2011-12-12 04:12:31 +0400)
>
> are available in the git repository at:
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git arm-devs.for-upstream
Pulled. Thanks.
Regards,
Anthony Liguori
>
> Peter Chubb (1):
> Fix sp804 dual-timer
>
> Peter Maydell (7):
> hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices
> hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions
> hw/mpcore.c: Use the GIC memory regions for the CPU interface
> hw/realview_gic: Use GIC memory region for the CPU interface
> hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only
> hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones
> hw/mpcore.c: Merge with hw/arm11mpcore.c
>
> Makefile.target | 1 +
> hw/a9mpcore.c | 189 ++++++++++++++++++++++++++++--
> hw/arm11mpcore.c | 130 +++++++++++++++++++++-
> hw/arm_gic.c | 75 ++++++++++++-
> hw/arm_mptimer.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/arm_timer.c | 41 ++++++-
> hw/mpcore.c | 283 ---------------------------------------------
> hw/realview_gic.c | 25 +----
> 8 files changed, 751 insertions(+), 325 deletions(-)
> create mode 100644 hw/arm_mptimer.c
> delete mode 100644 hw/mpcore.c
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PULL 0/8] arm-devs queue
@ 2013-06-25 18:21 Peter Maydell
2013-06-25 19:07 ` Anthony Liguori
0 siblings, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2013-06-25 18:21 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Paul Brook
arm-devs pullreq; nothing particularly earthshattering.
As with the target-arm pullreq, I'm trying to create a signed
pullreq here, so let me know if I've messed it up.
The signed tag itself is 'pull-arm-devs-20130625'; arm-devs.for-upstream
is the branch name, as usual.
The following changes since commit baf8673ca802cb3ea2cdbe94813441d23bde223b:
Merge remote-tracking branch 'stefanha/block' into staging (2013-06-24 14:33:17 -0500)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git arm-devs.for-upstream
for you to fetch changes up to 7426aa72c36c908a7d0eae3e38568bb0a70de479:
nand: Don't inherit from Sysbus (2013-06-25 19:15:46 +0100)
----------------------------------------------------------------
arm-devs queue
----------------------------------------------------------------
Jean-Christophe DUBOIS (2):
i.MX: Implement a more complete version of the GPT timer.
i.MX: Rework functions/types name and use new style initialization
John Rigby (1):
ARM: Allow dumping of device tree
Peter Crosthwaite (3):
block/nand: QOM casting sweep
block/nand: Convert Sysbus::init to Device::realize
nand: Don't inherit from Sysbus
Peter Maydell (1):
arm/boot: Free dtb blob memory after use
Stefan Weil (1):
i.MX31: Fix PRCS bit test
hw/arm/boot.c | 21 +-
hw/block/nand.c | 48 +++--
hw/misc/imx_ccm.c | 2 +-
hw/timer/imx_gpt.c | 558 ++++++++++++++++++++++++++++++----------------------
4 files changed, 369 insertions(+), 260 deletions(-)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] arm-devs queue
2013-06-25 18:21 Peter Maydell
@ 2013-06-25 19:07 ` Anthony Liguori
2013-06-25 20:49 ` Peter Maydell
0 siblings, 1 reply; 15+ messages in thread
From: Anthony Liguori @ 2013-06-25 19:07 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Paul Brook
Peter Maydell <peter.maydell@linaro.org> writes:
> arm-devs pullreq; nothing particularly earthshattering.
> As with the target-arm pullreq, I'm trying to create a signed
> pullreq here, so let me know if I've messed it up.
> The signed tag itself is 'pull-arm-devs-20130625'; arm-devs.for-upstream
> is the branch name, as usual.
>
>
> The following changes since commit baf8673ca802cb3ea2cdbe94813441d23bde223b:
>
> Merge remote-tracking branch 'stefanha/block' into staging (2013-06-24 14:33:17 -0500)
>
> are available in the git repository at:
>
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git
> arm-devs.for-upstream
No need to resubmit, but you'll want to use the tag name instead of the
branch name here in the future.
Regards,
Anthony Liguori
>
> for you to fetch changes up to 7426aa72c36c908a7d0eae3e38568bb0a70de479:
>
> nand: Don't inherit from Sysbus (2013-06-25 19:15:46 +0100)
>
> ----------------------------------------------------------------
> arm-devs queue
>
> ----------------------------------------------------------------
> Jean-Christophe DUBOIS (2):
> i.MX: Implement a more complete version of the GPT timer.
> i.MX: Rework functions/types name and use new style initialization
>
> John Rigby (1):
> ARM: Allow dumping of device tree
>
> Peter Crosthwaite (3):
> block/nand: QOM casting sweep
> block/nand: Convert Sysbus::init to Device::realize
> nand: Don't inherit from Sysbus
>
> Peter Maydell (1):
> arm/boot: Free dtb blob memory after use
>
> Stefan Weil (1):
> i.MX31: Fix PRCS bit test
>
> hw/arm/boot.c | 21 +-
> hw/block/nand.c | 48 +++--
> hw/misc/imx_ccm.c | 2 +-
> hw/timer/imx_gpt.c | 558 ++++++++++++++++++++++++++++++----------------------
> 4 files changed, 369 insertions(+), 260 deletions(-)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] arm-devs queue
2013-06-25 19:07 ` Anthony Liguori
@ 2013-06-25 20:49 ` Peter Maydell
2013-06-25 21:45 ` Anthony Liguori
0 siblings, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2013-06-25 20:49 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Paul Brook
On 25 June 2013 20:07, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> arm-devs pullreq; nothing particularly earthshattering.
>> As with the target-arm pullreq, I'm trying to create a signed
>> pullreq here, so let me know if I've messed it up.
>> The signed tag itself is 'pull-arm-devs-20130625'; arm-devs.for-upstream
>> is the branch name, as usual.
>>
>>
>> The following changes since commit baf8673ca802cb3ea2cdbe94813441d23bde223b:
>>
>> Merge remote-tracking branch 'stefanha/block' into staging (2013-06-24 14:33:17 -0500)
>>
>> are available in the git repository at:
>>
>>
>> git://git.linaro.org/people/pmaydell/qemu-arm.git
>> arm-devs.for-upstream
>
> No need to resubmit, but you'll want to use the tag name instead of the
> branch name here in the future.
Yeah, I'd wondered if that might be the case.
Oh, do you want the actual tag to have a signed-off-by:
line, and (more generically) do you care if the tag message
actually has any useful content? I notice mst does both.
thanks
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] arm-devs queue
2013-06-25 20:49 ` Peter Maydell
@ 2013-06-25 21:45 ` Anthony Liguori
2013-06-25 22:01 ` Peter Maydell
0 siblings, 1 reply; 15+ messages in thread
From: Anthony Liguori @ 2013-06-25 21:45 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Paul Brook
Peter Maydell <peter.maydell@linaro.org> writes:
> On 25 June 2013 20:07, Anthony Liguori <aliguori@us.ibm.com> wrote:
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>
>>> arm-devs pullreq; nothing particularly earthshattering.
>>> As with the target-arm pullreq, I'm trying to create a signed
>>> pullreq here, so let me know if I've messed it up.
>>> The signed tag itself is 'pull-arm-devs-20130625'; arm-devs.for-upstream
>>> is the branch name, as usual.
>>>
>>>
>>> The following changes since commit baf8673ca802cb3ea2cdbe94813441d23bde223b:
>>>
>>> Merge remote-tracking branch 'stefanha/block' into staging (2013-06-24 14:33:17 -0500)
>>>
>>> are available in the git repository at:
>>>
>>>
>>> git://git.linaro.org/people/pmaydell/qemu-arm.git
>>> arm-devs.for-upstream
>>
>> No need to resubmit, but you'll want to use the tag name instead of the
>> branch name here in the future.
>
> Yeah, I'd wondered if that might be the case.
>
> Oh, do you want the actual tag to have a signed-off-by:
> line,
I don't see any practical reason to add a SoB to a tag. A tag is a
symbolic reference to an existing commit. There is never any code
change.
A merge may involve code change so a SoB makes sense. I now SoB all
merges.
Of course, if you want to include a SoB, more power to you but I am not
requiring it.
> and (more generically) do you care if the tag message
> actually has any useful content? I notice mst does both.
Note the tags don't show up in qemu.git git history. I don't push them
as there's no point in pushing them there. When I do a merge, I'm
merging the commit that the tag points to, not the tag itself. The tag
only exists for me to be able to validate you are who you say you are
sending what you said you've sent.
So I really don't care if there's any content in the tag. It's mostly
for your own personal benefit.
Regards,
Anthony Liguori
>
> thanks
> -- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] arm-devs queue
2013-06-25 21:45 ` Anthony Liguori
@ 2013-06-25 22:01 ` Peter Maydell
0 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-06-25 22:01 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Paul Brook
On 25 June 2013 22:45, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Peter Maydell <peter.maydell@linaro.org> writes:
>> and (more generically) do you care if the tag message
>> actually has any useful content? I notice mst does both.
>
> Note the tags don't show up in qemu.git git history.
The tags don't, but the message does, at least according to
https://www.kernel.org/pub/software/scm/git/docs/howto/using-signed-tag-in-pull-request.html
which says a signed tag always results in a merge commit
which includes the message that came with the tag.
For most of these pull requests I'm not sure the message
would actually add much useful info though, which is why
I left it at just "arm-devs queue".
thanks
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2013-06-25 22:02 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-12 10:47 [Qemu-devel] [PULL 0/8] arm-devs queue Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 1/8] Fix sp804 dual-timer Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 2/8] hw/arm_mptimer.c: Turn ARM MPcore private timers into qdev devices Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 3/8] hw/arm_gic: Expose GIC CPU interfaces as sysbus memory regions Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 4/8] hw/mpcore.c: Use the GIC memory regions for the CPU interface Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 5/8] hw/realview_gic: Use GIC memory region " Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 6/8] hw/mpcore: Clean up mpcore_priv_read/write as they are now SCU only Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 7/8] hw/a9mpcore.c: Implement A9MP peripherals rather than 11MPcore ones Peter Maydell
2011-12-12 10:47 ` [Qemu-devel] [PATCH 8/8] hw/mpcore.c: Merge with hw/arm11mpcore.c Peter Maydell
2011-12-12 16:34 ` [Qemu-devel] [PULL 0/8] arm-devs queue Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2013-06-25 18:21 Peter Maydell
2013-06-25 19:07 ` Anthony Liguori
2013-06-25 20:49 ` Peter Maydell
2013-06-25 21:45 ` Anthony Liguori
2013-06-25 22:01 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).