* [Qemu-devel] [PATCH v2 0/0] integrator: fix Linux boot failure by emulating dbg
@ 2013-09-18 14:31 alex.bennee
2013-09-18 14:31 ` [Qemu-devel] [PATCH v2 1/1] " alex.bennee
0 siblings, 1 reply; 5+ messages in thread
From: alex.bennee @ 2013-09-18 14:31 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, paul
Hi,
I mistakenly appended this to the previous patch revision. I'm now
sending for further review.
Since v1:
- Updated with Peter Maydell's review comments.
--
Alex Bennée
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH v2 1/1] integrator: fix Linux boot failure by emulating dbg
2013-09-18 14:31 [Qemu-devel] [PATCH v2 0/0] integrator: fix Linux boot failure by emulating dbg alex.bennee
@ 2013-09-18 14:31 ` alex.bennee
2013-09-18 15:54 ` Andreas Färber
0 siblings, 1 reply; 5+ messages in thread
From: alex.bennee @ 2013-09-18 14:31 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, paul
From: Alex Bennée <alex@bennee.com>
Commit 9b8c69243 broke the ability to boot the kernel as the value
returned by unassigned_mem_read returned non-zero and left the kernel
looping forever waiting for it to change (see integrator_led_set in
the kernel code).
Relying on a varying implementation detail is incorrect anyway so this
introduces a memory region to emulate the debug/led region on the
integrator board. It is currently a basic stub as I have no idea what the
behaviour of this region should be so for now it simply returns 0's as
the old unassigned_mem_read did.
Signed-off-by: Alex Bennée <alex@bennee.com>
---
default-configs/arm-softmmu.mak | 1 +
hw/arm/integratorcp.c | 1 +
hw/misc/Makefile.objs | 1 +
hw/misc/arm_intdbg.c | 90 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 93 insertions(+)
create mode 100644 hw/misc/arm_intdbg.c
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index ac0815d..a5718d1 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -80,3 +80,4 @@ CONFIG_VERSATILE_PCI=y
CONFIG_VERSATILE_I2C=y
CONFIG_SDHCI=y
+CONFIG_INTEGRATOR_DBG=y
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 2ef93ed..46dc615 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -508,6 +508,7 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
icp_control_init(0xcb000000);
sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
+ sysbus_create_simple("integrator_dbg", 0x1a000000, 0);
sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
if (nd_table[0].used)
smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 2578e29..be284f3 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -10,6 +10,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
# ARM devices
common-obj-$(CONFIG_PL310) += arm_l2x0.o
+common-obj-$(CONFIG_INTEGRATOR_DBG) += arm_intdbg.o
# PKUnity SoC devices
common-obj-$(CONFIG_PUV3) += puv3_pm.o
diff --git a/hw/misc/arm_intdbg.c b/hw/misc/arm_intdbg.c
new file mode 100644
index 0000000..b505d09
--- /dev/null
+++ b/hw/misc/arm_intdbg.c
@@ -0,0 +1,90 @@
+/*
+ * LED, Switch and Debug control registers for ARM Integrator Boards
+ *
+ * This currently is a stub for this functionality written with
+ * reference to what the Linux kernel looks at. Previously we relied
+ * on the behaviour of unassigned_mem_read() in the core.
+ *
+ * The real h/w is described at:
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
+ *
+ * Written by Alex Bennée
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+
+#define TYPE_ARM_INTDBG "integrator_dbg"
+#define ARM_INTDBG(obj) \
+ OBJECT_CHECK(ARMIntDbgState, (obj), TYPE_ARM_INTDBG)
+
+typedef struct {
+ SysBusDevice parent_obj;
+ MemoryRegion iomem;
+
+ uint32_t alpha;
+ uint32_t leds;
+ uint32_t switches;
+} ARMIntDbgState;
+
+static uint64_t dbg_control_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ switch (offset >> 2) {
+ case 0: /* ALPHA */
+ case 1: /* LEDS */
+ case 2: /* SWITCHES */
+ qemu_log_mask(LOG_UNIMP, "dbg_control_read: returning zero from %x:%d\n", (int)offset, size);
+ return 0;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "dbg_control_read: Bad offset %x\n", (int)offset);
+ return 0;
+ }
+}
+
+static void dbg_control_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ switch (offset >> 2) {
+ case 1: /* ALPHA */
+ case 2: /* LEDS */
+ case 3: /* SWITCHES */
+ /* Nothing interesting implemented yet. */
+ qemu_log_mask(LOG_UNIMP, "dbg_control_write: ignoring write of %lx to %x:%d\n", value, (int)offset, size);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "dbg_control_write: write of %lx to bad offset %x\n", value, (int)offset);
+ }
+}
+
+static const MemoryRegionOps dbg_control_ops = {
+ .read = dbg_control_read,
+ .write = dbg_control_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void dbg_control_init(Object *obj)
+{
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+ ARMIntDbgState *s = ARM_INTDBG(obj);
+ memory_region_init_io(&s->iomem, NULL, &dbg_control_ops, NULL, "dbgleds", 0x1000000);
+ sysbus_init_mmio(sd, &s->iomem);
+}
+
+static const TypeInfo arm_intdbg_info = {
+ .name = TYPE_ARM_INTDBG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(ARMIntDbgState),
+ .instance_init = dbg_control_init,
+};
+
+static void arm_intdbg_register_types(void)
+{
+ type_register_static(&arm_intdbg_info);
+}
+
+type_init(arm_intdbg_register_types)
--
1.8.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/1] integrator: fix Linux boot failure by emulating dbg
2013-09-18 14:31 ` [Qemu-devel] [PATCH v2 1/1] " alex.bennee
@ 2013-09-18 15:54 ` Andreas Färber
2013-09-18 16:06 ` Alex Bennée
0 siblings, 1 reply; 5+ messages in thread
From: Andreas Färber @ 2013-09-18 15:54 UTC (permalink / raw)
To: alex.bennee; +Cc: peter.maydell, qemu-devel, paul
Am 18.09.2013 16:31, schrieb alex.bennee@linaro.org:
> From: Alex Bennée <alex@bennee.com>
>
> Commit 9b8c69243 broke the ability to boot the kernel as the value
> returned by unassigned_mem_read returned non-zero and left the kernel
> looping forever waiting for it to change (see integrator_led_set in
> the kernel code).
>
> Relying on a varying implementation detail is incorrect anyway so this
> introduces a memory region to emulate the debug/led region on the
> integrator board. It is currently a basic stub as I have no idea what the
> behaviour of this region should be so for now it simply returns 0's as
> the old unassigned_mem_read did.
>
> Signed-off-by: Alex Bennée <alex@bennee.com>
> ---
> default-configs/arm-softmmu.mak | 1 +
> hw/arm/integratorcp.c | 1 +
> hw/misc/Makefile.objs | 1 +
> hw/misc/arm_intdbg.c | 90 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 93 insertions(+)
> create mode 100644 hw/misc/arm_intdbg.c
Looks okay in general, some minor nits below:
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index ac0815d..a5718d1 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -80,3 +80,4 @@ CONFIG_VERSATILE_PCI=y
> CONFIG_VERSATILE_I2C=y
>
> CONFIG_SDHCI=y
> +CONFIG_INTEGRATOR_DBG=y
> diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
> index 2ef93ed..46dc615 100644
> --- a/hw/arm/integratorcp.c
> +++ b/hw/arm/integratorcp.c
> @@ -508,6 +508,7 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
> icp_control_init(0xcb000000);
> sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
> sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
> + sysbus_create_simple("integrator_dbg", 0x1a000000, 0);
> sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
> if (nd_table[0].used)
> smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 2578e29..be284f3 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -10,6 +10,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
>
> # ARM devices
> common-obj-$(CONFIG_PL310) += arm_l2x0.o
> +common-obj-$(CONFIG_INTEGRATOR_DBG) += arm_intdbg.o
>
> # PKUnity SoC devices
> common-obj-$(CONFIG_PUV3) += puv3_pm.o
> diff --git a/hw/misc/arm_intdbg.c b/hw/misc/arm_intdbg.c
> new file mode 100644
> index 0000000..b505d09
> --- /dev/null
> +++ b/hw/misc/arm_intdbg.c
> @@ -0,0 +1,90 @@
> +/*
> + * LED, Switch and Debug control registers for ARM Integrator Boards
> + *
> + * This currently is a stub for this functionality written with
> + * reference to what the Linux kernel looks at. Previously we relied
> + * on the behaviour of unassigned_mem_read() in the core.
> + *
> + * The real h/w is described at:
> + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
> + *
> + * Written by Alex Bennée
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "hw/hw.h"
> +#include "hw/sysbus.h"
> +#include "exec/address-spaces.h"
> +
> +#define TYPE_ARM_INTDBG "integrator_dbg"
If you move this constant into an include/hw/misc/arm_integratorcp_dbg.h
then you can reuse it in hw/arm/integratorcp.c above. (Optional.)
> +#define ARM_INTDBG(obj) \
> + OBJECT_CHECK(ARMIntDbgState, (obj), TYPE_ARM_INTDBG)
> +
> +typedef struct {
> + SysBusDevice parent_obj;
Please leave an empty line here to visually separate the parent field.
> + MemoryRegion iomem;
> +
> + uint32_t alpha;
> + uint32_t leds;
> + uint32_t switches;
> +} ARMIntDbgState;
> +
> +static uint64_t dbg_control_read(void *opaque, hwaddr offset,
> + unsigned size)
> +{
> + switch (offset >> 2) {
> + case 0: /* ALPHA */
> + case 1: /* LEDS */
> + case 2: /* SWITCHES */
> + qemu_log_mask(LOG_UNIMP, "dbg_control_read: returning zero from %x:%d\n", (int)offset, size);
HWADDR_PRIx, %u
Also suggest %s and __func__, cf. further below.
> + return 0;
> + default:
> + qemu_log_mask(LOG_GUEST_ERROR, "dbg_control_read: Bad offset %x\n", (int)offset);
HWADDR_PRIx
> + return 0;
> + }
> +}
> +
> +static void dbg_control_write(void *opaque, hwaddr offset,
> + uint64_t value, unsigned size)
> +{
> + switch (offset >> 2) {
> + case 1: /* ALPHA */
> + case 2: /* LEDS */
> + case 3: /* SWITCHES */
> + /* Nothing interesting implemented yet. */
> + qemu_log_mask(LOG_UNIMP, "dbg_control_write: ignoring write of %lx to %x:%d\n", value, (int)offset, size);
> + break;
> + default:
> + qemu_log_mask(LOG_GUEST_ERROR, "dbg_control_write: write of %lx to bad offset %x\n", value, (int)offset);
> + }
> +}
> +
> +static const MemoryRegionOps dbg_control_ops = {
> + .read = dbg_control_read,
> + .write = dbg_control_write,
> + .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void dbg_control_init(Object *obj)
> +{
> + SysBusDevice *sd = SYS_BUS_DEVICE(obj);
> + ARMIntDbgState *s = ARM_INTDBG(obj);
Please leave an empty line after the variable declaration block.
> + memory_region_init_io(&s->iomem, NULL, &dbg_control_ops, NULL, "dbgleds", 0x1000000);
"dbg-leds"?
> + sysbus_init_mmio(sd, &s->iomem);
> +}
> +
> +static const TypeInfo arm_intdbg_info = {
> + .name = TYPE_ARM_INTDBG,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(ARMIntDbgState),
> + .instance_init = dbg_control_init,
> +};
> +
> +static void arm_intdbg_register_types(void)
> +{
> + type_register_static(&arm_intdbg_info);
> +}
> +
> +type_init(arm_intdbg_register_types)
The naming is a bit unfortunate and inconsistent. For one, QOM types
should use dashes and at least the in-code constants/macros are
requested to have a verbose, readable name. Could you expand INTDBG to
INTEGRATOR_DBG or INTEGRATOR_DEBUG like you have done for the Makefile?
Also please use arm_intdbg_ prefix (or whatever you choose) consistently
throughout the file (the idea is to have "unique" names that allow to
associate __func__ debug output with its origin). Having "integrator" or
"integratorcp" in the file name would also clarify that it's not for
"interrupt" or "internal". ;) Similar for ARMIntDbgState -
"ARMIntegratorDbgState"?
Cheers,
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] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] integrator: fix Linux boot failure by emulating dbg
@ 2013-09-13 15:20 Peter Maydell
2013-09-16 12:50 ` [Qemu-devel] [PATCH v2 0/0] " alex.bennee
0 siblings, 1 reply; 5+ messages in thread
From: Peter Maydell @ 2013-09-13 15:20 UTC (permalink / raw)
To: alex.bennee; +Cc: QEMU Developers
On 13 September 2013 15:58, <alex.bennee@linaro.org> wrote:
> From: Alex Bennée <alex@bennee.com>
>
> Commit 9b8c69243 broke the ability to boot the kernel as the value
> returned by unassigned_mem_read returned non-zero and left the kernel
> looping forever waiting for it to change (see integrator_led_set in
> the kernel code).
>
> Relying on a varying implementation detail is incorrect anyway so this
> introduces a memory region to emulate the debug/led region on the
> integrator board. It is currently a basic stub as I have no idea what the
> behaviour of this region should be
See the integrator board documentation:
http://infocenter.arm.com/help/topic/com.arm.doc.dui0159b/Babbfijf.html
> so for now it simply returns 0's as
> the old unassigned_mem_read did.
> ---
> hw/arm/integratorcp.c | 2 ++
> hw/misc/Makefile.objs | 1 +
> hw/misc/arm_intdbg.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 93 insertions(+)
> create mode 100644 hw/misc/arm_intdbg.c
>
> diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
> index 2ef93ed..e5d07c4 100644
> --- a/hw/arm/integratorcp.c
> +++ b/hw/arm/integratorcp.c
> @@ -446,6 +446,7 @@ static void icp_control_init(hwaddr base)
> }
>
>
> +
Stray whitespace change.
> /* Board init. */
>
> static struct arm_boot_info integrator_binfo = {
> @@ -508,6 +509,7 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
> icp_control_init(0xcb000000);
> sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
> sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
> + sysbus_create_simple("integrator_dbg", 0x1a000000, 0);
> sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
> if (nd_table[0].used)
> smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 2578e29..e2c84a3 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -22,6 +22,7 @@ obj-$(CONFIG_LINUX) += vfio.o
> endif
>
> obj-$(CONFIG_REALVIEW) += arm_sysctl.o
> +obj-y += arm_intdbg.o
The device isn't depending on anything target specific
so it can go in common-obj-. It needs its own
CONFIG_INTEGRATOR_DBG in default-configs/arm-softmmu.mak
so you can make it common-obj-$(CONFIG_INTEGRATOR_DBG) +=.
> obj-$(CONFIG_A9SCU) += a9scu.o
> obj-$(CONFIG_NSERIES) += cbus.o
> obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
> diff --git a/hw/misc/arm_intdbg.c b/hw/misc/arm_intdbg.c
> new file mode 100644
> index 0000000..1f21447
> --- /dev/null
> +++ b/hw/misc/arm_intdbg.c
> @@ -0,0 +1,90 @@
> +/*
> + * LED, Switch and Debug control registers for ARM Integrator Boards
> + *
> + * This currently is a stub for this functionality written with
> + * reference to what the Linux kernel looks at. Previously we relied
> + * on the behaviour of unassigned_mem_read() in the core.
> + *
> + * Written by Alex Bennée
> + *
> + * This code is licensed under the GPL.
Would be nice to give a specific version of the GPL...
("2" or "2 or later" are your two basic options.)
> + */
> +
> +#include "hw/hw.h"
> +#include "hw/sysbus.h"
> +#include "exec/address-spaces.h"
> +
> +#define TYPE_ARM_INTDBG "integrator_dbg"
> +#define ARM_INTDBG(obj) \
> + OBJECT_CHECK(arm_intdbg_state, (obj), TYPE_ARM_INTDBG)
> +
> +typedef struct {
> + SysBusDevice parent_obj;
> + MemoryRegion iomem;
> +
> + uint32_t alpha;
> + uint32_t leds;
> + uint32_t switches;
> +} arm_intdbg_state;
CODING_STYLE says type names should be camelcase, so
ARMIntDbgState.
> +
> +static uint64_t dbg_control_read(void *opaque, hwaddr offset,
> + unsigned size)
> +{
> + switch (offset >> 2) {
> + case 0: /* ALPHA */
> + return 0;
> + case 1: /* LEDS */
> + return 0;
> + case 2: /* SWITCHES */
> + return 0;
You could log these with qemu_log_mask(LOG_UNIMP, ...)
> + default:
> + hw_error("dbg_control_read: Bad offset %x\n", (int)offset);
Don't hw_error() for something a guest can provoke.
You can just log the info to the debug log (if the
user has enabled it) and press on:
qemu_log_mask(LOG_GUEST_ERROR,
"dbg_control_read: Bad offset %x\n", (int)offset);
> + return 0;
> + }
> +}
> +
> +static void dbg_control_write(void *opaque, hwaddr offset,
> + uint64_t value, unsigned size)
> +{
> + switch (offset >> 2) {
> + case 1: /* ALPHA */
> + case 2: /* LEDS */
> + case 3: /* SWITCHES */
> + /* Nothing interesting implemented yet. */
> + break;
> + default:
> + hw_error("dbg_control_write: Bad offset %x\n", (int)offset);
Same remarks as above about logging unimplemented
and bad guest behaviour.
> + }
> +}
> +
> +static const MemoryRegionOps dbg_control_ops = {
> + .read = dbg_control_read,
> + .write = dbg_control_write,
> + .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void dbg_control_init(Object *obj)
> +{
> + SysBusDevice *sd = SYS_BUS_DEVICE(obj);
> + arm_intdbg_state *s = ARM_INTDBG(obj);
> + memory_region_init_io(&s->iomem, NULL, &dbg_control_ops, NULL, "dbgleds", 0x1000);
(Does this line overflow 80 characters? You can
catch this and other style errors by running your
patch through scripts/checkpatch.pl...)
The documentation says the size of this region is 16MB,
ie 0x1000000. (Actually it says we effectively don't
decode most of the address lines so it probably repeats
every 16 bytes, but let's not worry about that right now.)
> + sysbus_init_mmio(sd, &s->iomem);
> +}
> +
> +/*
> + Hardware boilerplate
> +*/
You don't need to add a comment telling us QOM involves
lots of boilerplate, we already know that :-)
> +
> +static const TypeInfo arm_intdbg_info = {
> + .name = TYPE_ARM_INTDBG,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(arm_intdbg_state),
> + .instance_init = dbg_control_init,
> +};
> +
> +static void arm_intdbg_register_types(void)
> +{
> + type_register_static(&arm_intdbg_info);
> +}
> +
> +type_init(arm_intdbg_register_types)
thanks
-- PMM
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-09-18 16:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-18 14:31 [Qemu-devel] [PATCH v2 0/0] integrator: fix Linux boot failure by emulating dbg alex.bennee
2013-09-18 14:31 ` [Qemu-devel] [PATCH v2 1/1] " alex.bennee
2013-09-18 15:54 ` Andreas Färber
2013-09-18 16:06 ` Alex Bennée
-- strict thread matches above, loose matches on Subject: below --
2013-09-13 15:20 [Qemu-devel] [PATCH] " Peter Maydell
2013-09-16 12:50 ` [Qemu-devel] [PATCH v2 0/0] " alex.bennee
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).