Commit 5fce3122 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180622' into staging



target-arm queue:
 * hw/intc/arm_gicv3: fix wrong values when reading IPRIORITYR
 * target/arm: fix read of freed memory in kvm_arm_machine_init_done()
 * virt: support up to 512 CPUs
 * virt: support 256MB ECAM PCI region (for more PCI devices)
 * xlnx-zynqmp: Use Cortex-R5F, not Cortex-R5
 * mps2-tz: Implement and use the TrustZone Memory Protection Controller
 * target/arm: enforce alignment checking for v6M cores
 * xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom()
 * vl.c: Don't zero-initialize statics for serial_hds

# gpg: Signature made Fri 22 Jun 2018 13:56:00 BST
# gpg:                using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20180622: (28 commits)
  xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom()
  vl.c: Don't zero-initialize statics for serial_hds
  target/arm: Strict alignment for ARMv6-M and ARMv8-M Baseline
  target/arm: Introduce ARM_FEATURE_M_MAIN
  hw/arm/mps2-tz.c: Instantiate MPCs
  hw/arm/iotkit: Wire up MPC interrupt lines
  hw/arm/iotkit: Instantiate MPC
  hw/misc/iotkit-secctl.c: Implement SECMPCINTSTATUS
  hw/misc/tz_mpc.c: Honour the BLK_LUT settings in translate
  hw/misc/tz-mpc.c: Implement correct blocked-access behaviour
  hw/misc/tz-mpc.c: Implement registers
  hw/misc/tz-mpc.c: Implement the Arm TrustZone Memory Protection Controller
  xlnx-zynqmp: Swap Cortex-R5 for Cortex-R5F
  target-arm: Add the Cortex-R5F
  hw/arm/virt: Increase max_cpus to 512
  hw/arm/virt: Use 256MB ECAM region by default
  hw/arm/virt: Add virt-3.0 machine type
  hw/arm/virt: Add a new 256MB ECAM region
  hw/arm/virt: Register two redistributor regions when necessary
  hw/arm/virt-acpi-build: Advertise one or two GICR structures
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c52e53f4 6dad8260
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -457,6 +457,8 @@ F: hw/char/cmsdk-apb-uart.c
F: include/hw/char/cmsdk-apb-uart.h
F: hw/misc/tz-ppc.c
F: include/hw/misc/tz-ppc.h
F: hw/misc/tz-mpc.c
F: include/hw/misc/tz-mpc.h

ARM cores
M: Peter Maydell <peter.maydell@linaro.org>
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ CONFIG_CMSDK_APB_UART=y
CONFIG_MPS2_FPGAIO=y
CONFIG_MPS2_SCC=y

CONFIG_TZ_MPC=y
CONFIG_TZ_PPC=y
CONFIG_IOTKIT=y
CONFIG_IOTKIT_SECCTL=y
+101 −11
Original line number Diff line number Diff line
@@ -130,6 +130,19 @@ static void iotkit_init(Object *obj)
                      TYPE_TZ_PPC);
    init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
                      TYPE_TZ_PPC);
    init_sysbus_child(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
    object_initialize(&s->mpc_irq_orgate, sizeof(s->mpc_irq_orgate),
                      TYPE_OR_IRQ);
    object_property_add_child(obj, "mpc-irq-orgate",
                              OBJECT(&s->mpc_irq_orgate), &error_abort);
    for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
        char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
        SplitIRQ *splitter = &s->mpc_irq_splitter[i];

        object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ);
        object_property_add_child(obj, name, OBJECT(splitter), &error_abort);
        g_free(name);
    }
    init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0),
                      TYPE_CMSDK_APB_TIMER);
    init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1),
@@ -162,6 +175,12 @@ static void iotkit_exp_irq(void *opaque, int n, int level)
    qemu_set_irq(s->exp_irqs[n], level);
}

static void iotkit_mpcexp_status(void *opaque, int n, int level)
{
    IoTKit *s = IOTKIT(opaque);
    qemu_set_irq(s->mpcexp_status_in[n], level);
}

static void iotkit_realize(DeviceState *dev, Error **errp)
{
    IoTKit *s = IOTKIT(dev);
@@ -266,15 +285,6 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
     */
    make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);

    /* This RAM should be behind a Memory Protection Controller, but we
     * don't implement that yet.
     */
    memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(&s->container, 0x20000000, &s->sram0);

    /* Security controller */
    object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
@@ -310,6 +320,48 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
    qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
                                qdev_get_gpio_in(dev_splitter, 0));

    /* This RAM lives behind the Memory Protection Controller */
    memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
                             "downstream", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    /* Map the upstream end of the MPC into the right place... */
    memory_region_add_subregion(&s->container, 0x20000000,
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
                                                       1));
    /* ...and its register interface */
    memory_region_add_subregion(&s->container, 0x50083000,
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
                                                       0));

    /* We must OR together lines from the MPC splitters to go to the NVIC */
    object_property_set_int(OBJECT(&s->mpc_irq_orgate),
                            IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
                             "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
                          qdev_get_gpio_in(DEVICE(&s->armv7m), 9));

    /* Devices behind APB PPC0:
     *   0x40000000: timer0
     *   0x40001000: timer1
@@ -473,8 +525,6 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
    create_unimplemented_device("NS watchdog", 0x40081000, 0x1000);
    create_unimplemented_device("S watchdog", 0x50081000, 0x1000);

    create_unimplemented_device("SRAM0 MPC", 0x50083000, 0x1000);

    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
        Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);

@@ -520,6 +570,46 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
        g_free(gpioname);
    }

    /* Wire up the splitters for the MPC IRQs */
    for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
        DeviceState *dev_splitter = DEVICE(splitter);

        object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        object_property_set_bool(OBJECT(splitter), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        if (i < IOTS_NUM_EXP_MPC) {
            /* Splitter input is from GPIO input line */
            s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
            qdev_connect_gpio_out(dev_splitter, 0,
                                  qdev_get_gpio_in_named(dev_secctl,
                                                         "mpcexp_status", i));
        } else {
            /* Splitter input is from our own MPC */
            qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
                                        qdev_get_gpio_in(dev_splitter, 0));
            qdev_connect_gpio_out(dev_splitter, 0,
                                  qdev_get_gpio_in_named(dev_secctl,
                                                         "mpc_status", 0));
        }

        qdev_connect_gpio_out(dev_splitter, 1,
                              qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
    }
    /* Create GPIO inputs which will pass the line state for our
     * mpcexp_irq inputs to the correct splitter devices.
     */
    qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
                            IOTS_NUM_EXP_MPC);

    iotkit_forward_sec_resp_cfg(s);

    system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
+44 −27
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include "hw/timer/cmsdk-apb-timer.h"
#include "hw/misc/mps2-scc.h"
#include "hw/misc/mps2-fpgaio.h"
#include "hw/misc/tz-mpc.h"
#include "hw/arm/iotkit.h"
#include "hw/devices.h"
#include "net/net.h"
@@ -64,13 +65,12 @@ typedef struct {

    IoTKit iotkit;
    MemoryRegion psram;
    MemoryRegion ssram1;
    MemoryRegion ssram[3];
    MemoryRegion ssram1_m;
    MemoryRegion ssram23;
    MPS2SCC scc;
    MPS2FPGAIO fpgaio;
    TZPPC ppc[5];
    UnimplementedDeviceState ssram_mpc[3];
    TZMPC ssram_mpc[3];
    UnimplementedDeviceState spi[5];
    UnimplementedDeviceState i2c[4];
    UnimplementedDeviceState i2s_audio;
@@ -96,16 +96,6 @@ typedef struct {
/* Main SYSCLK frequency in Hz */
#define SYSCLK_FRQ 20000000

/* Initialize the auxiliary RAM region @mr and map it into
 * the memory map at @base.
 */
static void make_ram(MemoryRegion *mr, const char *name,
                     hwaddr base, hwaddr size)
{
    memory_region_init_ram(mr, NULL, name, size, &error_fatal);
    memory_region_add_subregion(get_system_memory(), base, mr);
}

/* Create an alias of an entire original MemoryRegion @orig
 * located at @base in the memory map.
 */
@@ -245,6 +235,44 @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
    return sysbus_mmio_get_region(s, 0);
}

static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
                              const char *name, hwaddr size)
{
    TZMPC *mpc = opaque;
    int i = mpc - &mms->ssram_mpc[0];
    MemoryRegion *ssram = &mms->ssram[i];
    MemoryRegion *upstream;
    char *mpcname = g_strdup_printf("%s-mpc", name);
    static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
    static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };

    memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);

    init_sysbus_child(OBJECT(mms), mpcname, mpc,
                      sizeof(mms->ssram_mpc[0]), TYPE_TZ_MPC);
    object_property_set_link(OBJECT(mpc), OBJECT(ssram),
                             "downstream", &error_fatal);
    object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
    /* Map the upstream end of the MPC into system memory */
    upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
    memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
    /* and connect its interrupt to the IoTKit */
    qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
                                qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
                                                       "mpcexp_status", i));

    /* The first SSRAM is a special case as it has an alias; accesses to
     * the alias region at 0x00400000 must also go to the MPC upstream.
     */
    if (i == 0) {
        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
    }

    g_free(mpcname);
    /* Return the register interface MR for our caller to map behind the PPC */
    return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
}

static void mps2tz_common_init(MachineState *machine)
{
    MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
@@ -306,14 +334,6 @@ static void mps2tz_common_init(MachineState *machine)
                                         NULL, "mps.ram", 0x01000000);
    memory_region_add_subregion(system_memory, 0x80000000, &mms->psram);

    /* The SSRAM memories should all be behind Memory Protection Controllers,
     * but we don't implement that yet.
     */
    make_ram(&mms->ssram1, "mps.ssram1", 0x00000000, 0x00400000);
    make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x00400000);

    make_ram(&mms->ssram23, "mps.ssram23", 0x28000000, 0x00400000);

    /* The overflow IRQs for all UARTs are ORed together.
     * Tx, Rx and "combined" IRQs are sent to the NVIC separately.
     * Create the OR gate for this.
@@ -343,12 +363,9 @@ static void mps2tz_common_init(MachineState *machine)
    const PPCInfo ppcs[] = { {
            .name = "apb_ppcexp0",
            .ports = {
                { "ssram-mpc0", make_unimp_dev, &mms->ssram_mpc[0],
                  0x58007000, 0x1000 },
                { "ssram-mpc1", make_unimp_dev, &mms->ssram_mpc[1],
                  0x58008000, 0x1000 },
                { "ssram-mpc2", make_unimp_dev, &mms->ssram_mpc[2],
                  0x58009000, 0x1000 },
                { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
                { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
                { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
            },
        }, {
            .name = "apb_ppcexp1",
+22 −8
Original line number Diff line number Diff line
@@ -150,16 +150,17 @@ static void acpi_dsdt_add_virtio(Aml *scope,
}

static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
                              uint32_t irq, bool use_highmem)
                              uint32_t irq, bool use_highmem, bool highmem_ecam)
{
    int ecam_id = VIRT_ECAM_ID(highmem_ecam);
    Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
    int i, bus_no;
    hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base;
    hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size;
    hwaddr base_pio = memmap[VIRT_PCIE_PIO].base;
    hwaddr size_pio = memmap[VIRT_PCIE_PIO].size;
    hwaddr base_ecam = memmap[VIRT_PCIE_ECAM].base;
    hwaddr size_ecam = memmap[VIRT_PCIE_ECAM].size;
    hwaddr base_ecam = memmap[ecam_id].base;
    hwaddr size_ecam = memmap[ecam_id].size;
    int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;

    Aml *dev = aml_device("%s", "PCI0");
@@ -173,7 +174,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
    aml_append(dev, aml_name_decl("_CCA", aml_int(1)));

    /* Declare the PCI Routing Table. */
    Aml *rt_pkg = aml_package(nr_pcie_buses * PCI_NUM_PINS);
    Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS);
    for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) {
        for (i = 0; i < PCI_NUM_PINS; i++) {
            int gsi = (i + bus_no) % PCI_NUM_PINS;
@@ -316,7 +317,10 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
    Aml *dev_res0 = aml_device("%s", "RES0");
    aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
    crs = aml_resource_template();
    aml_append(crs, aml_memory32_fixed(base_ecam, size_ecam, AML_READ_WRITE));
    aml_append(crs,
        aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
                         AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, base_ecam,
                         base_ecam + size_ecam - 1, 0x0000, size_ecam));
    aml_append(dev_res0, aml_name_decl("_CRS", crs));
    aml_append(dev, dev_res0);
    aml_append(scope, dev);
@@ -573,16 +577,17 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
    AcpiTableMcfg *mcfg;
    const MemMapEntry *memmap = vms->memmap;
    int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
    int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
    int mcfg_start = table_data->len;

    mcfg = acpi_data_push(table_data, len);
    mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
    mcfg->allocation[0].address = cpu_to_le64(memmap[ecam_id].base);

    /* Only a single allocation so no need to play with segments */
    mcfg->allocation[0].pci_segment = cpu_to_le16(0);
    mcfg->allocation[0].start_bus_number = 0;
    mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
    mcfg->allocation[0].end_bus_number = (memmap[ecam_id].size
                                          / PCIE_MMCFG_SIZE_MIN) - 1;

    build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
@@ -670,6 +675,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)

    if (vms->gic_version == 3) {
        AcpiMadtGenericTranslator *gic_its;
        int nb_redist_regions = virt_gicv3_redist_region_count(vms);
        AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
                                                         sizeof *gicr);

@@ -678,6 +684,14 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
        gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
        gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);

        if (nb_redist_regions == 2) {
            gicr = acpi_data_push(table_data, sizeof(*gicr));
            gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
            gicr->length = sizeof(*gicr);
            gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
            gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
        }

        if (its_class_name() && !vmc->no_its) {
            gic_its = acpi_data_push(table_data, sizeof *gic_its);
            gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
@@ -757,7 +771,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
                    (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
    acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
                      vms->highmem);
                      vms->highmem, vms->highmem_ecam);
    acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
                       (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
    acpi_dsdt_add_power_button(scope);
Loading