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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).