blob: d6b47b11ce451e430463a5a18d4469562b9f70de [file] [log] [blame]
Simon Glass215be682023-01-17 10:48:03 -07001// 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
17static 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
52static int sf_bootdev_bind(struct udevice *dev)
53{
54 struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
55
Simon Glass7e1f6a42023-01-17 10:48:08 -070056 ucp->prio = BOOTDEVP_4_SCAN_FAST;
Simon Glass215be682023-01-17 10:48:03 -070057
58 return 0;
59}
60
61struct bootdev_ops sf_bootdev_ops = {
62 .get_bootflow = sf_get_bootflow,
63};
64
65static const struct udevice_id sf_bootdev_ids[] = {
66 { .compatible = "u-boot,bootdev-sf" },
67 { }
68};
69
70U_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
78BOOTDEV_HUNTER(sf_bootdev_hunter) = {
Simon Glass7e1f6a42023-01-17 10:48:08 -070079 .prio = BOOTDEVP_4_SCAN_FAST,
Simon Glass215be682023-01-17 10:48:03 -070080 .uclass = UCLASS_SPI_FLASH,
81 .drv = DM_DRIVER_REF(sf_bootdev),
82};