1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Read a bootflow from SPI flash
4  *
5  * Copyright 2022 Google LLC
6  */
7 
8 #include <common.h>
9 #include <bootdev.h>
10 #include <bootflow.h>
11 #include <bootmeth.h>
12 #include <dm.h>
13 #include <env.h>
14 #include <malloc.h>
15 #include <spi_flash.h>
16 
sf_get_bootflow(struct udevice * dev,struct bootflow_iter * iter,struct bootflow * bflow)17 static int sf_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
18 			   struct bootflow *bflow)
19 {
20 	struct udevice *sf = dev_get_parent(dev);
21 	uint size;
22 	char *buf;
23 	int ret;
24 
25 	/* We only support the whole device, not partitions */
26 	if (iter->part)
27 		return log_msg_ret("max", -ESHUTDOWN);
28 
29 	size = env_get_hex("script_size_f", 0);
30 	if (!size)
31 		return log_msg_ret("sz", -EINVAL);
32 
33 	buf = malloc(size + 1);
34 	if (!buf)
35 		return log_msg_ret("buf", -ENOMEM);
36 
37 	ret = spi_flash_read_dm(sf, env_get_hex("script_offset_f", 0),
38 				size, buf);
39 	if (ret)
40 		return log_msg_ret("cmd", -EINVAL);
41 	bflow->state = BOOTFLOWST_MEDIA;
42 
43 	ret = bootmeth_set_bootflow(bflow->method, bflow, buf, size);
44 	if (ret) {
45 		free(buf);
46 		return log_msg_ret("method", ret);
47 	}
48 
49 	return 0;
50 }
51 
sf_bootdev_bind(struct udevice * dev)52 static int sf_bootdev_bind(struct udevice *dev)
53 {
54 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
55 
56 	ucp->prio = BOOTDEVP_4_SCAN_FAST;
57 
58 	return 0;
59 }
60 
61 struct bootdev_ops sf_bootdev_ops = {
62 	.get_bootflow	= sf_get_bootflow,
63 };
64 
65 static const struct udevice_id sf_bootdev_ids[] = {
66 	{ .compatible = "u-boot,bootdev-sf" },
67 	{ }
68 };
69 
70 U_BOOT_DRIVER(sf_bootdev) = {
71 	.name		= "sf_bootdev",
72 	.id		= UCLASS_BOOTDEV,
73 	.ops		= &sf_bootdev_ops,
74 	.bind		= sf_bootdev_bind,
75 	.of_match	= sf_bootdev_ids,
76 };
77 
78 BOOTDEV_HUNTER(sf_bootdev_hunter) = {
79 	.prio		= BOOTDEVP_4_SCAN_FAST,
80 	.uclass		= UCLASS_SPI_FLASH,
81 	.drv		= DM_DRIVER_REF(sf_bootdev),
82 };
83