1 // SPDX-License-Identifier: GPL-2.0+
3 * Bootmethod for QEMU qfw
5 * Copyright 2023 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
9 #define LOG_CATEGORY UCLASS_BOOTSTD
20 static int qfw_check(struct udevice
*dev
, struct bootflow_iter
*iter
)
22 const struct udevice
*media
= dev_get_parent(iter
->dev
);
23 enum uclass_id id
= device_get_uclass_id(media
);
25 log_debug("media=%s\n", media
->name
);
32 static int qfw_read_bootflow(struct udevice
*dev
, struct bootflow
*bflow
)
34 struct udevice
*qfw_dev
= dev_get_parent(bflow
->dev
);
38 load
= env_get_hex("kernel_addr_r", 0);
39 initrd
= env_get_hex("ramdisk_addr_r", 0);
40 log_debug("setup kernel %s %lx %lx\n", qfw_dev
->name
, load
, initrd
);
41 bflow
->name
= strdup("qfw");
43 return log_msg_ret("name", -ENOMEM
);
45 ret
= qemu_fwcfg_setup_kernel(qfw_dev
, load
, initrd
);
46 log_debug("setup kernel result %d\n", ret
);
48 return log_msg_ret("cmd", -EIO
);
50 bflow
->state
= BOOTFLOWST_READY
;
55 static int qfw_read_file(struct udevice
*dev
, struct bootflow
*bflow
,
56 const char *file_path
, ulong addr
, ulong
*sizep
)
61 static int qfw_boot(struct udevice
*dev
, struct bootflow
*bflow
)
65 ret
= run_command("booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdtcontroladdr}",
68 ret
= run_command("bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} "
69 "${fdtcontroladdr}", 0);
72 return ret
? -EIO
: 0;
75 static int qfw_bootmeth_bind(struct udevice
*dev
)
77 struct bootmeth_uc_plat
*plat
= dev_get_uclass_plat(dev
);
79 plat
->desc
= "QEMU boot using firmware interface";
84 static struct bootmeth_ops qfw_bootmeth_ops
= {
86 .read_bootflow
= qfw_read_bootflow
,
87 .read_file
= qfw_read_file
,
91 static const struct udevice_id qfw_bootmeth_ids
[] = {
92 { .compatible
= "u-boot,qfw-extlinux" },
96 U_BOOT_DRIVER(bootmeth_qfw
) = {
97 .name
= "bootmeth_qfw",
98 .id
= UCLASS_BOOTMETH
,
99 .of_match
= qfw_bootmeth_ids
,
100 .ops
= &qfw_bootmeth_ops
,
101 .bind
= qfw_bootmeth_bind
,