From: Anthony Liguori <anthony@codemonkey.ws>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Grant Likely <grant.likely@secretlab.ca>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] arm: add device tree support
Date: Mon, 27 Feb 2012 11:41:13 -0600 [thread overview]
Message-ID: <4F4BC039.8060808@codemonkey.ws> (raw)
In-Reply-To: <1330364305-410-1-git-send-email-peter.maydell@linaro.org>
On 02/27/2012 11:38 AM, Peter Maydell wrote:
> From: Grant Likely<grant.likely@secretlab.ca>
>
> If compiled with CONFIG_FDT, allow user to specify a device tree file using
> the -dtb argument. If the machine supports it then the dtb will be loaded
> into memory and passed to the kernel on boot.
>
> Signed-off-by: Jeremy Kerr<jeremy.kerr@canonical.com>
> Signed-off-by: Grant Likely<grant.likely@secretlab.ca>
> [Peter Maydell: Use machine opt rather than global to pass dtb filename]
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Thanks for doing the work to wrap this in QemuOpts. This was a nice improvement.
Regards,
Anthony Liguori
> ---
> v1->v2: fix potential NULL deref if qemu_opts_find() returns NULL
>
> Makefile.target | 1 +
> configure | 1 +
> hw/arm-misc.h | 1 +
> hw/arm_boot.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++---
> qemu-config.c | 4 ++
> qemu-options.hx | 9 +++++
> vl.c | 8 ++++
> 7 files changed, 120 insertions(+), 6 deletions(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index 68a5641..6a56b3e 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -373,6 +373,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
> diff --git a/configure b/configure
> index f9d5330..7d509e8 100755
> --- a/configure
> +++ b/configure
> @@ -3472,6 +3472,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"
> diff --git a/hw/arm-misc.h b/hw/arm-misc.h
> index 306013a..734bd82 100644
> --- a/hw/arm-misc.h
> +++ b/hw/arm-misc.h
> @@ -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,
> diff --git a/hw/arm_boot.c b/hw/arm_boot.c
> index 2ef25ca..fc66910 100644
> --- a/hw/arm_boot.c
> +++ b/hw/arm_boot.c
> @@ -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,10 +286,12 @@ static void do_cpu_reset(void *opaque)
> } else {
> if (env == first_cpu) {
> env->regs[15] = info->loader_start;
> - if (old_param) {
> - set_kernel_args_old(info);
> - } else {
> - set_kernel_args(info);
> + 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;
> - bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
> +
> + /* 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;
>
> diff --git a/qemu-config.c b/qemu-config.c
> index 7d9da78..be84a03 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -578,6 +578,10 @@ static QemuOptsList qemu_machine_opts = {
> .name = "append",
> .type = QEMU_OPT_STRING,
> .help = "Linux kernel command line",
> + }, {
> + .name = "dtb",
> + .type = QEMU_OPT_STRING,
> + .help = "Linux kernel device tree file",
> },
> { /* End of list */ }
> },
> diff --git a/qemu-options.hx b/qemu-options.hx
> index b129996..e38799c 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2037,6 +2037,15 @@ Use @var{file1} and @var{file2} as modules and pass arg=foo as parameter to the
> first module.
> ETEXI
>
> +DEF("dtb", HAS_ARG, QEMU_OPTION_dtb, \
> + "-dtb file use 'file' as device tree image\n", QEMU_ARCH_ARM)
> +STEXI
> +@item -dtb @var{file}
> +@findex -dtb
> +Use @var{file} as a device tree binary (dtb) image and pass it to the kernel
> +on boot.
> +ETEXI
> +
> STEXI
> @end table
> ETEXI
> diff --git a/vl.c b/vl.c
> index 1d4c350..2d3347d 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2526,6 +2526,9 @@ int main(int argc, char **argv, char **envp)
> case QEMU_OPTION_append:
> qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg);
> break;
> + case QEMU_OPTION_dtb:
> + qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg);
> + break;
> case QEMU_OPTION_cdrom:
> drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
> break;
> @@ -3345,6 +3348,11 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
>
> + if (!linux_boot&& machine_opts&& qemu_opt_get(machine_opts, "dtb")) {
> + fprintf(stderr, "-dtb only allowed with -kernel option\n");
> + exit(1);
> + }
> +
> os_set_line_buffering();
>
> if (init_timer_alarm()< 0) {
next prev parent reply other threads:[~2012-02-27 17:41 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-27 17:38 [Qemu-devel] [PATCH] arm: add device tree support Peter Maydell
2012-02-27 17:41 ` Anthony Liguori [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-02-22 19:48 Peter Maydell
2012-01-29 7:48 Peter Crosthwaite
2012-01-27 21:53 Grant Likely
2012-01-27 22:34 ` Paul Brook
2012-01-28 18:48 ` Grant Likely
2012-01-29 11:15 ` Paul Brook
2012-01-29 16:01 ` Grant Likely
2012-01-29 18:48 ` Andreas Färber
2012-01-29 21:29 ` Peter Maydell
2012-01-30 13:33 ` Grant Likely
2012-01-29 19:13 ` Peter Maydell
2012-01-29 20:36 ` Grant Likely
2012-01-30 11:36 ` Andreas Färber
2012-01-30 13:31 ` Grant Likely
2012-01-30 0:24 ` John Williams
2012-01-29 20:42 ` Edgar E. Iglesias
2012-01-29 23:54 ` Peter Crosthwaite
2012-01-30 13:40 ` Grant Likely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F4BC039.8060808@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=grant.likely@secretlab.ca \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.