Skip to content

Commit

Permalink
integrator: fix Linux boot failure by emulating dbg region
Browse files Browse the repository at this point in the history
Commit 9b8c692 (since reverted) 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 basic stub of a memory region for the debug/LED section
on the integrator board.

Signed-off-by: Alex Bennée <alex@bennee.com>
Message-id: 1382451366-9539-1-git-send-email-alex.bennee@linaro.org
[PMM: removed three unused fields from struct IntegratorDebugState]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
stsquad authored and edgarigl committed Oct 31, 2013
1 parent 0bc2a33 commit b861605
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions default-configs/arm-softmmu.mak
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ CONFIG_VERSATILE_PCI=y
CONFIG_VERSATILE_I2C=y

CONFIG_SDHCI=y
CONFIG_INTEGRATOR_DEBUG=y
2 changes: 2 additions & 0 deletions hw/arm/integratorcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/arm/arm.h"
#include "hw/misc/arm_integrator_debug.h"
#include "net/net.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
Expand Down Expand Up @@ -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(TYPE_INTEGRATOR_DEBUG, 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]);
Expand Down
1 change: 1 addition & 0 deletions hw/misc/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ obj-$(CONFIG_VMPORT) += vmport.o

# ARM devices
common-obj-$(CONFIG_PL310) += arm_l2x0.o
common-obj-$(CONFIG_INTEGRATOR_DEBUG) += arm_integrator_debug.o

# PKUnity SoC devices
common-obj-$(CONFIG_PUV3) += puv3_pm.o
Expand Down
99 changes: 99 additions & 0 deletions hw/misc/arm_integrator_debug.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* LED, Switch and Debug control registers for ARM Integrator Boards
*
* This is currently a stub for this functionality but at least
* ensures something other than unassigned_mem_read() handles access
* to this area.
*
* The real h/w is described at:
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
*
* Copyright (c) 2013 Alex Bennée <alex@bennee.com>
*
* 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"
#include "hw/misc/arm_integrator_debug.h"

#define INTEGRATOR_DEBUG(obj) \
OBJECT_CHECK(IntegratorDebugState, (obj), TYPE_INTEGRATOR_DEBUG)

typedef struct {
SysBusDevice parent_obj;

MemoryRegion iomem;
} IntegratorDebugState;

static uint64_t intdbg_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,
"%s: returning zero from %" HWADDR_PRIx ":%u\n",
__func__, offset, size);
return 0;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad offset %" HWADDR_PRIx,
__func__, offset);
return 0;
}
}

static void intdbg_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,
"%s: ignoring write of %" PRIu64
" to %" HWADDR_PRIx ":%u\n",
__func__, value, offset, size);
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: write of %" PRIu64
" to bad offset %" HWADDR_PRIx "\n",
__func__, value, offset);
}
}

static const MemoryRegionOps intdbg_control_ops = {
.read = intdbg_control_read,
.write = intdbg_control_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};

static void intdbg_control_init(Object *obj)
{
SysBusDevice *sd = SYS_BUS_DEVICE(obj);
IntegratorDebugState *s = INTEGRATOR_DEBUG(obj);

memory_region_init_io(&s->iomem, NULL, &intdbg_control_ops,
NULL, "dbg-leds", 0x1000000);
sysbus_init_mmio(sd, &s->iomem);
}

static const TypeInfo intdbg_info = {
.name = TYPE_INTEGRATOR_DEBUG,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IntegratorDebugState),
.instance_init = intdbg_control_init,
};

static void intdbg_register_types(void)
{
type_register_static(&intdbg_info);
}

type_init(intdbg_register_types)
18 changes: 18 additions & 0 deletions include/hw/misc/arm_integrator_debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* ARM Integrator Board Debug, switch and LED section
*
* Browse the data sheet:
*
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html
*
* Copyright (c) 2013 Alex Bennée <alex@bennee.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef QEMU_INTEGRATOR_DEBUG_H
#define QEMU_INTEGRATOR_DEBUG_H

#define TYPE_INTEGRATOR_DEBUG "integrator_debug"

#endif

0 comments on commit b861605

Please sign in to comment.