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

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



target-arm queue:
 * enable 32-bit EL3 (TrustZone) for vexpress and virt boards
 * add fw_cfg device to virt board for UEFI firmware config
 * support passing commandline kernel/initrd to firmware

# gpg: Signature made Tue 23 Dec 2014 13:50:33 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20141223: (31 commits)
  hw/arm/virt: enable passing of EFI-stubbed kernel to guest UEFI firmware
  hw/arm: pass pristine kernel image to guest firmware over fw_cfg
  hw/loader: split out load_image_gzipped_buffer()
  arm: add fw_cfg to "virt" board
  fw_cfg_mem: expose the "data_width" property with fw_cfg_init_mem_wide()
  fw_cfg_mem: introduce the "data_width" property
  exec: allows 8-byte accesses in subpage_ops
  fw_cfg_mem: flip ctl_mem_ops and data_mem_ops to DEVICE_BIG_ENDIAN
  fw_cfg_mem: max access size and region size are the same for data register
  fw_cfg: move boards to fw_cfg_init_io() / fw_cfg_init_mem()
  fw_cfg: hard separation between the MMIO and I/O port mappings
  target-arm: add cpu feature EL3 to CPUs with Security Extensions
  target-arm: Disable EL3 on unsupported machines
  target-arm: Breakout integratorcp and versatilepb cpu init
  target-arm: Set CPU has_el3 prop during virt init
  target-arm: Enable CPU has_el3 prop during VE init
  target-arm: Add arm_boot_info secure_boot control
  target-arm: Add ARMCPU secure property
  target-arm: Add feature unset function
  target-arm: Add virt machine secure property
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 03de06dd aa351061
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -191,9 +191,9 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
        audio_detach_capture (hw);
#endif
        QLIST_REMOVE (hw, entries);
        glue (hw->pcm_ops->fini_, TYPE) (hw);
        glue (s->nb_hw_voices_, TYPE) += 1;
        glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
        glue (hw->pcm_ops->fini_, TYPE) (hw);
        g_free (hw);
        *hwp = NULL;
    }
+11 −2
Original line number Diff line number Diff line
@@ -1768,7 +1768,7 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
                             unsigned len)
{
    subpage_t *subpage = opaque;
    uint8_t buf[4];
    uint8_t buf[8];

#if defined(DEBUG_SUBPAGE)
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
@@ -1782,6 +1782,8 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
        return lduw_p(buf);
    case 4:
        return ldl_p(buf);
    case 8:
        return ldq_p(buf);
    default:
        abort();
    }
@@ -1791,7 +1793,7 @@ static void subpage_write(void *opaque, hwaddr addr,
                          uint64_t value, unsigned len)
{
    subpage_t *subpage = opaque;
    uint8_t buf[4];
    uint8_t buf[8];

#if defined(DEBUG_SUBPAGE)
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx
@@ -1808,6 +1810,9 @@ static void subpage_write(void *opaque, hwaddr addr,
    case 4:
        stl_p(buf, value);
        break;
    case 8:
        stq_p(buf, value);
        break;
    default:
        abort();
    }
@@ -1830,6 +1835,10 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
static const MemoryRegionOps subpage_ops = {
    .read = subpage_read,
    .write = subpage_write,
    .impl.min_access_size = 1,
    .impl.max_access_size = 8,
    .valid.min_access_size = 1,
    .valid.max_access_size = 8,
    .valid.accepts = subpage_accepts,
    .endianness = DEVICE_NATIVE_ENDIAN,
};
+93 −5
Original line number Diff line number Diff line
@@ -457,6 +457,16 @@ static void do_cpu_reset(void *opaque)
                env->thumb = info->entry & 1;
            }
        } else {
            /* If we are booting Linux then we need to check whether we are
             * booting into secure or non-secure state and adjust the state
             * accordingly.  Out of reset, ARM is defined to be in secure state
             * (SCR.NS = 0), we change that here if non-secure boot has been
             * requested.
             */
            if (arm_feature(env, ARM_FEATURE_EL3) && !info->secure_boot) {
                env->cp15.scr_el3 |= SCR_NS;
            }

            if (CPU(cpu) == first_cpu) {
                if (env->aarch64) {
                    env->pc = info->loader_start;
@@ -478,6 +488,55 @@ static void do_cpu_reset(void *opaque)
    }
}

/**
 * load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified
 *                          by key.
 * @fw_cfg:         The firmware config instance to store the data in.
 * @size_key:       The firmware config key to store the size of the loaded
 *                  data under, with fw_cfg_add_i32().
 * @data_key:       The firmware config key to store the loaded data under,
 *                  with fw_cfg_add_bytes().
 * @image_name:     The name of the image file to load. If it is NULL, the
 *                  function returns without doing anything.
 * @try_decompress: Whether the image should be decompressed (gunzipped) before
 *                  adding it to fw_cfg. If decompression fails, the image is
 *                  loaded as-is.
 *
 * In case of failure, the function prints an error message to stderr and the
 * process exits with status 1.
 */
static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
                                 uint16_t data_key, const char *image_name,
                                 bool try_decompress)
{
    size_t size = -1;
    uint8_t *data;

    if (image_name == NULL) {
        return;
    }

    if (try_decompress) {
        size = load_image_gzipped_buffer(image_name,
                                         LOAD_IMAGE_MAX_GUNZIP_BYTES, &data);
    }

    if (size == (size_t)-1) {
        gchar *contents;
        gsize length;

        if (!g_file_get_contents(image_name, &contents, &length, NULL)) {
            fprintf(stderr, "failed to load \"%s\"\n", image_name);
            exit(1);
        }
        size = length;
        data = (uint8_t *)contents;
    }

    fw_cfg_add_i32(fw_cfg, size_key, size);
    fw_cfg_add_bytes(fw_cfg, data_key, data, size);
}

void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
{
    CPUState *cs;
@@ -500,19 +559,48 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
    }

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

        if (have_dtb(info)) {
            /* If we have a device tree blob, but no kernel to supply it to,
             * copy it to the base of RAM for a bootloader to pick up.
            /* If we have a device tree blob, but no kernel to supply it to (or
             * the kernel is supposed to be loaded by the bootloader), copy the
             * DTB to the base of RAM for the bootloader to pick up.
             */
            if (load_dtb(info->loader_start, info, 0) < 0) {
                exit(1);
            }
        }

        /* If no kernel specified, do nothing; we will start from address 0
         * (typically a boot ROM image) in the same way as hardware.
        if (info->kernel_filename) {
            FWCfgState *fw_cfg;
            bool try_decompressing_kernel;

            fw_cfg = fw_cfg_find();
            try_decompressing_kernel = arm_feature(&cpu->env,
                                                   ARM_FEATURE_AARCH64);

            /* Expose the kernel, the command line, and the initrd in fw_cfg.
             * We don't process them here at all, it's all left to the
             * firmware.
             */
            load_image_to_fw_cfg(fw_cfg,
                                 FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
                                 info->kernel_filename,
                                 try_decompressing_kernel);
            load_image_to_fw_cfg(fw_cfg,
                                 FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
                                 info->initrd_filename, false);

            if (info->kernel_cmdline) {
                fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                               strlen(info->kernel_cmdline) + 1);
                fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
                                  info->kernel_cmdline);
            }
        }

        /* We will start from address 0 (typically a boot ROM image) in the
         * same way as hardware.
         */
        return;
    }
+11 −0
Original line number Diff line number Diff line
@@ -152,6 +152,17 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
        Error *err = NULL;

        /* By default A9 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("%s", error_get_pretty(err));
                exit(1);
            }
        }

        s->cpu[n] = ARM_CPU(cpuobj);
        object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
                                "reset-cbar", &error_abort);
+12 −0
Original line number Diff line number Diff line
@@ -241,6 +241,18 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
        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("%s", error_get_pretty(err));
                exit(1);
            }
        }

        if (object_property_find(cpuobj, "reset-cbar", NULL)) {
            object_property_set_int(cpuobj, MPCORE_PERIPHBASE,
                                    "reset-cbar", &error_abort);
Loading