diff options
-rw-r--r-- | cmd/qfw.c | 69 | ||||
-rw-r--r-- | common/qfw.c | 66 | ||||
-rw-r--r-- | include/qfw.h | 13 |
3 files changed, 79 insertions, 69 deletions
diff --git a/cmd/qfw.c b/cmd/qfw.c index 8837911d99f..ae3c6a7a84e 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -7,78 +7,11 @@ #include <command.h> #include <env.h> #include <errno.h> -#include <mapmem.h> #include <qfw.h> #include <dm.h> static struct udevice *qfw_dev; -/* - * This function prepares kernel for zboot. It loads kernel data - * to 'load_addr', initrd to 'initrd_addr' and kernel command - * line using qemu fw_cfg interface. - */ -int qemu_fwcfg_cmd_setup_kernel(ulong load_addr, ulong initrd_addr) -{ - char *data_addr; - uint32_t setup_size, kernel_size, cmdline_size, initrd_size; - - qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); - qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); - - if (!kernel_size) { - printf("fatal: no kernel available\n"); - return -ENOENT; - } - - data_addr = map_sysmem(load_addr, 0); - if (setup_size) { - qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, - le32_to_cpu(setup_size), data_addr); - data_addr += le32_to_cpu(setup_size); - } - - qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, - le32_to_cpu(kernel_size), data_addr); - data_addr += le32_to_cpu(kernel_size); - env_set_hex("filesize", le32_to_cpu(kernel_size)); - - data_addr = map_sysmem(initrd_addr, 0); - qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); - if (!initrd_size) { - printf("warning: no initrd available\n"); - } else { - qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, - le32_to_cpu(initrd_size), data_addr); - data_addr += le32_to_cpu(initrd_size); - env_set_hex("filesize", le32_to_cpu(initrd_size)); - } - - qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); - if (cmdline_size) { - qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA, - le32_to_cpu(cmdline_size), data_addr); - /* - * if kernel cmdline only contains '\0', (e.g. no -append - * when invoking qemu), do not update bootargs - */ - if (*data_addr) { - if (env_set("bootargs", data_addr) < 0) - printf("warning: unable to change bootargs\n"); - } - } - - printf("loading kernel to address %lx size %x", load_addr, - le32_to_cpu(kernel_size)); - if (initrd_size) - printf(" initrd %lx size %x\n", initrd_addr, - le32_to_cpu(initrd_size)); - else - printf("\n"); - - return 0; -} - static int qemu_fwcfg_cmd_list_firmware(void) { int ret; @@ -148,7 +81,7 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag, return CMD_RET_FAILURE; } - return qemu_fwcfg_cmd_setup_kernel(load_addr, initrd_addr); + return qemu_fwcfg_setup_kernel(qfw_dev, load_addr, initrd_addr); } static struct cmd_tbl fwcfg_commands[] = { diff --git a/common/qfw.c b/common/qfw.c index 90cbb8c5dd4..45e87d3ae28 100644 --- a/common/qfw.c +++ b/common/qfw.c @@ -5,9 +5,11 @@ */ #include <dm.h> -#include <dm/uclass.h> +#include <env.h> +#include <mapmem.h> #include <qfw.h> #include <stdlib.h> +#include <dm/uclass.h> int qfw_get_dev(struct udevice **devp) { @@ -102,3 +104,65 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter) { return iter->entry == iter->end; } + +int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr, + ulong initrd_addr) +{ + char *data_addr; + u32 setup_size, kernel_size, cmdline_size, initrd_size; + + qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size); + qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size); + + if (!kernel_size) { + printf("fatal: no kernel available\n"); + return -ENOENT; + } + + data_addr = map_sysmem(load_addr, 0); + if (setup_size) { + qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, + le32_to_cpu(setup_size), data_addr); + data_addr += le32_to_cpu(setup_size); + } + + qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, + le32_to_cpu(kernel_size), data_addr); + data_addr += le32_to_cpu(kernel_size); + env_set_hex("filesize", le32_to_cpu(kernel_size)); + + data_addr = map_sysmem(initrd_addr, 0); + qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size); + if (!initrd_size) { + printf("warning: no initrd available\n"); + } else { + qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, + le32_to_cpu(initrd_size), data_addr); + data_addr += le32_to_cpu(initrd_size); + env_set_hex("filesize", le32_to_cpu(initrd_size)); + } + + qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size); + if (cmdline_size) { + qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA, + le32_to_cpu(cmdline_size), data_addr); + /* + * if kernel cmdline only contains '\0', (e.g. no -append + * when invoking qemu), do not update bootargs + */ + if (*data_addr) { + if (env_set("bootargs", data_addr) < 0) + printf("warning: unable to change bootargs\n"); + } + } + + printf("loading kernel to address %lx size %x", load_addr, + le32_to_cpu(kernel_size)); + if (initrd_size) + printf(" initrd %lx size %x\n", initrd_addr, + le32_to_cpu(initrd_size)); + else + printf("\n"); + + return 0; +} diff --git a/include/qfw.h b/include/qfw.h index 7ca132e66a2..42798fea7db 100644 --- a/include/qfw.h +++ b/include/qfw.h @@ -316,4 +316,17 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter); */ int qemu_cpu_fixup(void); +/* + * qemu_fwcfg_setup_kernel() - Prepare the kernel for zboot + * + * Loads kernel data to 'load_addr', initrd to 'initrd_addr' and kernel command + * line using qemu fw_cfg interface + * + * @load_addr: Load address for kernel + * @initrd_addr: Load address for ramdisk + * @return 0 if OK, -ENOENT if no kernel + */ +int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr, + ulong initrd_addr); + #endif |