blob: 017a74a3016fc6bd664ccfdd24270e2797a14787 [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
Simon Glass215be682023-01-17 10:48:03 -07008#include <bootdev.h>
9#include <bootflow.h>
10#include <bootmeth.h>
11#include <dm.h>
12#include <env.h>
13#include <malloc.h>
14#include <spi_flash.h>
15
16static int sf_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
17 struct bootflow *bflow)
18{
19 struct udevice *sf = dev_get_parent(dev);
20 uint size;
21 char *buf;
22 int ret;
23
24 /* We only support the whole device, not partitions */
25 if (iter->part)
26 return log_msg_ret("max", -ESHUTDOWN);
27
28 size = env_get_hex("script_size_f", 0);
29 if (!size)
30 return log_msg_ret("sz", -EINVAL);
31
32 buf = malloc(size + 1);
33 if (!buf)
34 return log_msg_ret("buf", -ENOMEM);
35
36 ret = spi_flash_read_dm(sf, env_get_hex("script_offset_f", 0),
37 size, buf);
38 if (ret)
39 return log_msg_ret("cmd", -EINVAL);
40 bflow->state = BOOTFLOWST_MEDIA;
41
42 ret = bootmeth_set_bootflow(bflow->method, bflow, buf, size);
43 if (ret) {
44 free(buf);
45 return log_msg_ret("method", ret);
46 }
47
48 return 0;
49}
50
51static int sf_bootdev_bind(struct udevice *dev)
52{
53 struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
54
Simon Glass7e1f6a42023-01-17 10:48:08 -070055 ucp->prio = BOOTDEVP_4_SCAN_FAST;
Simon Glass215be682023-01-17 10:48:03 -070056
57 return 0;
58}
59
60struct bootdev_ops sf_bootdev_ops = {
61 .get_bootflow = sf_get_bootflow,
62};
63
64static const struct udevice_id sf_bootdev_ids[] = {
65 { .compatible = "u-boot,bootdev-sf" },
66 { }
67};
68
69U_BOOT_DRIVER(sf_bootdev) = {
70 .name = "sf_bootdev",
71 .id = UCLASS_BOOTDEV,
72 .ops = &sf_bootdev_ops,
73 .bind = sf_bootdev_bind,
74 .of_match = sf_bootdev_ids,
75};
76
77BOOTDEV_HUNTER(sf_bootdev_hunter) = {
Simon Glass7e1f6a42023-01-17 10:48:08 -070078 .prio = BOOTDEVP_4_SCAN_FAST,
Simon Glass215be682023-01-17 10:48:03 -070079 .uclass = UCLASS_SPI_FLASH,
80 .drv = DM_DRIVER_REF(sf_bootdev),
81};