Commit a1a88589 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



target-arm queue:
 * fix bugs in gdb singlestep handling and breakpoints
 * minor code cleanup in arm_gic
 * clean up error messages in hw/arm/virt
 * fix highbank kernel booting by adding a board-setup blob

# gpg: Signature made Tue 10 Nov 2015 13:43:52 GMT using RSA key ID 14360CDE
# 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>"

* remotes/pmaydell/tags/pull-target-arm-20151110:
  target-arm: Clean up DISAS_UPDATE usage in AArch32 translation code
  hw/arm/virt: error_report cleanups
  arm: highbank: Implement PSCI and dummy monitor
  arm: highbank: Defeature CPU override
  arm: boot: Add secure_board_setup flag
  hw/intc/arm_gic: Remove the definition of NUM_CPU
  target-arm: Fix gdb singlestep handling in arm_debug_excp_handler()

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents a8b4f958 577bf808
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "hw/hw.h"
#include "hw/arm/arm.h"
#include "hw/arm/linux-boot-if.h"
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/loader.h"
@@ -495,7 +496,8 @@ static void do_cpu_reset(void *opaque)
                }

                /* Set to non-secure if not a secure boot */
                if (!info->secure_boot) {
                if (!info->secure_boot &&
                    (cs != first_cpu || !info->secure_board_setup)) {
                    /* Linux expects non-secure state */
                    env->cp15.scr_el3 |= SCR_NS;
                }
@@ -598,6 +600,12 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
    struct arm_boot_info *info =
        container_of(n, struct arm_boot_info, load_kernel_notifier);

    /* The board code is not supposed to set secure_board_setup unless
     * running its code in secure mode is actually possible, and KVM
     * doesn't support secure.
     */
    assert(!(info->secure_board_setup && kvm_enabled()));

    /* Load the kernel.  */
    if (!info->kernel_filename || info->firmware_loaded) {

+67 −24
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "hw/devices.h"
#include "hw/loader.h"
#include "net/net.h"
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "sysemu/block-backend.h"
@@ -32,10 +33,52 @@
#define SMP_BOOT_REG            0x40
#define MPCORE_PERIPHBASE       0xfff10000

#define MVBAR_ADDR              0x200

#define NIRQ_GIC                160

/* Board init.  */

/* MVBAR_ADDR is limited by precision of movw */

QEMU_BUILD_BUG_ON(MVBAR_ADDR >= (1 << 16));

#define ARMV7_IMM16(x) (extract32((x),  0, 12) | \
                        extract32((x), 12,  4) << 16)

static void hb_write_board_setup(ARMCPU *cpu,
                                 const struct arm_boot_info *info)
{
    int n;
    uint32_t board_setup_blob[] = {
        /* MVBAR_ADDR */
        /* Default unimplemented and unused vectors to spin. Makes it
         * easier to debug (as opposed to the CPU running away).
         */
        0xeafffffe, /* notused1: b notused */
        0xeafffffe, /* notused2: b notused */
        0xe1b0f00e, /* smc: movs pc, lr - exception return */
        0xeafffffe, /* prefetch_abort: b prefetch_abort */
        0xeafffffe, /* data_abort: b data_abort */
        0xeafffffe, /* notused3: b notused3 */
        0xeafffffe, /* irq: b irq */
        0xeafffffe, /* fiq: b fiq */
#define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
        0xe3000000 + ARMV7_IMM16(MVBAR_ADDR), /* movw r0, MVBAR_ADDR */
        0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 - set MVBAR */
        0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 - get SCR */
        0xe3810001, /* orr r0, #1 - set NS */
        0xee010f11, /* mcr p15, 0, r0, c1 , c1, 0 - set SCR */
        0xe1600070, /* smc - go to monitor mode to flush NS change */
        0xe12fff1e, /* bx lr - return to caller */
    };
    for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
        board_setup_blob[n] = tswap32(board_setup_blob[n]);
    }
    rom_add_blob_fixed("board-setup", board_setup_blob,
                       sizeof(board_setup_blob), MVBAR_ADDR);
}

static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
{
    int n;
@@ -223,7 +266,6 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
    MemoryRegion *sysmem;
    char *sysboot_filename;

    if (!cpu_model) {
    switch (machine_id) {
    case CALXEDA_HIGHBANK:
        cpu_model = "cortex-a9";
@@ -232,7 +274,6 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
        cpu_model = "cortex-a15";
        break;
    }
    }

    for (n = 0; n < smp_cpus; n++) {
        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
@@ -240,24 +281,16 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
        ARMCPU *cpu;
        Error *err = NULL;

        if (!oc) {
            error_report("Unable to find CPU definition");
            exit(1);
        }

        cpuobj = object_new(object_class_get_name(oc));
        cpu = ARM_CPU(cpuobj);

        /* By default A9 and A15 CPUs have EL3 enabled.  This board does not
         * currently support EL3 so the CPU EL3 property is disabled before
         * realization.
         */
        if (object_property_find(cpuobj, "has_el3", NULL)) {
            object_property_set_bool(cpuobj, false, "has_el3", &err);
            if (err) {
                error_report_err(err);
                exit(1);
            }
        object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC,
                                "psci-conduit", &error_abort);

        if (n) {
            /* Secondary CPUs start in PSCI powered-down state */
            object_property_set_bool(cpuobj, true,
                                     "start-powered-off", &error_abort);
        }

        if (object_property_find(cpuobj, "reset-cbar", NULL)) {
@@ -378,6 +411,16 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
    highbank_binfo.loader_start = 0;
    highbank_binfo.write_secondary_boot = hb_write_secondary;
    highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
    if (!kvm_enabled()) {
        highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
        highbank_binfo.write_board_setup = hb_write_board_setup;
        highbank_binfo.secure_board_setup = true;
    } else {
        error_report("WARNING: cannot load built-in Monitor support "
                     "if KVM is enabled. Some guests (such as Linux) "
                     "may not boot.");
    }

    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
}

+5 −5
Original line number Diff line number Diff line
@@ -941,8 +941,8 @@ static void machvirt_init(MachineState *machine)
    if (!gic_version) {
        gic_version = kvm_arm_vgic_probe();
        if (!gic_version) {
            error_report("Unable to determine GIC version supported by host\n"
                         "Probably KVM acceleration is not supported\n");
            error_report("Unable to determine GIC version supported by host");
            error_printf("KVM acceleration is probably not supported\n");
            exit(1);
        }
    }
@@ -990,7 +990,7 @@ static void machvirt_init(MachineState *machine)
        char *cpuopts = g_strdup(cpustr[1]);

        if (!oc) {
            fprintf(stderr, "Unable to find CPU definition\n");
            error_report("Unable to find CPU definition");
            exit(1);
        }
        cpuobj = object_new(object_class_get_name(oc));
@@ -1126,8 +1126,8 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
    } else if (!strcmp(value, "host")) {
        vms->gic_version = 0; /* Will probe later */
    } else {
        error_report("Invalid gic-version option value\n"
                     "Allowed values are: 3, 2, host\n");
        error_report("Invalid gic-version option value");
        error_printf("Allowed gic-version values are: 3, 2, host\n");
        exit(1);
    }
}
+3 −5
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@ static const uint8_t gic_id[] = {
    0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
};

#define NUM_CPU(s) ((s)->num_cpu)

static inline int gic_get_current_cpu(GICState *s)
{
    if (s->num_cpu > 1) {
@@ -64,7 +62,7 @@ void gic_update(GICState *s)
    int cpu;
    int cm;

    for (cpu = 0; cpu < NUM_CPU(s); cpu++) {
    for (cpu = 0; cpu < s->num_cpu; cpu++) {
        cm = 1 << cpu;
        s->current_pending[cpu] = 1023;
        if (!(s->ctlr & (GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GRP1))
@@ -567,7 +565,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
        if (offset == 4)
            /* Interrupt Controller Type Register */
            return ((s->num_irq / 32) - 1)
                    | ((NUM_CPU(s) - 1) << 5)
                    | ((s->num_cpu - 1) << 5)
                    | (s->security_extn << 10);
        if (offset < 0x08)
            return 0;
@@ -1284,7 +1282,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
     * GIC v2 defines a larger memory region (0x1000) so this will need
     * to be extended when we implement A15.
     */
    for (i = 0; i < NUM_CPU(s); i++) {
    for (i = 0; i < s->num_cpu; i++) {
        s->backref[i] = s;
        memory_region_init_io(&s->cpuiomem[i+1], OBJECT(s), &gic_cpu_ops,
                              &s->backref[i], "gic_cpu", 0x100);
+6 −0
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ struct arm_boot_info {
    hwaddr board_setup_addr;
    void (*write_board_setup)(ARMCPU *cpu,
                              const struct arm_boot_info *info);

    /* If set, the board specific loader/setup blob will be run from secure
     * mode, regardless of secure_boot. The blob becomes responsible for
     * changing to non-secure state if implementing a non-secure boot
     */
    bool secure_board_setup;
};

/**
Loading