~philmd/qemu

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
16

[PATCH v3 00/16] hw/arm/raspi: Add thermal/timer, improve address space, run U-boot

Details
Message ID
<20191019234715.25750-1-f4bug@amsat.org>
DKIM signature
missing
Download raw message
Since v2:
- fixed issue in videocore address space
- allow to start with some cores OFF (to boot firmwares)
- add proof-of-concept test for '-smp cores=1' and U-boot
- fixed my email setup

Previous cover:

Hi,

Some patches from v1 are already merged. This v2 addresses the
review comment from v1, and add patches to clean the memory
space when using multiple cores.

Laurent, if you test U-Boot with this patchset again, do you mind
replying with a "Tested-by:" tag?

The next patchset is probably about the interrupt controller blocks,
then will come another one about the MBox/Properties.

The last patch is unrelated to the series, but since I cleaned this
for the raspi and the highbank is the only board with the same issue,
I included the patch in this series.

Please review.

Regards,

Phil.

$ git backport-diff -u v2
001/16:[----] [--] 'hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor'
002/16:[----] [--] 'hw/arm/bcm2835_peripherals: Use the thermal sensor block'
003/16:[----] [--] 'hw/timer/bcm2835: Add the BCM2835 SYS_timer'
004/16:[----] [--] 'hw/arm/bcm2835_peripherals: Use the SYS_timer'
005/16:[----] [--] 'hw/arm/bcm2836: Make the SoC code modular'
006/16:[down] 'hw/arm/bcm2836: Rename cpus[] as cpu[].core'
007/16:[0053] [FC] 'hw/arm/bcm2836: Use per CPU address spaces'
008/16:[down] 'hw/arm/bcm2835_peripherals: Add const link property in realize()'
009/16:[0105] [FC] 'hw/arm/bcm2836: Create VideoCore address space in the SoC'
010/16:[----] [--] 'hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot'
011/16:[down] 'hw/arm/raspi: Use -smp cores=<N> option to restrict enabled cores'
012/16:[down] 'hw/arm/bcm2836: Rename enabled_cpus -> enabled_cores'
013/16:[----] [-C] 'hw/arm/raspi: Make the board code modular'
014/16:[----] [--] 'hw/arm/highbank: Use AddressSpace when using write_secondary_boot()'
015/16:[down] 'python/qemu/machine: Allow to use other serial consoles than default'
016/16:[down] 'NOTFORMERGE tests/acceptance: Test U-boot on the Raspberry Pi 3'

v2: https://lists.gnu.org/archive/html/qemu-devel/2019-10/msg04474.html

Philippe Mathieu-Daudé (16):
  hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor
  hw/arm/bcm2835_peripherals: Use the thermal sensor block
  hw/timer/bcm2835: Add the BCM2835 SYS_timer
  hw/arm/bcm2835_peripherals: Use the SYS_timer
  hw/arm/bcm2836: Make the SoC code modular
  hw/arm/bcm2836: Rename cpus[] as cpu[].core
  hw/arm/bcm2836: Use per CPU address spaces
  hw/arm/bcm2835_peripherals: Add const link property in realize()
  hw/arm/bcm2836: Create VideoCore address space in the SoC
  hw/arm/raspi: Use AddressSpace when using
    arm_boot::write_secondary_boot
  hw/arm/raspi: Use -smp cores=<N> option to restrict enabled cores
  hw/arm/bcm2836: Rename enabled_cpus -> enabled_cores
  hw/arm/raspi: Make the board code modular
  hw/arm/highbank: Use AddressSpace when using write_secondary_boot()
  python/qemu/machine: Allow to use other serial consoles than default
  NOTFORMERGE tests/acceptance: Test U-boot on the Raspberry Pi 3

 hw/arm/bcm2835_peripherals.c           |  76 +++++++----
 hw/arm/bcm2836.c                       | 119 ++++++++++++++----
 hw/arm/highbank.c                      |   3 +-
 hw/arm/raspi.c                         | 127 +++++++++++++++----
 hw/misc/Makefile.objs                  |   1 +
 hw/misc/bcm2835_thermal.c              | 135 ++++++++++++++++++++
 hw/timer/Makefile.objs                 |   1 +
 hw/timer/bcm2835_systmr.c              | 166 +++++++++++++++++++++++++
 hw/timer/trace-events                  |   5 +
 include/hw/arm/bcm2835_peripherals.h   |   9 +-
 include/hw/arm/bcm2836.h               |  17 ++-
 include/hw/arm/raspi_platform.h        |   1 +
 include/hw/misc/bcm2835_thermal.h      |  27 ++++
 include/hw/timer/bcm2835_systmr.h      |  33 +++++
 python/qemu/machine.py                 |   9 +-
 tests/acceptance/boot_linux_console.py |  23 ++++
 16 files changed, 671 insertions(+), 81 deletions(-)
 create mode 100644 hw/misc/bcm2835_thermal.c
 create mode 100644 hw/timer/bcm2835_systmr.c
 create mode 100644 include/hw/misc/bcm2835_thermal.h
 create mode 100644 include/hw/timer/bcm2835_systmr.h

-- 
2.21.0

[PATCH v3 01/16] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor

Details
Message ID
<20191019234715.25750-2-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +163 -0
We will soon implement the SYS_timer. This timer is used by Linux
in the thermal subsystem, so once available, the subsystem will be
enabled and poll the temperature sensors. We need to provide the
minimum required to keep Linux booting.

Add a dummy thermal sensor returning ~25°C based on:
https://github.com/raspberrypi/linux/blob/rpi-5.3.y/drivers/thermal/broadcom/bcm2835_thermal.c

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2:
- Explicit g_assert_not_reached() with comment (Alex)
- Add vmstate and reset handler (Peter)

checkpatch warning:
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
This is OK because the regex are:

  F: hw/*/bcm283*
  F: include/hw/*/bcm283*
---
 hw/misc/Makefile.objs             |   1 +
 hw/misc/bcm2835_thermal.c         | 135 ++++++++++++++++++++++++++++++
 include/hw/misc/bcm2835_thermal.h |  27 ++++++
 3 files changed, 163 insertions(+)
 create mode 100644 hw/misc/bcm2835_thermal.c
 create mode 100644 include/hw/misc/bcm2835_thermal.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a150680966..c89f3816a5 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -53,6 +53,7 @@ common-obj-$(CONFIG_OMAP) += omap_tap.o
common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o
common-obj-$(CONFIG_RASPI) += bcm2835_property.o
common-obj-$(CONFIG_RASPI) += bcm2835_rng.o
common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
diff --git a/hw/misc/bcm2835_thermal.c b/hw/misc/bcm2835_thermal.c
new file mode 100644
index 0000000000..c6f3b1ad60
--- /dev/null
+++ b/hw/misc/bcm2835_thermal.c
@@ -0,0 +1,135 @@
/*
 * BCM2835 dummy thermal sensor
 *
 * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "hw/misc/bcm2835_thermal.h"
#include "hw/registerfields.h"
#include "migration/vmstate.h"

REG32(CTL, 0)
FIELD(CTL, POWER_DOWN, 0, 1)
FIELD(CTL, RESET, 1, 1)
FIELD(CTL, BANDGAP_CTRL, 2, 3)
FIELD(CTL, INTERRUPT_ENABLE, 5, 1)
FIELD(CTL, DIRECT, 6, 1)
FIELD(CTL, INTERRUPT_CLEAR, 7, 1)
FIELD(CTL, HOLD, 8, 10)
FIELD(CTL, RESET_DELAY, 18, 8)
FIELD(CTL, REGULATOR_ENABLE, 26, 1)

REG32(STAT, 4)
FIELD(STAT, DATA, 0, 10)
FIELD(STAT, VALID, 10, 1)
FIELD(STAT, INTERRUPT, 11, 1)

#define THERMAL_OFFSET_C 412
#define THERMAL_COEFF  (-0.538f)

static uint16_t bcm2835_thermal_temp2adc(int temp_C)
{
    return (temp_C - THERMAL_OFFSET_C) / THERMAL_COEFF;
}

static uint64_t bcm2835_thermal_read(void *opaque, hwaddr addr, unsigned size)
{
    Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);
    uint32_t val = 0;

    switch (addr) {
    case A_CTL:
        val = s->ctl;
        break;
    case A_STAT:
        /* Temperature is constantly 25°C. */
        val = FIELD_DP32(bcm2835_thermal_temp2adc(25), STAT, VALID, true);
        break;
    default:
        /* MemoryRegionOps are aligned, so this can not happen. */
        g_assert_not_reached();
    }
    return val;
}

static void bcm2835_thermal_write(void *opaque, hwaddr addr,
                                  uint64_t value, unsigned size)
{
    Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);

    switch (addr) {
    case A_CTL:
        s->ctl = value;
        break;
    case A_STAT:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: write 0x%" PRIx64
                                       " to 0x%" HWADDR_PRIx "\n",
                       __func__, value, addr);
        break;
    default:
        /* MemoryRegionOps are aligned, so this can not happen. */
        g_assert_not_reached();
    }
}

static const MemoryRegionOps bcm2835_thermal_ops = {
    .read = bcm2835_thermal_read,
    .write = bcm2835_thermal_write,
    .impl.max_access_size = 4,
    .valid.min_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void bcm2835_thermal_reset(DeviceState *dev)
{
    Bcm2835ThermalState *s = BCM2835_THERMAL(dev);

    s->ctl = 0;
}

static void bcm2835_thermal_realize(DeviceState *dev, Error **errp)
{
    Bcm2835ThermalState *s = BCM2835_THERMAL(dev);

    memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_thermal_ops,
                          s, TYPE_BCM2835_THERMAL, 8);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}

static const VMStateDescription bcm2835_thermal_vmstate = {
    .name = "bcm2835_thermal",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(ctl, Bcm2835ThermalState),
        VMSTATE_END_OF_LIST()
    }
};

static void bcm2835_thermal_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = bcm2835_thermal_realize;
    dc->reset = bcm2835_thermal_reset;
    dc->vmsd = &bcm2835_thermal_vmstate;
}

static const TypeInfo bcm2835_thermal_info = {
    .name = TYPE_BCM2835_THERMAL,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(Bcm2835ThermalState),
    .class_init = bcm2835_thermal_class_init,
};

static void bcm2835_thermal_register_types(void)
{
    type_register_static(&bcm2835_thermal_info);
}

type_init(bcm2835_thermal_register_types)
diff --git a/include/hw/misc/bcm2835_thermal.h b/include/hw/misc/bcm2835_thermal.h
new file mode 100644
index 0000000000..c3651b27ec
--- /dev/null
+++ b/include/hw/misc/bcm2835_thermal.h
@@ -0,0 +1,27 @@
/*
 * BCM2835 dummy thermal sensor
 *
 * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef HW_MISC_BCM2835_THERMAL_H
#define HW_MISC_BCM2835_THERMAL_H

#include "hw/sysbus.h"

#define TYPE_BCM2835_THERMAL "bcm2835-thermal"

#define BCM2835_THERMAL(obj) \
    OBJECT_CHECK(Bcm2835ThermalState, (obj), TYPE_BCM2835_THERMAL)

typedef struct {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/
    MemoryRegion iomem;
    uint32_t ctl;
} Bcm2835ThermalState;

#endif
-- 
2.21.0

[PATCH v3 03/16] hw/timer/bcm2835: Add the BCM2835 SYS_timer

Details
Message ID
<20191019234715.25750-4-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +205 -0
Add the 64-bit free running timer. Do not model the COMPARE register
(no IRQ generated).
This timer is used by Linux kernel and recently U-Boot:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clocksource/bcm2835_timer.c?h=v3.7
https://github.com/u-boot/u-boot/blob/v2019.07/include/configs/rpi.h#L19

Datasheet used:
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2:
- Add status/compare* registers
- Add vmstate and reset handler

checkpatch warning:
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
This is OK because the regex are:

  F: hw/*/bcm283*
  F: include/hw/*/bcm283*
---
 hw/timer/Makefile.objs            |   1 +
 hw/timer/bcm2835_systmr.c         | 166 ++++++++++++++++++++++++++++++
 hw/timer/trace-events             |   5 +
 include/hw/timer/bcm2835_systmr.h |  33 ++++++
 4 files changed, 205 insertions(+)
 create mode 100644 hw/timer/bcm2835_systmr.c
 create mode 100644 include/hw/timer/bcm2835_systmr.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 123d92c969..696cda5905 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -47,3 +47,4 @@ common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
common-obj-$(CONFIG_MSF2) += mss-timer.o
common-obj-$(CONFIG_RASPI) += bcm2835_systmr.o
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
new file mode 100644
index 0000000000..49b40b55f9
--- /dev/null
+++ b/hw/timer/bcm2835_systmr.c
@@ -0,0 +1,166 @@
/*
 * BCM2835 SYS timer emulation
 *
 * Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * Datasheet: BCM2835 ARM Peripherals (C6357-M-1398)
 * https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
 *
 * Only the free running 64-bit counter is implemented.
 * The 4 COMPARE registers and the interruption are not implemented.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/timer.h"
#include "hw/timer/bcm2835_systmr.h"
#include "hw/registerfields.h"
#include "migration/vmstate.h"
#include "trace.h"

REG32(CTRL_STATUS,  0x00)
REG32(COUNTER_LOW,  0x04)
REG32(COUNTER_HIGH, 0x08)
REG32(COMPARE0,     0x0c)
REG32(COMPARE1,     0x10)
REG32(COMPARE2,     0x14)
REG32(COMPARE3,     0x18)

static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
{
    bool enable = !!s->reg.status;

    trace_bcm2835_systmr_irq(enable);
    qemu_set_irq(s->irq, enable);
}

static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
                                          unsigned timer_index)
{
    /* TODO fow now, since neither Linux nor U-boot use these timers. */
    qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
                  timer_index);
}

static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
                                    unsigned size)
{
    BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
    uint64_t r = 0;

    switch (offset) {
    case A_CTRL_STATUS:
        r = s->reg.status;
        break;
    case A_COMPARE0 ... A_COMPARE3:
        r = s->reg.compare[(offset - A_COMPARE0) >> 2];
        break;
    case A_COUNTER_LOW:
    case A_COUNTER_HIGH:
        /* Free running counter at 1MHz */
        r = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
        r >>= 8 * (offset - A_COUNTER_LOW);
        r &= UINT32_MAX;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        break;
    }
    trace_bcm2835_systmr_read(offset, r);

    return r;
}

static void bcm2835_systmr_write(void *opaque, hwaddr offset,
                                 uint64_t value, unsigned size)
{
    BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);

    trace_bcm2835_systmr_write(offset, value);
    switch (offset) {
    case A_CTRL_STATUS:
        s->reg.status &= ~value; /* Ack */
        bcm2835_systmr_update_irq(s);
        break;
    case A_COMPARE0 ... A_COMPARE3:
        s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
        bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
        break;
    case A_COUNTER_LOW:
    case A_COUNTER_HIGH:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: read-only ofs 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad offset 0x%" HWADDR_PRIx "\n",
                      __func__, offset);
        break;
    }
}

static const MemoryRegionOps bcm2835_systmr_ops = {
    .read = bcm2835_systmr_read,
    .write = bcm2835_systmr_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void bcm2835_systmr_reset(DeviceState *dev)
{
    BCM2835SystemTimerState *s = BCM2835_SYSTIMER(dev);

    s->reg.status = 0;
    for (size_t i = 0; i < ARRAY_SIZE(s->reg.compare); i++) {
        s->reg.compare[i] = 0;
    }
}

static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
{
    BCM2835SystemTimerState *s = BCM2835_SYSTIMER(dev);

    memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
                          s, "bcm2835-sys-timer", 0x20);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
}

static const VMStateDescription bcm2835_systmr_vmstate = {
    .name = "bcm2835_sys_timer",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
        VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
        VMSTATE_END_OF_LIST()
    }
};

static void bcm2835_systmr_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = bcm2835_systmr_realize;
    dc->reset = bcm2835_systmr_reset;
    dc->vmsd = &bcm2835_systmr_vmstate;
}

static const TypeInfo bcm2835_systmr_info = {
    .name = TYPE_BCM2835_SYSTIMER,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(BCM2835SystemTimerState),
    .class_init = bcm2835_systmr_class_init,
};

static void bcm2835_systmr_register_types(void)
{
    type_register_static(&bcm2835_systmr_info);
}

type_init(bcm2835_systmr_register_types);
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index db02a9142c..0aa399ac69 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -87,3 +87,8 @@ pl031_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
pl031_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
pl031_alarm_raised(void) "alarm raised"
pl031_set_alarm(uint32_t ticks) "alarm set for %u ticks"

# bcm2835_systmr.c
bcm2835_systmr_irq(bool enable) "timer irq state %u"
bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
new file mode 100644
index 0000000000..c0bc5c8127
--- /dev/null
+++ b/include/hw/timer/bcm2835_systmr.h
@@ -0,0 +1,33 @@
/*
 * BCM2835 SYS timer emulation
 *
 * Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef BCM2835_SYSTIMER_H
#define BCM2835_SYSTIMER_H

#include "hw/sysbus.h"
#include "hw/irq.h"

#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
#define BCM2835_SYSTIMER(obj) \
    OBJECT_CHECK(BCM2835SystemTimerState, (obj), TYPE_BCM2835_SYSTIMER)

typedef struct {
    /*< private >*/
    SysBusDevice parent_obj;

    /*< public >*/
    MemoryRegion iomem;
    qemu_irq irq;

    struct {
        uint32_t status;
        uint32_t compare[4];
    } reg;
} BCM2835SystemTimerState;

#endif
-- 
2.21.0

[PATCH v3 06/16] hw/arm/bcm2836: Rename cpus[] as cpu[].core

Details
Message ID
<20191019234715.25750-7-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +17 -13
As we are going to add more core-specific fields, add a 'cpu'
structure and move the ARMCPU field there as 'core'.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2836.c         | 26 ++++++++++++++------------
 include/hw/arm/bcm2836.h |  4 +++-
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 019e67b906..221ff06895 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -51,8 +51,9 @@ static void bcm2836_init(Object *obj)
    int n;

    for (n = 0; n < BCM283X_NCPUS; n++) {
        object_initialize_child(obj, "cpu[*]", &s->cpus[n], sizeof(s->cpus[n]),
                                info->cpu_type, &error_abort, NULL);
        object_initialize_child(obj, "cpu[*]", &s->cpu[n].core,
                                sizeof(s->cpu[n].core), info->cpu_type,
                                &error_abort, NULL);
    }

    sysbus_init_child_obj(obj, "control", &s->control, sizeof(s->control),
@@ -122,10 +123,10 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)

    for (n = 0; n < BCM283X_NCPUS; n++) {
        /* TODO: this should be converted to a property of ARM_CPU */
        s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
        s->cpu[n].core.mp_affinity = (info->clusterid << 8) | n;

        /* set periphbase/CBAR value for CPU-local registers */
        object_property_set_int(OBJECT(&s->cpus[n]),
        object_property_set_int(OBJECT(&s->cpu[n].core),
                                info->peri_base,
                                "reset-cbar", &err);
        if (err) {
@@ -134,14 +135,15 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        }

        /* start powered off if not enabled */
        object_property_set_bool(OBJECT(&s->cpus[n]), n >= s->enabled_cpus,
        object_property_set_bool(OBJECT(&s->cpu[n].core), n >= s->enabled_cpus,
                                 "start-powered-off", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
        object_property_set_bool(OBJECT(&s->cpu[n].core), true,
                                 "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
@@ -149,18 +151,18 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)

        /* Connect irq/fiq outputs from the interrupt controller. */
        qdev_connect_gpio_out_named(DEVICE(&s->control), "irq", n,
                qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_IRQ));
                qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_IRQ));
        qdev_connect_gpio_out_named(DEVICE(&s->control), "fiq", n,
                qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_FIQ));
                qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_FIQ));

        /* Connect timers from the CPU to the interrupt controller */
        qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
        qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_PHYS,
                qdev_get_gpio_in_named(DEVICE(&s->control), "cntpnsirq", n));
        qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
        qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_VIRT,
                qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
        qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_HYP,
        qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_HYP,
                qdev_get_gpio_in_named(DEVICE(&s->control), "cnthpirq", n));
        qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_SEC,
        qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_SEC,
                qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
    }
}
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
index 97187f72be..92a6544816 100644
--- a/include/hw/arm/bcm2836.h
+++ b/include/hw/arm/bcm2836.h
@@ -35,7 +35,9 @@ typedef struct BCM283XState {
    char *cpu_type;
    uint32_t enabled_cpus;

    ARMCPU cpus[BCM283X_NCPUS];
    struct {
        ARMCPU core;
    } cpu[BCM283X_NCPUS];
    BCM2836ControlState control;
    BCM2835PeripheralState peripherals;
} BCM283XState;
-- 
2.21.0

[PATCH v3 02/16] hw/arm/bcm2835_peripherals: Use the thermal sensor block

Details
Message ID
<20191019234715.25750-3-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +16 -0
Map the thermal sensor in the BCM2835 block.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2835_peripherals.c         | 13 +++++++++++++
 include/hw/arm/bcm2835_peripherals.h |  2 ++
 include/hw/arm/raspi_platform.h      |  1 +
 3 files changed, 16 insertions(+)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index fdcf616c56..70bf927a02 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -111,6 +111,10 @@ static void bcm2835_peripherals_init(Object *obj)
    object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
                                   OBJECT(&s->gpu_bus_mr), &error_abort);

    /* Thermal */
    sysbus_init_child_obj(obj, "thermal", &s->thermal, sizeof(s->thermal),
                          TYPE_BCM2835_THERMAL);

    /* GPIO */
    sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
                          TYPE_BCM2835_GPIO);
@@ -321,6 +325,15 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                                                  INTERRUPT_DMA0 + n));
    }

    /* THERMAL */
    object_property_set_bool(OBJECT(&s->thermal), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(&s->peri_mr, THERMAL_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->thermal), 0));

    /* GPIO */
    object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
    if (err) {
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 62a4c7b559..be7ad9b499 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -20,6 +20,7 @@
#include "hw/misc/bcm2835_property.h"
#include "hw/misc/bcm2835_rng.h"
#include "hw/misc/bcm2835_mbox.h"
#include "hw/misc/bcm2835_thermal.h"
#include "hw/sd/sdhci.h"
#include "hw/sd/bcm2835_sdhost.h"
#include "hw/gpio/bcm2835_gpio.h"
@@ -53,6 +54,7 @@ typedef struct BCM2835PeripheralState {
    SDHCIState sdhci;
    BCM2835SDHostState sdhost;
    BCM2835GpioState gpio;
    Bcm2835ThermalState thermal;
    UnimplementedDeviceState i2s;
    UnimplementedDeviceState spi[1];
    UnimplementedDeviceState i2c[3];
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
index cdcbca943f..61b04a1bd4 100644
--- a/include/hw/arm/raspi_platform.h
+++ b/include/hw/arm/raspi_platform.h
@@ -48,6 +48,7 @@
#define SPI0_OFFSET             0x204000
#define BSC0_OFFSET             0x205000 /* BSC0 I2C/TWI */
#define OTP_OFFSET              0x20f000
#define THERMAL_OFFSET          0x212000
#define BSC_SL_OFFSET           0x214000 /* SPI slave */
#define AUX_OFFSET              0x215000 /* AUX: UART1/SPI1/SPI2 */
#define EMMC1_OFFSET            0x300000
-- 
2.21.0

[PATCH v3 04/16] hw/arm/bcm2835_peripherals: Use the SYS_timer

Details
Message ID
<20191019234715.25750-5-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +18 -2
Connect the recently added SYS_timer.
Now U-Boot does not hang anymore polling a free running counter
stuck at 0.
This timer is also used by the Linux kernel thermal subsystem.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2: Remove spurious error check (Alex)
---
 hw/arm/bcm2835_peripherals.c         | 17 ++++++++++++++++-
 include/hw/arm/bcm2835_peripherals.h |  3 ++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 70bf927a02..17207ae07e 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -58,6 +58,10 @@ static void bcm2835_peripherals_init(Object *obj)
    /* Interrupt Controller */
    sysbus_init_child_obj(obj, "ic", &s->ic, sizeof(s->ic), TYPE_BCM2835_IC);

    /* SYS Timer */
    sysbus_init_child_obj(obj, "systimer", &s->systmr, sizeof(s->systmr),
                          TYPE_BCM2835_SYSTIMER);

    /* UART0 */
    sysbus_init_child_obj(obj, "uart0", &s->uart0, sizeof(s->uart0),
                          TYPE_PL011);
@@ -171,6 +175,18 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ic), 0));
    sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));

    /* Sys Timer */
    object_property_set_bool(OBJECT(&s->systmr), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
                               INTERRUPT_ARM_TIMER));

    /* UART0 */
    qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
    object_property_set_bool(OBJECT(&s->uart0), true, "realized", &err);
@@ -352,7 +368,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
    }

    create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
    create_unimp(s, &s->systmr, "bcm2835-systimer", ST_OFFSET, 0x20);
    create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
    create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
    create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index be7ad9b499..7859281e11 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -24,6 +24,7 @@
#include "hw/sd/sdhci.h"
#include "hw/sd/bcm2835_sdhost.h"
#include "hw/gpio/bcm2835_gpio.h"
#include "hw/timer/bcm2835_systmr.h"
#include "hw/misc/unimp.h"

#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
@@ -39,7 +40,7 @@ typedef struct BCM2835PeripheralState {
    MemoryRegion ram_alias[4];
    qemu_irq irq, fiq;

    UnimplementedDeviceState systmr;
    BCM2835SystemTimerState systmr;
    UnimplementedDeviceState armtmr;
    UnimplementedDeviceState cprman;
    UnimplementedDeviceState a2w;
-- 
2.21.0

[PATCH v3 05/16] hw/arm/bcm2836: Make the SoC code modular

Details
Message ID
<20191019234715.25750-6-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +9 -9
This file creates the BCM2836/BCM2837 blocks.
The biggest differences with the BCM2838 we are going to add, are
the base addresses of the interrupt controller and the peripherals.
Add these addresses in the BCM283XInfo structure to make this
block more modular. Remove the MCORE_OFFSET offset as it is
not useful and rather confusing.

Reviewed-by: Esteban Bosse <estebanbosse@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2836.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 723aef6bf5..019e67b906 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -16,15 +16,11 @@
#include "hw/arm/raspi_platform.h"
#include "hw/sysbus.h"

/* Peripheral base address seen by the CPU */
#define BCM2836_PERI_BASE       0x3F000000

/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
#define BCM2836_CONTROL_BASE    0x40000000

struct BCM283XInfo {
    const char *name;
    const char *cpu_type;
    hwaddr peri_base; /* Peripheral base address seen by the CPU */
    hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */
    int clusterid;
};

@@ -32,12 +28,16 @@ static const BCM283XInfo bcm283x_socs[] = {
    {
        .name = TYPE_BCM2836,
        .cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"),
        .peri_base = 0x3f000000,
        .ctrl_base = 0x40000000,
        .clusterid = 0xf,
    },
#ifdef TARGET_AARCH64
    {
        .name = TYPE_BCM2837,
        .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
        .peri_base = 0x3f000000,
        .ctrl_base = 0x40000000,
        .clusterid = 0x0,
    },
#endif
@@ -104,7 +104,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
    }

    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
                            BCM2836_PERI_BASE, 1);
                            info->peri_base, 1);

    /* bcm2836 interrupt controller (and mailboxes, etc.) */
    object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
@@ -113,7 +113,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        return;
    }

    sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, BCM2836_CONTROL_BASE);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, info->ctrl_base);

    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
        qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
@@ -126,7 +126,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)

        /* set periphbase/CBAR value for CPU-local registers */
        object_property_set_int(OBJECT(&s->cpus[n]),
                                BCM2836_PERI_BASE + MSYNC_OFFSET,
                                info->peri_base,
                                "reset-cbar", &err);
        if (err) {
            error_propagate(errp, err);
-- 
2.21.0

[PATCH v3 11/16] hw/arm/raspi: Use -smp cores=<N> option to restrict enabled cores

Details
Message ID
<20191019234715.25750-12-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +2 -2
The abstract TYPE_BCM283X device provides a 'enabled-cpus' property
to restrict the number of cores powered on reset. This because on
real hardware the GPU is responsible of starting the cores and keep
them spinning until the Linux kernel is ready to use them.
When using the -kernel paramenter, QEMU does this by installing the
'raspi_smpboot' code when arm_boot_info::write_board_setup() is
called. This is a special feature to help the Linux kernel, and can
only be used with a Linux kernel.

Even if loaded with the -kernel option, U-boot is not Linux, thus
is not recognized as it and the raspi_smpboot code is not installed.

Upon introduction of this machine in commit 1df7d1f9303, the -smp <N>
option allowd to limit the number of cores powered on reset.
Unfortunately later commit 72649619341 added a check which made this
feature unusable:

  $ qemu-system-aarch64 -M raspi3 -smp 1
  qemu-system-aarch64: Invalid SMP CPUs 1. The min CPUs supported by machine 'raspi3' is 4

Fortunately, the -smp option allow various kind of CPU topology:

  -smp [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,dies=dies][,sockets=sockets]
           set the number of CPUs to 'n' [default=1]
           maxcpus= maximum number of total cpus, including
           offline CPUs for hotplug, etc
           cores= number of CPU cores on one socket (for PC, it's on one die)
           threads= number of threads on one CPU core
           dies= number of CPU dies on one socket (for PC only)
           sockets= number of discrete sockets in the system

Let's use the 'cores' argument to specify the number of cores powered
at reset to restore this feature, and allow to boot U-boot.

We can now run U-boot using:

  $ qemu-system-aarch64 -M raspi3 -smp 4,cores=1 ...

Reported-by: Laurent Bonnans <laurent.bonnans@here.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/raspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 569d85c11a..45d3f91f95 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -190,8 +190,8 @@ static void raspi_init(MachineState *machine, int version)
    /* Setup the SOC */
    object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
                                   &error_abort);
    object_property_set_int(OBJECT(&s->soc), machine->smp.cpus, "enabled-cpus",
                            &error_abort);
    object_property_set_int(OBJECT(&s->soc), machine->smp.cores,
                            "enabled-cpus", &error_abort);
    int board_rev = version == 3 ? 0xa02082 : 0xa21041;
    object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
                            &error_abort);
-- 
2.21.0

[PATCH v3 07/16] hw/arm/bcm2836: Use per CPU address spaces

Details
Message ID
<20191019234715.25750-8-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +38 -7
Currently all CPUs access the main system bus. Let each CPU have
his own address space.

Before:

  (qemu) info mtree
  address-space: memory
    0000000000000000-ffffffffffffffff (prio 0, i/o): system
      0000000000000000-000000003fffffff (prio 0, ram): ram
      000000003f000000-000000003fffffff (prio 1, i/o): bcm2835-peripherals
        000000003f003000-000000003f00301f (prio 0, i/o): bcm2835-sys-timer
        000000003f007000-000000003f007fff (prio 0, i/o): bcm2835-dma
        000000003f00b200-000000003f00b3ff (prio 0, i/o): bcm2835-ic
        000000003f00b400-000000003f00b43f (prio -1000, i/o): bcm2835-sp804
        000000003f00b800-000000003f00bbff (prio 0, i/o): bcm2835-mbox
        000000003f100000-000000003f100fff (prio -1000, i/o): bcm2835-cprman
        000000003f102000-000000003f102fff (prio -1000, i/o): bcm2835-a2w
        000000003f104000-000000003f10400f (prio 0, i/o): bcm2835-rng
        000000003f200000-000000003f200fff (prio 0, i/o): bcm2835_gpio
        000000003f201000-000000003f201fff (prio 0, i/o): pl011
        000000003f202000-000000003f202fff (prio 0, i/o): bcm2835-sdhost
        000000003f203000-000000003f2030ff (prio -1000, i/o): bcm2835-i2s
        000000003f204000-000000003f20401f (prio -1000, i/o): bcm2835-spi0
        000000003f205000-000000003f20501f (prio -1000, i/o): bcm2835-i2c0
        000000003f20f000-000000003f20f07f (prio -1000, i/o): bcm2835-otp
        000000003f212000-000000003f212007 (prio 0, i/o): bcm2835-thermal
        000000003f214000-000000003f2140ff (prio -1000, i/o): bcm2835-spis
        000000003f215000-000000003f2150ff (prio 0, i/o): bcm2835-aux
        000000003f300000-000000003f3000ff (prio 0, i/o): sdhci
        000000003f600000-000000003f6000ff (prio -1000, i/o): bcm2835-smi
        000000003f804000-000000003f80401f (prio -1000, i/o): bcm2835-i2c1
        000000003f805000-000000003f80501f (prio -1000, i/o): bcm2835-i2c2
        000000003f900000-000000003f907fff (prio -1000, i/o): bcm2835-dbus
        000000003f910000-000000003f917fff (prio -1000, i/o): bcm2835-ave0
        000000003f980000-000000003f980fff (prio -1000, i/o): dwc-usb2
        000000003fe00000-000000003fe000ff (prio -1000, i/o): bcm2835-sdramc
        000000003fe05000-000000003fe050ff (prio 0, i/o): bcm2835-dma-chan15
      0000000040000000-00000000400000ff (prio 0, i/o): bcm2836-control

  address-space: cpu-secure-memory-0
    0000000000000000-ffffffffffffffff (prio 0, i/o): system
      0000000000000000-000000003fffffff (prio 0, ram): ram
      000000003f000000-000000003fffffff (prio 1, i/o): bcm2835-peripherals
        000000003f003000-000000003f00301f (prio 0, i/o): bcm2835-sys-timer
        000000003f007000-000000003f007fff (prio 0, i/o): bcm2835-dma
        000000003f00b200-000000003f00b3ff (prio 0, i/o): bcm2835-ic
        000000003f00b400-000000003f00b43f (prio -1000, i/o): bcm2835-sp804
        000000003f00b800-000000003f00bbff (prio 0, i/o): bcm2835-mbox
        000000003f100000-000000003f100fff (prio -1000, i/o): bcm2835-cprman
        000000003f102000-000000003f102fff (prio -1000, i/o): bcm2835-a2w
        000000003f104000-000000003f10400f (prio 0, i/o): bcm2835-rng
        000000003f200000-000000003f200fff (prio 0, i/o): bcm2835_gpio
        000000003f201000-000000003f201fff (prio 0, i/o): pl011
        000000003f202000-000000003f202fff (prio 0, i/o): bcm2835-sdhost
        000000003f203000-000000003f2030ff (prio -1000, i/o): bcm2835-i2s
        000000003f204000-000000003f20401f (prio -1000, i/o): bcm2835-spi0
        000000003f205000-000000003f20501f (prio -1000, i/o): bcm2835-i2c0
        000000003f20f000-000000003f20f07f (prio -1000, i/o): bcm2835-otp
        000000003f212000-000000003f212007 (prio 0, i/o): bcm2835-thermal
        000000003f214000-000000003f2140ff (prio -1000, i/o): bcm2835-spis
        000000003f215000-000000003f2150ff (prio 0, i/o): bcm2835-aux
        000000003f300000-000000003f3000ff (prio 0, i/o): sdhci
        000000003f600000-000000003f6000ff (prio -1000, i/o): bcm2835-smi
        000000003f804000-000000003f80401f (prio -1000, i/o): bcm2835-i2c1
        000000003f805000-000000003f80501f (prio -1000, i/o): bcm2835-i2c2
        000000003f900000-000000003f907fff (prio -1000, i/o): bcm2835-dbus
        000000003f910000-000000003f917fff (prio -1000, i/o): bcm2835-ave0
        000000003f980000-000000003f980fff (prio -1000, i/o): dwc-usb2
        000000003fe00000-000000003fe000ff (prio -1000, i/o): bcm2835-sdramc
        000000003fe05000-000000003fe050ff (prio 0, i/o): bcm2835-dma-chan15
      0000000040000000-00000000400000ff (prio 0, i/o): bcm2836-control

  address-space: cpu-memory-0
    0000000000000000-ffffffffffffffff (prio 0, i/o): system
      0000000000000000-000000003fffffff (prio 0, ram): ram
      000000003f000000-000000003fffffff (prio 1, i/o): bcm2835-peripherals
        000000003f003000-000000003f00301f (prio 0, i/o): bcm2835-sys-timer
        000000003f007000-000000003f007fff (prio 0, i/o): bcm2835-dma
        000000003f00b200-000000003f00b3ff (prio 0, i/o): bcm2835-ic
        000000003f00b400-000000003f00b43f (prio -1000, i/o): bcm2835-sp804
        000000003f00b800-000000003f00bbff (prio 0, i/o): bcm2835-mbox
        000000003f100000-000000003f100fff (prio -1000, i/o): bcm2835-cprman
        000000003f102000-000000003f102fff (prio -1000, i/o): bcm2835-a2w
        000000003f104000-000000003f10400f (prio 0, i/o): bcm2835-rng
        000000003f200000-000000003f200fff (prio 0, i/o): bcm2835_gpio
        000000003f201000-000000003f201fff (prio 0, i/o): pl011
        000000003f202000-000000003f202fff (prio 0, i/o): bcm2835-sdhost
        000000003f203000-000000003f2030ff (prio -1000, i/o): bcm2835-i2s
        000000003f204000-000000003f20401f (prio -1000, i/o): bcm2835-spi0
        000000003f205000-000000003f20501f (prio -1000, i/o): bcm2835-i2c0
        000000003f20f000-000000003f20f07f (prio -1000, i/o): bcm2835-otp
        000000003f212000-000000003f212007 (prio 0, i/o): bcm2835-thermal
        000000003f214000-000000003f2140ff (prio -1000, i/o): bcm2835-spis
        000000003f215000-000000003f2150ff (prio 0, i/o): bcm2835-aux
        000000003f300000-000000003f3000ff (prio 0, i/o): sdhci
        000000003f600000-000000003f6000ff (prio -1000, i/o): bcm2835-smi
        000000003f804000-000000003f80401f (prio -1000, i/o): bcm2835-i2c1
        000000003f805000-000000003f80501f (prio -1000, i/o): bcm2835-i2c2
        000000003f900000-000000003f907fff (prio -1000, i/o): bcm2835-dbus
        000000003f910000-000000003f917fff (prio -1000, i/o): bcm2835-ave0
        000000003f980000-000000003f980fff (prio -1000, i/o): dwc-usb2
        000000003fe00000-000000003fe000ff (prio -1000, i/o): bcm2835-sdramc
        000000003fe05000-000000003fe050ff (prio 0, i/o): bcm2835-dma-chan15
      0000000040000000-00000000400000ff (prio 0, i/o): bcm2836-control

  memory-region: ram
    0000000000000000-000000003fffffff (prio 0, ram): ram

  memory-region: bcm2835-peripherals
    000000003f000000-000000003fffffff (prio 1, i/o): bcm2835-peripherals
      000000003f003000-000000003f00301f (prio 0, i/o): bcm2835-sys-timer
      000000003f007000-000000003f007fff (prio 0, i/o): bcm2835-dma
      000000003f00b200-000000003f00b3ff (prio 0, i/o): bcm2835-ic
      000000003f00b400-000000003f00b43f (prio -1000, i/o): bcm2835-sp804
      000000003f00b800-000000003f00bbff (prio 0, i/o): bcm2835-mbox
      000000003f100000-000000003f100fff (prio -1000, i/o): bcm2835-cprman
      000000003f102000-000000003f102fff (prio -1000, i/o): bcm2835-a2w
      000000003f104000-000000003f10400f (prio 0, i/o): bcm2835-rng
      000000003f200000-000000003f200fff (prio 0, i/o): bcm2835_gpio
      000000003f201000-000000003f201fff (prio 0, i/o): pl011
      000000003f202000-000000003f202fff (prio 0, i/o): bcm2835-sdhost
      000000003f203000-000000003f2030ff (prio -1000, i/o): bcm2835-i2s
      000000003f204000-000000003f20401f (prio -1000, i/o): bcm2835-spi0
      000000003f205000-000000003f20501f (prio -1000, i/o): bcm2835-i2c0
      000000003f20f000-000000003f20f07f (prio -1000, i/o): bcm2835-otp
      000000003f212000-000000003f212007 (prio 0, i/o): bcm2835-thermal
      000000003f214000-000000003f2140ff (prio -1000, i/o): bcm2835-spis
      000000003f215000-000000003f2150ff (prio 0, i/o): bcm2835-aux
      000000003f300000-000000003f3000ff (prio 0, i/o): sdhci
      000000003f600000-000000003f6000ff (prio -1000, i/o): bcm2835-smi
      000000003f804000-000000003f80401f (prio -1000, i/o): bcm2835-i2c1
      000000003f805000-000000003f80501f (prio -1000, i/o): bcm2835-i2c2
      000000003f900000-000000003f907fff (prio -1000, i/o): bcm2835-dbus
      000000003f910000-000000003f917fff (prio -1000, i/o): bcm2835-ave0
      000000003f980000-000000003f980fff (prio -1000, i/o): dwc-usb2
      000000003fe00000-000000003fe000ff (prio -1000, i/o): bcm2835-sdramc
      000000003fe05000-000000003fe050ff (prio 0, i/o): bcm2835-dma-chan15

After:

  (qemu) info mtree
  address-space: memory
    0000000000000000-ffffffffffffffff (prio 0, i/o): system

  address-space: cpu-secure-memory-0
    0000000000000000-00000000ffffffff (prio 0, i/o): cpu-bus
      0000000000000000-000000003fffffff (prio 1, i/o): alias arm-ram @ram 0000000000000000-000000003fffffff
      000000003f000000-000000003fffffff (prio 2, i/o): alias arm-peripherals @bcm2835-peripherals 0000000000000000-0000000000ffffff
      0000000040000000-0000000040003fff (prio 2, i/o): alias arm-control @bcm2836-control 0000000000000000-0000000000003fff

  address-space: cpu-memory-0
    0000000000000000-00000000ffffffff (prio 0, i/o): cpu-bus
      0000000000000000-000000003fffffff (prio 1, i/o): alias arm-ram @ram 0000000000000000-000000003fffffff
      000000003f000000-000000003fffffff (prio 2, i/o): alias arm-peripherals @bcm2835-peripherals 0000000000000000-0000000000ffffff
      0000000040000000-0000000040003fff (prio 2, i/o): alias arm-control @bcm2836-control 0000000000000000-0000000000003fff

  memory-region: ram
    0000000000000000-000000003fffffff (prio 0, ram): ram

  memory-region: bcm2835-peripherals
    0000000000000000-0000000000ffffff (prio 0, i/o): bcm2835-peripherals
      0000000000003000-000000000000301f (prio 0, i/o): bcm2835-sys-timer
      0000000000007000-0000000000007fff (prio 0, i/o): bcm2835-dma
      000000000000b200-000000000000b3ff (prio 0, i/o): bcm2835-ic
      000000000000b400-000000000000b43f (prio -1000, i/o): bcm2835-sp804
      000000000000b800-000000000000bbff (prio 0, i/o): bcm2835-mbox
      0000000000100000-0000000000100fff (prio -1000, i/o): bcm2835-cprman
      0000000000102000-0000000000102fff (prio -1000, i/o): bcm2835-a2w
      0000000000104000-000000000010400f (prio 0, i/o): bcm2835-rng
      0000000000200000-0000000000200fff (prio 0, i/o): bcm2835_gpio
      0000000000201000-0000000000201fff (prio 0, i/o): pl011
      0000000000202000-0000000000202fff (prio 0, i/o): bcm2835-sdhost
      0000000000203000-00000000002030ff (prio -1000, i/o): bcm2835-i2s
      0000000000204000-000000000020401f (prio -1000, i/o): bcm2835-spi0
      0000000000205000-000000000020501f (prio -1000, i/o): bcm2835-i2c0
      000000000020f000-000000000020f07f (prio -1000, i/o): bcm2835-otp
      0000000000212000-0000000000212007 (prio 0, i/o): bcm2835-thermal
      0000000000214000-00000000002140ff (prio -1000, i/o): bcm2835-spis
      0000000000215000-00000000002150ff (prio 0, i/o): bcm2835-aux
      0000000000300000-00000000003000ff (prio 0, i/o): sdhci
      0000000000600000-00000000006000ff (prio -1000, i/o): bcm2835-smi
      0000000000804000-000000000080401f (prio -1000, i/o): bcm2835-i2c1
      0000000000805000-000000000080501f (prio -1000, i/o): bcm2835-i2c2
      0000000000900000-0000000000907fff (prio -1000, i/o): bcm2835-dbus
      0000000000910000-0000000000917fff (prio -1000, i/o): bcm2835-ave0
      0000000000980000-0000000000980fff (prio -1000, i/o): dwc-usb2
      0000000000e00000-0000000000e000ff (prio -1000, i/o): bcm2835-sdramc
      0000000000e05000-0000000000e050ff (prio 0, i/o): bcm2835-dma-chan15

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2836.c         | 39 ++++++++++++++++++++++++++++++++++-----
 hw/arm/raspi.c           |  2 --
 include/hw/arm/bcm2836.h |  4 ++++
 3 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 221ff06895..374a44b38c 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -9,6 +9,7 @@
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "cpu.h"
@@ -51,6 +52,8 @@ static void bcm2836_init(Object *obj)
    int n;

    for (n = 0; n < BCM283X_NCPUS; n++) {
        memory_region_init(&s->cpu[n].container, obj, "cpu-bus", 4 * GiB);

        object_initialize_child(obj, "cpu[*]", &s->cpu[n].core,
                                sizeof(s->cpu[n].core), info->cpu_type,
                                &error_abort, NULL);
@@ -72,9 +75,11 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
    BCM283XState *s = BCM283X(dev);
    BCM283XClass *bc = BCM283X_GET_CLASS(dev);
    const BCM283XInfo *info = bc->info;
    MemoryRegion *ram_mr, *peri_mr, *ctrl_mr;
    Object *obj;
    Error *err = NULL;
    int n;
    uint64_t ram_size;

    /* common peripherals from bcm2835 */

@@ -84,13 +89,14 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
                   __func__, error_get_pretty(err));
        return;
    }
    ram_mr = MEMORY_REGION(obj);
    ram_size = memory_region_size(ram_mr);

    object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
@@ -104,8 +110,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        return;
    }

    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
                            info->peri_base, 1);
    peri_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->peripherals), 0);

    /* bcm2836 interrupt controller (and mailboxes, etc.) */
    object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
@@ -113,8 +118,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        error_propagate(errp, err);
        return;
    }

    sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, info->ctrl_base);
    ctrl_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->control), 0);

    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
        qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
@@ -122,6 +126,31 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));

    for (n = 0; n < BCM283X_NCPUS; n++) {
        memory_region_init_alias(&s->cpu[n].ram_alias, OBJECT(s),
                                 "arm-ram", ram_mr, 0, ram_size);
        memory_region_add_subregion_overlap(&s->cpu[n].container, 0,
                                            &s->cpu[n].ram_alias, 1);

        memory_region_init_alias(&s->cpu[n].peri_alias, OBJECT(s),
                                 "arm-peripherals", peri_mr, 0, 16 * MiB);
        memory_region_add_subregion_overlap(&s->cpu[n].container,
                                            info->peri_base,
                                            &s->cpu[n].peri_alias, 2);

        memory_region_init_alias(&s->cpu[n].control_alias, OBJECT(s),
                                 "arm-control", ctrl_mr, 0, 16 * KiB);
        memory_region_add_subregion_overlap(&s->cpu[n].container,
                                            info->ctrl_base,
                                            &s->cpu[n].control_alias, 2);

        object_property_set_link(OBJECT(&s->cpu[n].core),
                                 OBJECT(&s->cpu[n].container),
                                 "memory", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        /* TODO: this should be converted to a property of ARM_CPU */
        s->cpu[n].core.mp_affinity = (info->clusterid << 8) | n;

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 615d755879..a12459bc41 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -184,8 +184,6 @@ static void raspi_init(MachineState *machine, int version)
    /* Allocate and map RAM */
    memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
                                         machine->ram_size);
    /* FIXME: Remove when we have custom CPU address space support */
    memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0);

    /* Setup the SOC */
    object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
index 92a6544816..e3498cb861 100644
--- a/include/hw/arm/bcm2836.h
+++ b/include/hw/arm/bcm2836.h
@@ -37,6 +37,10 @@ typedef struct BCM283XState {

    struct {
        ARMCPU core;
        MemoryRegion container;
        MemoryRegion ram_alias;
        MemoryRegion peri_alias;
        MemoryRegion control_alias;
    } cpu[BCM283X_NCPUS];
    BCM2836ControlState control;
    BCM2835PeripheralState peripherals;
-- 
2.21.0

[PATCH v3 08/16] hw/arm/bcm2835_peripherals: Add const link property in realize()

Details
Message ID
<20191019234715.25750-9-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +17 -8
The VideoCore GPU is indenpendant from the Peripheral block. In
the next commit, we will move its instantiation to the SoC block.
The "gpu-bus" object will not be accessible in init() but later
in realize(). As a preliminary step to keep the diff clearer, move
the const link property creation from init() to realize().

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2835_peripherals.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 17207ae07e..d51e9c8def 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -82,9 +82,6 @@ static void bcm2835_peripherals_init(Object *obj)
    object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size",
                              &error_abort);

    object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
                                   OBJECT(&s->gpu_bus_mr), &error_abort);

    /* Property channel */
    sysbus_init_child_obj(obj, "property", &s->property, sizeof(s->property),
                          TYPE_BCM2835_PROPERTY);
@@ -93,8 +90,6 @@ static void bcm2835_peripherals_init(Object *obj)

    object_property_add_const_link(OBJECT(&s->property), "fb",
                                   OBJECT(&s->fb), &error_abort);
    object_property_add_const_link(OBJECT(&s->property), "dma-mr",
                                   OBJECT(&s->gpu_bus_mr), &error_abort);

    /* Random Number Generator */
    sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
@@ -112,9 +107,6 @@ static void bcm2835_peripherals_init(Object *obj)
    sysbus_init_child_obj(obj, "dma", &s->dma, sizeof(s->dma),
                          TYPE_BCM2835_DMA);

    object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
                                   OBJECT(&s->gpu_bus_mr), &error_abort);

    /* Thermal */
    sysbus_init_child_obj(obj, "thermal", &s->thermal, sizeof(s->thermal),
                          TYPE_BCM2835_THERMAL);
@@ -156,6 +148,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
    memory_region_add_subregion_overlap(&s->gpu_bus_mr, BCM2835_VC_PERI_BASE,
                                        &s->peri_mr_alias, 1);

    obj = OBJECT(&s->gpu_bus_mr);
    /* RAM is aliased four times (different cache configurations) on the GPU */
    for (n = 0; n < 4; n++) {
        memory_region_init_alias(&s->ram_alias[n], OBJECT(s),
@@ -236,6 +229,12 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
        return;
    }

    object_property_add_const_link(OBJECT(&s->fb), "dma-mr", obj, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_uint(OBJECT(&s->fb), ram_size - vcram_size,
                             "vcram-base", &err);
    if (err) {
@@ -255,6 +254,11 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                       qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));

    /* Property channel */
    object_property_add_const_link(OBJECT(&s->property), "dma-mr", obj, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_bool(OBJECT(&s->property), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
@@ -323,6 +327,11 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                               INTERRUPT_SDIO));

    /* DMA Channels */
    object_property_add_const_link(OBJECT(&s->dma), "dma-mr", obj, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_bool(OBJECT(&s->dma), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
-- 
2.21.0

[PATCH v3 09/16] hw/arm/bcm2836: Create VideoCore address space in the SoC

Details
Message ID
<20191019234715.25750-10-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +53 -21
Currently the VideoCore is created in the Peripheral container
as the 'GPU bus'. It is created there because the peripherals
using DMA use physical addresses from the VideoCore bus.
However the VideoCore is a GPU core placed at the same
hierarchical level than the ARM cores.

To match the datasheet design, create the VideoCore container
in the SoC, and link it to the peripheral container.

The VideoCore bus is 1GiB wide, accessible at 4 regions in
different cache configurations. Add the full mapping.

Before this commit the memory tree is:

 (qemu) info mtree
 address-space: bcm2835-dma-memory
   0000000000000000-00000000ffffffff (prio 0, i/o): bcm2835-gpu
     0000000000000000-000000003fffffff (prio 0, i/o): alias bcm2835-gpu-ram-alias[*] @ram 0000000000000000-000000003fffffff
     0000000040000000-000000007fffffff (prio 0, i/o): alias bcm2835-gpu-ram-alias[*] @ram 0000000000000000-000000003fffffff
     000000007e000000-000000007effffff (prio 1, i/o): alias bcm2835-peripherals @bcm2835-peripherals 0000000000000000-0000000000ffffff
     0000000080000000-00000000bfffffff (prio 0, i/o): alias bcm2835-gpu-ram-alias[*] @ram 0000000000000000-000000003fffffff
     00000000c0000000-00000000ffffffff (prio 0, i/o): alias bcm2835-gpu-ram-alias[*] @ram 0000000000000000-000000003fffffff

After:

 address-space: bcm2835-dma-memory
   0000000000000000-00000000ffffffff (prio 0, i/o): gpu-bus
     0000000000000000-000000003fffffff (prio 0, i/o): alias l1-l2-cached @videocore 0000000000000000-000000003fffffff
     0000000040000000-000000007fffffff (prio 0, i/o): alias l2-cached-coherent @videocore 0000000000000000-000000003fffffff
     0000000080000000-00000000bfffffff (prio 0, i/o): alias l2-cached @videocore 0000000000000000-000000003fffffff
     00000000c0000000-00000000ffffffff (prio 0, i/o): alias direct-uncached @videocore 0000000000000000-000000003fffffff

 memory-region: videocore
   0000000000000000-000000003fffffff (prio 0, i/o): videocore
     0000000000000000-000000003fffffff (prio 0, i/o): alias vc-ram @ram 0000000000000000-000000003fffffff
     000000003e000000-000000003effffff (prio 1, i/o): alias vc-peripherals @bcm2835-peripherals 0000000000000000-0000000000ffffff

Now the periferals are accessible from the uncached region too.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/arm/bcm2835_peripherals.c         | 25 +++++-------------
hw/arm/bcm2836.c                     | 38 ++++++++++++++++++++++++++++
include/hw/arm/bcm2835_peripherals.h |  4 +--
include/hw/arm/bcm2836.h             |  7 +++++
4 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index d51e9c8def..5da310efb1 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -9,6 +9,7 @@
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "hw/arm/bcm2835_peripherals.h"
@@ -45,10 +46,6 @@ static void bcm2835_peripherals_init(Object *obj)
    object_property_add_child(obj, "peripheral-io", OBJECT(&s->peri_mr), NULL);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);

    /* Internal memory region for peripheral bus addresses (not exported) */
    memory_region_init(&s->gpu_bus_mr, obj, "bcm2835-gpu", (uint64_t)1 << 32);
    object_property_add_child(obj, "gpu-bus", OBJECT(&s->gpu_bus_mr), NULL);

    /* Internal memory region for request/response communication with
     * mailbox-addressable peripherals (not exported)
     */
@@ -140,21 +137,11 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
    ram = MEMORY_REGION(obj);
    ram_size = memory_region_size(ram);

    /* Map peripherals and RAM into the GPU address space. */
    memory_region_init_alias(&s->peri_mr_alias, OBJECT(s),
                             "bcm2835-peripherals", &s->peri_mr, 0,
                             memory_region_size(&s->peri_mr));

    memory_region_add_subregion_overlap(&s->gpu_bus_mr, BCM2835_VC_PERI_BASE,
                                        &s->peri_mr_alias, 1);

    obj = OBJECT(&s->gpu_bus_mr);
    /* RAM is aliased four times (different cache configurations) on the GPU */
    for (n = 0; n < 4; n++) {
        memory_region_init_alias(&s->ram_alias[n], OBJECT(s),
                                 "bcm2835-gpu-ram-alias[*]", ram, 0, ram_size);
        memory_region_add_subregion_overlap(&s->gpu_bus_mr, (hwaddr)n << 30,
                                            &s->ram_alias[n], 0);
    obj = object_property_get_link(OBJECT(dev), "videocore-bus", &err);
    if (obj == NULL) {
        error_setg(errp, "%s: required videocore-bus link not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    /* Interrupt Controller */
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 374a44b38c..ada35e5620 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -51,6 +51,14 @@ static void bcm2836_init(Object *obj)
    const BCM283XInfo *info = bc->info;
    int n;

    /* VideoCore memory region */
    memory_region_init(&s->vc.gpu, obj, "videocore", 1 * GiB);
    object_property_add_child(obj, "videocore", OBJECT(&s->vc.gpu), NULL);

    /* Internal memory region for peripheral bus addresses (not exported) */
    memory_region_init(&s->vc.bus, obj, "gpu-bus", 4 * GiB);
    object_property_add_child(obj, "gpu-bus", OBJECT(&s->vc.bus), NULL);

    for (n = 0; n < BCM283X_NCPUS; n++) {
        memory_region_init(&s->cpu[n].container, obj, "cpu-bus", 4 * GiB);

@@ -97,6 +105,12 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        error_propagate(errp, err);
        return;
    }
    object_property_add_const_link(OBJECT(&s->peripherals), "videocore-bus",
                                   OBJECT(&s->vc.bus), &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
@@ -112,6 +126,30 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)

    peri_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->peripherals), 0);

    /* Map peripherals and RAM into the GPU address space. */
    memory_region_init_alias(&s->vc.peri_alias, OBJECT(s),
                             "vc-peripherals", peri_mr, 0,
                             memory_region_size(peri_mr));
    memory_region_add_subregion_overlap(&s->vc.gpu, 0x3e000000,
                                        &s->vc.peri_alias, 1);
    memory_region_init_alias(&s->vc.ram_alias, OBJECT(s),
                             "vc-ram", ram_mr, 0, ram_size);
    memory_region_add_subregion(&s->vc.gpu, 0,
                                &s->vc.ram_alias);
    static const char * const bus_alias_name[] = {
        "l1-l2-cached",
        "l2-cached-coherent",
        "l2-cached",
        "direct-uncached"
    };
    /* Alias different cache configurations on the GPU */
    for (n = 0; n < ARRAY_SIZE(bus_alias_name); n++) {
        memory_region_init_alias(&s->vc.gpu_alias[n], OBJECT(s),
                                 bus_alias_name[n], &s->vc.gpu, 0, 1 * GiB);
        memory_region_add_subregion(&s->vc.bus, n * GiB,
                                    &s->vc.gpu_alias[n]);
    }

    /* bcm2836 interrupt controller (and mailboxes, etc.) */
    object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
    if (err) {
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 7859281e11..fb6d84ec50 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -36,8 +36,8 @@ typedef struct BCM2835PeripheralState {
    SysBusDevice parent_obj;
    /*< public >*/

    MemoryRegion peri_mr, peri_mr_alias, gpu_bus_mr, mbox_mr;
    MemoryRegion ram_alias[4];
    MemoryRegion peri_mr, mbox_mr;

    qemu_irq irq, fiq;

    BCM2835SystemTimerState systmr;
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
index e3498cb861..787ab76738 100644
--- a/include/hw/arm/bcm2836.h
+++ b/include/hw/arm/bcm2836.h
@@ -35,6 +35,13 @@ typedef struct BCM283XState {
    char *cpu_type;
    uint32_t enabled_cpus;

    struct {
        MemoryRegion bus;
        MemoryRegion gpu;
        MemoryRegion peri_alias;
        MemoryRegion ram_alias;
        MemoryRegion gpu_alias[4];
    } vc;
    struct {
        ARMCPU core;
        MemoryRegion container;
-- 
2.21.0

[PATCH v3 14/16] hw/arm/highbank: Use AddressSpace when using write_secondary_boot()

Details
Message ID
<20191019234715.25750-15-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +2 -1
write_secondary_boot() is used in SMP configurations where the
CPU address space might not be the main System Bus.
The rom_add_blob_fixed_as() function allow us to specify an
address space. Use it to write each boot blob in the corresponding
CPU address space.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/highbank.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f1724d6929..518d935fdf 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -78,7 +78,8 @@ static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
        smpboot[n] = tswap32(smpboot[n]);
    }
    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR);
    rom_add_blob_fixed_as("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR,
                          arm_boot_address_space(cpu, info));
}

static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
-- 
2.21.0

[PATCH v3 13/16] hw/arm/raspi: Make the board code modular

Details
Message ID
<20191019234715.25750-14-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +94 -13
Our code currently create the raspi2 (based on the BCM2836)
and the raspi3 (on the BCM2837). Similarly, the raspi4 is
based on the BCM2838. To be able to add the new board,
make the current code more modular:

- Dynamically fills the 'board-rev' value
- Allow DRAM sizes different than 1 GiB

Rename the board model name as 'B' since this is the one
encoded in the 'board-rev' tag.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/raspi.c | 107 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 94 insertions(+), 13 deletions(-)

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index b1b488ca53..004804bdb3 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -13,6 +13,7 @@

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/arm/bcm2836.h"
@@ -29,8 +30,67 @@
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
#define SPINTABLE_ADDR  0xd8 /* Pi 3 bootloader spintable */

/* Table of Linux board IDs for different Pi versions */
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
enum BoardIdManufacturer {
    M_SONY_UK = 0,
    M_EMBEST = 2,
};

enum BoardIdChip {
    C_BCM2835 = 0,
    C_BCM2836 = 1,
    C_BCM2837 = 2,
};

enum BoardIdType {
    T_2B = 0x04,
    T_3B = 0x08,
};

enum BoardIdRevision {
    R_1_0 = 0,
    R_1_1 = 1,
    R_1_2 = 2,
    R_1_3 = 3,
};

static const char *processor_typename[] = {
    [C_BCM2836] = TYPE_BCM2836,
    [C_BCM2837] = TYPE_BCM2837,
};

typedef struct BoardInfo BoardInfo;

struct BoardInfo {
    /* Table of Linux board IDs for different Pi versions */
    int board_id;
    /*
     * Board revision codes:
     * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/
     */
    struct {
        enum BoardIdType type;
        enum BoardIdRevision revision;
        enum BoardIdChip chip;
        enum BoardIdManufacturer manufacturer;
    } board_rev;
    uint64_t ram_size_min;
    uint64_t ram_size_max;
};

static const BoardInfo bcm283x_boards[] = {
    [2] = {
        .board_id = 0xc43,
        .board_rev = { T_2B, R_1_1, C_BCM2836, M_EMBEST },
        .ram_size_min = 1 * GiB,
        .ram_size_max = 1 * GiB,
    },
    [3] = {
        .board_id = 0xc44,
        .board_rev = { T_3B, R_1_2, C_BCM2837, M_SONY_UK },
        .ram_size_min = 1 * GiB,
        .ram_size_max = 1 * GiB,
    },
};

typedef struct RasPiState {
    BCM283XState soc;
@@ -116,7 +176,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
    static struct arm_boot_info binfo;
    int r;

    binfo.board_id = raspi_boardid[version];
    binfo.board_id = bcm283x_boards[version].board_id;
    binfo.ram_size = ram_size;
    binfo.nb_cpus = machine->smp.cpus;

@@ -148,7 +208,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
     * the normal Linux boot process
     */
    if (machine->firmware) {
        hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2;
        hwaddr firmware_addr = version >= 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2;
        /* load the firmware image (typically kernel.img) */
        r = load_image_targphys(machine->firmware, firmware_addr,
                                ram_size - firmware_addr);
@@ -172,16 +232,32 @@ static void raspi_init(MachineState *machine, int version)
    BlockBackend *blk;
    BusState *bus;
    DeviceState *carddev;
    char *size_str;
    int board_rev;
    const char *soc_type;

    if (machine->ram_size > 1 * GiB) {
    if (machine->ram_size < bcm283x_boards[version].ram_size_min) {
        size_str = size_to_str(bcm283x_boards[version].ram_size_min);
        error_report("Requested ram size is too small for this machine: "
                     "minimum is %s", size_str);
        g_free(size_str);
        exit(1);
    }
    if (machine->ram_size > bcm283x_boards[version].ram_size_max) {
        size_str = size_to_str(bcm283x_boards[version].ram_size_max);
        error_report("Requested ram size is too large for this machine: "
                     "maximum is 1GB");
                     "maximum is %s", size_str);
        g_free(size_str);
        exit(1);
    }
    if (!is_power_of_2(machine->ram_size)) {
        error_report("Requested ram size is not a power of 2");
        exit(1);
    }

    soc_type = processor_typename[bcm283x_boards[version].board_rev.chip];
    object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
                            version == 3 ? TYPE_BCM2837 : TYPE_BCM2836,
                            &error_abort, NULL);
                            soc_type, &error_abort, NULL);

    /* Allocate and map RAM */
    memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
@@ -192,9 +268,14 @@ static void raspi_init(MachineState *machine, int version)
                                   &error_abort);
    object_property_set_int(OBJECT(&s->soc), machine->smp.cores,
                            "enabled-cores", &error_abort);
    int board_rev = version == 3 ? 0xa02082 : 0xa21041;
    object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
                            &error_abort);

    board_rev = ((63 - clz64(machine->ram_size / MiB)) << 20)
                | (bcm283x_boards[version].board_rev.manufacturer << 16)
                | (bcm283x_boards[version].board_rev.chip << 12)
                | (bcm283x_boards[version].board_rev.type << 4)
                | (bcm283x_boards[version].board_rev.revision << 0);
    object_property_set_int(OBJECT(&s->soc), board_rev,
                            "board-rev", &error_abort);
    object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);

    /* Create and plug in the SD cards */
@@ -221,7 +302,7 @@ static void raspi2_init(MachineState *machine)

static void raspi2_machine_init(MachineClass *mc)
{
    mc->desc = "Raspberry Pi 2";
    mc->desc = "Raspberry Pi 2B";
    mc->init = raspi2_init;
    mc->block_default_type = IF_SD;
    mc->no_parallel = 1;
@@ -243,7 +324,7 @@ static void raspi3_init(MachineState *machine)

static void raspi3_machine_init(MachineClass *mc)
{
    mc->desc = "Raspberry Pi 3";
    mc->desc = "Raspberry Pi 3B";
    mc->init = raspi3_init;
    mc->block_default_type = IF_SD;
    mc->no_parallel = 1;
-- 
2.21.0

[PATCH v3 10/16] hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot

Details
Message ID
<20191019234715.25750-11-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +8 -6
write_secondary_boot() is used in SMP configurations where the
CPU address space might not be the main System Bus.
The rom_add_blob_fixed_as() function allow us to specify an
address space. Use it to write each boot blob in the corresponding
CPU address space.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/raspi.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index a12459bc41..569d85c11a 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -60,12 +60,14 @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
    QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
                      || (BOARDSETUP_ADDR >> 4) >= 0x100);

    rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
                       info->smp_loader_start);
    rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
                          info->smp_loader_start,
                          arm_boot_address_space(cpu, info));
}

static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
{
    AddressSpace *as = arm_boot_address_space(cpu, info);
    /* Unlike the AArch32 version we don't need to call the board setup hook.
     * The mechanism for doing the spin-table is also entirely different.
     * We must have four 64-bit fields at absolute addresses
@@ -92,10 +94,10 @@ static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
        0, 0, 0, 0
    };

    rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
                       info->smp_loader_start);
    rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
                       SPINTABLE_ADDR);
    rom_add_blob_fixed_as("raspi_smpboot", smpboot, sizeof(smpboot),
                          info->smp_loader_start, as);
    rom_add_blob_fixed_as("raspi_spintables", spintables, sizeof(spintables),
                          SPINTABLE_ADDR, as);
}

static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
-- 
2.21.0

[PATCH v3 12/16] hw/arm/bcm2836: Rename enabled_cpus -> enabled_cores

Details
Message ID
<20191019234715.25750-13-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +4 -4
We now use -smp cores=<n> to limit the number of cores powered
on reset. Rename the 'enabled_cpus' variable as 'enabled_cores'
to better match the new use. No functional changes.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/bcm2836.c         | 4 ++--
 hw/arm/raspi.c           | 2 +-
 include/hw/arm/bcm2836.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index ada35e5620..e3cef69687 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -202,7 +202,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
        }

        /* start powered off if not enabled */
        object_property_set_bool(OBJECT(&s->cpu[n].core), n >= s->enabled_cpus,
        object_property_set_bool(OBJECT(&s->cpu[n].core), n >= s->enabled_cores,
                                 "start-powered-off", &err);
        if (err) {
            error_propagate(errp, err);
@@ -235,7 +235,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
}

static Property bcm2836_props[] = {
    DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
    DEFINE_PROP_UINT32("enabled-cores", BCM283XState, enabled_cores,
                       BCM283X_NCPUS),
    DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 45d3f91f95..b1b488ca53 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -191,7 +191,7 @@ static void raspi_init(MachineState *machine, int version)
    object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
                                   &error_abort);
    object_property_set_int(OBJECT(&s->soc), machine->smp.cores,
                            "enabled-cpus", &error_abort);
                            "enabled-cores", &error_abort);
    int board_rev = version == 3 ? 0xa02082 : 0xa21041;
    object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
                            &error_abort);
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
index 787ab76738..2c3f1e6c6a 100644
--- a/include/hw/arm/bcm2836.h
+++ b/include/hw/arm/bcm2836.h
@@ -33,7 +33,7 @@ typedef struct BCM283XState {
    /*< public >*/

    char *cpu_type;
    uint32_t enabled_cpus;
    uint32_t enabled_cores;

    struct {
        MemoryRegion bus;
-- 
2.21.0

[PATCH NOTFORMERGE v3 16/16] tests/acceptance: Test U-boot on the Raspberry Pi 3

Details
Message ID
<20191019234715.25750-17-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +23 -0
This is a proof-of-concept for the '-smp cores=1' feature which
restricts the cores brought online on reset.

The u-boot binary is old and from an untrusted source, but I
don't want to add the build machinery in QEMU, so it is enough
to demonstrate the feature works reliably.

By default this test is not run:

  $ avocado run -t machine:raspi3 tests/acceptance/
   (1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi3_uboot: SKIP: untrusted code
  RESULTS    : PASS 0 | ERROR 0 | FAIL 0 | SKIP 1 | WARN 0 | INTERRUPT 0 | CANCEL 0
  JOB TIME   : 0.23 s

We can run it setting the AVOCADO_ALLOW_UNTRUSTED_CODE variable:

  $ AVOCADO_ALLOW_UNTRUSTED_CODE=1 ./tests/venv/bin/avocado --show=app,console run -t machine:raspi3 tests/acceptance/
   (1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi3_uboot:  console: U-Boot 2016.05-rc1-gd36dcaf (Apr 28 2016 - 23:29:29 +0200)
  console: DRAM:  960 MiB
  console: RPI 3 Model B (0xa02082)
  console: boot regs: 0x00000000 0x00000000 0x00000000 0x00000000
  console: MMC:   bcm2835_sdhci: 0
  console: Card did not respond to voltage select!
  console: ** Bad device mmc 0 **
  console: Using default environment
  console: In:    serial
  console: Out:   lcd
  console: Err:   lcd
  console: Net:   Net Initialization Skipped
  console: No ethernet found.
  PASS (0.30 s)

Then test QEMU:

  $ qemu-system-aarch64 \
      -M raspi3 -smp 4,cores=1 \
      -kernel u-boot.bin \
      -serial null -serial stdio

  U-Boot 2016.05-rc1-gd36dcaf (Apr 28 2016 - 23:29:29 +0200)

  DRAM:  960 MiB
  RPI 3 Model B (0xa02082)
  boot regs: 0x00000000 0x00000000 0x00000000 0x00000000
  MMC:   bcm2835_sdhci: 0
  Card did not respond to voltage select!
  ** Bad device mmc 0 **
  Using default environment

  In:    serial
  Out:   lcd
  Err:   lcd
  Net:   Net Initialization Skipped
  No ethernet found.
  starting USB...
  USB0:   Core Release: 0.000
  SNPSID invalid (not DWC2 OTG device): 00000000
  Port not available.
  Autoboot in 2 seconds
  Card did not respond to voltage select!
  starting USB...
  USB0:   Core Release: 0.000
  SNPSID invalid (not DWC2 OTG device): 00000000
  Port not available.
  USB is stopped. Please issue 'usb start' first.
  starting USB...
  USB0:   Core Release: 0.000
  SNPSID invalid (not DWC2 OTG device): 00000000
  Port not available.
  No ethernet found.
  missing environment variable: pxeuuid
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default-arm-bcm283x
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default-arm
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default
  No ethernet found.
  Config file not found
  starting USB...
  USB0:   Core Release: 0.000
  SNPSID invalid (not DWC2 OTG device): 00000000
  Port not available.
  No ethernet found.
  U-Boot> version

  U-Boot 2016.05-rc1-gd36dcaf (Apr 28 2016 - 23:29:29 +0200)
  aarch64-unknown-linux-gnu-gcc (Gentoo 5.3.0 p1.0, pie-0.6.5) 5.3.0
  GNU ld (Gentoo 2.25.1 p1.1) 2.25.1
  U-Boot> ^C
  qemu-system-aarch64: terminating on signal 2

We can also build a recent U-boot with:

  u-boot$ export CROSS_COMPILE=aarch64-linux-gnu-
  u-boot$ make rpi_3_defconfig
  u-boot$ make -j8

And test it:

  $ qemu-system-aarch64 \
      -M raspi3 -smp 4,cores=1 \
      -kernel u-boot.bin \
      -serial null -serial stdio

  MMC:   mmc@7e202000: 0, sdhci@7e300000: 1
  Loading Environment from FAT... WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
  WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
  Card did not respond to voltage select!
  In:    serial
  Out:   vidconsole
  Err:   vidconsole
  Net:   No ethernet found.
  starting USB...
  Bus usb@7e980000: Port not available.
  Hit any key to stop autoboot:  0
  WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
  WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
  WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
  Card did not respond to voltage select!
  MMC: no card present
  starting USB...
  Bus usb@7e980000: Port not available.
  USB is stopped. Please issue 'usb start' first.
  starting USB...
  Bus usb@7e980000: Port not available.
  No ethernet found.
  missing environment variable: pxeuuid
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/000000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/000
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/00
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/0
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default-arm-bcm283x-rpi
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default-arm-bcm283x
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default-arm
  No ethernet found.
  missing environment variable: bootfile
  Retrieving file: pxelinux.cfg/default
  No ethernet found.
  Config file not found
  starting USB...
  Bus usb@7e980000: Port not available.
  No ethernet found.
  No ethernet found.
  U-Boot> version
  U-Boot 2019.10-rc4-dirty (Oct 19 2019 - 22:02:10 +0000)

  aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0
  GNU ld (GNU Binutils for Debian) 2.31.1
  U-Boot> reset
  resetting ...
  U-Boot> ^C
  qemu-system-aarch64: terminating on signal 2

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 tests/acceptance/boot_linux_console.py | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
index 8a9a314ab4..7c73051a9a 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -14,6 +14,7 @@ import lzma
import gzip
import shutil

from avocado import skipUnless
from avocado_qemu import Test
from avocado.utils import process
from avocado.utils import archive
@@ -316,6 +317,28 @@ class BootLinuxConsole(Test):
        self.vm.launch()
        self.wait_for_console_pattern('init started: BusyBox')

    @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
    def test_arm_raspi3_uboot(self):
        """
        :avocado: tags=arch:aarch64
        :avocado: tags=machine:raspi3
        :avocado: tags=endian:little
        """
        uboot_url = ('https://github.com/poinck/piii64/raw/bf3e070d/'
                     'boot/u-boot.bin')
        uboot_hash = 'cd2ab2a24589a5b9d177af172af8b39998e5f93f'
        uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)

        self.vm.set_machine('raspi3')
        self.vm.set_console(console_index=1)
        kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE
        self.vm.add_args('-kernel', uboot_path,
                         '-smp', '4,cores=1', # start 3 cores disabled
                         '-no-reboot')
        self.vm.launch()
        self.wait_for_console_pattern('RPI 3 Model B')
        self.wait_for_console_pattern('No ethernet found.')

    def test_s390x_s390_ccw_virtio(self):
        """
        :avocado: tags=arch:s390x
-- 
2.21.0

[PATCH v3 15/16] python/qemu/machine: Allow to use other serial consoles than default

Details
Message ID
<20191019234715.25750-16-f4bug@amsat.org>
In-Reply-To
<20191019234715.25750-1-f4bug@amsat.org> (view parent)
DKIM signature
missing
Download raw message
Patch: +8 -1
Currently the QEMU Python module limits the QEMUMachine class to
use the first serial console.

Some machines/guest might use another console than the first one as
the 'boot console'. For example the Raspberry Pi uses the second
(AUX) console.

To be able to use the Nth console as default, we simply need to
connect all the N - 1 consoles to the null chardev.

Add an index argument, so we can use a specific serial console as
default.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2:
- renamed 'console_index', added docstring (Cleber)
- reworded description (pm215)
---
 python/qemu/machine.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 128a3d1dc2..6fa68fa35a 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -235,6 +235,8 @@ class QEMUMachine(object):
                '-display', 'none', '-vga', 'none']
        if self._machine is not None:
            args.extend(['-machine', self._machine])
        for i in range(self._console_index):
            args.extend(['-serial', 'null'])
        if self._console_set:
            self._console_address = os.path.join(self._temp_dir,
                                                 self._name + "-console.sock")
@@ -495,7 +497,7 @@ class QEMUMachine(object):
        """
        self._machine = machine_type

    def set_console(self, device_type=None):
    def set_console(self, device_type=None, console_index=0):
        """
        Sets the device type for a console device

@@ -516,9 +518,14 @@ class QEMUMachine(object):
                            chardev:console" command line argument will
                            be used instead, resorting to the machine's
                            default device type.
        @param console_index: the index of the console device to use.
                              If not zero, the command line will create
                              'index - 1' consoles and connect them to
                              the 'null' backing character device.
        """
        self._console_set = True
        self._console_device_type = device_type
        self._console_index = console_index

    @property
    def console_socket(self):
-- 
2.21.0
Reply to thread Export thread (mbox)