Commit d9bafcd1 authored by Blue Swirl's avatar Blue Swirl
Browse files

Merge branch 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm

* 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm:
  hw/arm11mpcore: Fix broken realview_mpcore/arm11mpcore_priv properties
  arm: add device tree support
  arm: make sure that number of irqs can be represented in GICD_TYPER.
  arm: clean up GIC constants
parents b3e54c68 0f58a188
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -374,6 +374,7 @@ obj-arm-y += vexpress.o
obj-arm-y += strongarm.o
obj-arm-y += collie.o
obj-arm-y += pl041.o lm4549.o
obj-arm-$(CONFIG_FDT) += device_tree.o

obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
+1 −0
Original line number Diff line number Diff line
@@ -3485,6 +3485,7 @@ case "$target_arch2" in
    gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
    target_phys_bits=32
    target_llong_alignment=4
    target_libs_softmmu="$fdt_libs"
  ;;
  cris)
    target_nptl="yes"
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct arm_boot_info {
    const char *kernel_filename;
    const char *kernel_cmdline;
    const char *initrd_filename;
    const char *dtb_filename;
    target_phys_addr_t loader_start;
    /* multicore boards that use the default secondary core boot functions
     * need to put the address of the secondary boot code, the boot reg,
+10 −10
Original line number Diff line number Diff line
@@ -202,16 +202,7 @@ static int realview_mpcore_init(SysBusDevice *dev)
}

static Property mpcore_rirq_properties[] = {
    DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
    /* The ARM11 MPCORE TRM says the on-chip controller may have
     * anything from 0 to 224 external interrupt IRQ lines (with another
     * 32 internal). We default to 32+32, which is the number provided by
     * the ARM11 MPCore test chip in the Realview Versatile Express
     * coretile. Other boards may differ and should set this property
     * appropriately. Some Linux kernels may not boot if the hardware
     * has more IRQ lines than the kernel expects.
     */
    DEFINE_PROP_UINT32("num-irq", mpcore_priv_state, num_irq, 64),
    DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1),
    DEFINE_PROP_END_OF_LIST(),
};

@@ -233,6 +224,15 @@ static TypeInfo mpcore_rirq_info = {

static Property mpcore_priv_properties[] = {
    DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
    /* The ARM11 MPCORE TRM says the on-chip controller may have
     * anything from 0 to 224 external interrupt IRQ lines (with another
     * 32 internal). We default to 32+32, which is the number provided by
     * the ARM11 MPCore test chip in the Realview Versatile Express
     * coretile. Other boards may differ and should set this property
     * appropriately. Some Linux kernels may not boot if the hardware
     * has more IRQ lines than the kernel expects.
     */
    DEFINE_PROP_UINT32("num-irq", mpcore_priv_state, num_irq, 64),
    DEFINE_PROP_END_OF_LIST(),
};

+96 −6
Original line number Diff line number Diff line
@@ -7,11 +7,14 @@
 * This code is licensed under the GPL.
 */

#include "config.h"
#include "hw.h"
#include "arm-misc.h"
#include "sysemu.h"
#include "boards.h"
#include "loader.h"
#include "elf.h"
#include "device_tree.h"

#define KERNEL_ARGS_ADDR 0x100
#define KERNEL_LOAD_ADDR 0x00010000
@@ -208,6 +211,67 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
    }
}

static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo)
{
#ifdef CONFIG_FDT
    uint32_t mem_reg_property[] = { cpu_to_be32(binfo->loader_start),
                                    cpu_to_be32(binfo->ram_size) };
    void *fdt = NULL;
    char *filename;
    int size, rc;

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
    if (!filename) {
        fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
        return -1;
    }

    fdt = load_device_tree(filename, &size);
    if (!fdt) {
        fprintf(stderr, "Couldn't open dtb file %s\n", filename);
        g_free(filename);
        return -1;
    }
    g_free(filename);

    rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
                               sizeof(mem_reg_property));
    if (rc < 0) {
        fprintf(stderr, "couldn't set /memory/reg\n");
    }

    rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
                                      binfo->kernel_cmdline);
    if (rc < 0) {
        fprintf(stderr, "couldn't set /chosen/bootargs\n");
    }

    if (binfo->initrd_size) {
        rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
                binfo->loader_start + INITRD_LOAD_ADDR);
        if (rc < 0) {
            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
        }

        rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
                    binfo->loader_start + INITRD_LOAD_ADDR +
                    binfo->initrd_size);
        if (rc < 0) {
            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
        }
    }

    cpu_physical_memory_write(addr, fdt, size);

    return 0;

#else
    fprintf(stderr, "Device tree requested, "
                "but qemu was compiled without fdt support\n");
    return -1;
#endif
}

static void do_cpu_reset(void *opaque)
{
    CPUState *env = opaque;
@@ -222,11 +286,13 @@ static void do_cpu_reset(void *opaque)
        } else {
            if (env == first_cpu) {
                env->regs[15] = info->loader_start;
                if (!info->dtb_filename) {
                    if (old_param) {
                        set_kernel_args_old(info);
                    } else {
                        set_kernel_args(info);
                    }
                }
            } else {
                info->secondary_cpu_reset_hook(env, info);
            }
@@ -243,6 +309,7 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
    uint64_t elf_entry;
    target_phys_addr_t entry;
    int big_endian;
    QemuOpts *machine_opts;

    /* Load the kernel.  */
    if (!info->kernel_filename) {
@@ -250,6 +317,13 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
        exit(1);
    }

    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
    if (machine_opts) {
        info->dtb_filename = qemu_opt_get(machine_opts, "dtb");
    } else {
        info->dtb_filename = NULL;
    }

    if (!info->secondary_cpu_reset_hook) {
        info->secondary_cpu_reset_hook = default_reset_secondary;
    }
@@ -300,8 +374,25 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
        } else {
            initrd_size = 0;
        }
        info->initrd_size = initrd_size;

        bootloader[4] = info->board_id;

        /* for device tree boot, we pass the DTB directly in r2. Otherwise
         * we point to the kernel args.
         */
        if (info->dtb_filename) {
            /* Place the DTB after the initrd in memory */
            target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN(info->loader_start
                                                             + INITRD_LOAD_ADDR
                                                             + initrd_size);
            if (load_dtb(dtb_start, info)) {
                exit(1);
            }
            bootloader[5] = dtb_start;
        } else {
            bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
        }
        bootloader[6] = entry;
        for (n = 0; n < sizeof(bootloader) / 4; n++) {
            bootloader[n] = tswap32(bootloader[n]);
@@ -311,7 +402,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
        if (info->nb_cpus > 1) {
            info->write_secondary_boot(env, info);
        }
        info->initrd_size = initrd_size;
    }
    info->is_linux = is_linux;

Loading