1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Verified Boot for Embedded (VBE) access functions
4 *
5 * Copyright 2022 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#include <common.h>
10#include <bootmeth.h>
11#include <bootstd.h>
12#include <dm.h>
13#include <image.h>
14#include <vbe.h>
15#include <dm/uclass-internal.h>
16
17/**
18 * is_vbe() - Check if a device is a VBE method
19 *
20 * @dev: Device to check
21 * @return true if this is a VBE bootmth device, else false
22 */
23static bool is_vbe(struct udevice *dev)
24{
25	return !strncmp("vbe", dev->driver->name, 3);
26}
27
28int vbe_find_next_device(struct udevice **devp)
29{
30	for (uclass_find_next_device(devp);
31	     *devp;
32	     uclass_find_next_device(devp)) {
33		if (is_vbe(*devp))
34			return 0;
35	}
36
37	return 0;
38}
39
40int vbe_find_first_device(struct udevice **devp)
41{
42	uclass_find_first_device(UCLASS_BOOTMETH, devp);
43	if (!*devp || is_vbe(*devp))
44		return 0;
45
46	return vbe_find_next_device(devp);
47}
48
49int vbe_list(void)
50{
51	struct bootstd_priv *std;
52	struct udevice *dev;
53	int ret;
54
55	ret = bootstd_get_priv(&std);
56	if (ret)
57		return ret;
58
59	printf("%3s  %-3s  %-15s  %-15s %s\n", "#", "Sel", "Device", "Driver",
60	       "Description");
61	printf("%3s  %-3s  %-15s  %-15s %s\n", "---", "---", "--------------",
62	       "--------------", "-----------");
63	for (ret = vbe_find_first_device(&dev); dev;
64	     ret = vbe_find_next_device(&dev)) {
65		const struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
66
67		printf("%3d  %-3s  %-15s  %-15s %s\n", dev_seq(dev),
68		       std->vbe_bootmeth == dev ? "*" : "", dev->name,
69		       dev->driver->name, plat->desc);
70	}
71	printf("%3s  %-3s  %-15s  %-15s %s\n", "---", "---", "--------------",
72	       "--------------", "-----------");
73
74	return 0;
75}
76
77int vbe_select(struct udevice *dev)
78{
79	struct bootstd_priv *std;
80	int ret;
81
82	ret = bootstd_get_priv(&std);
83	if (ret)
84		return ret;
85	std->vbe_bootmeth = dev;
86
87	return 0;
88}
89
90int vbe_find_by_any(const char *name, struct udevice **devp)
91{
92	struct udevice *dev;
93	int ret, seq;
94	char *endp;
95
96	seq = simple_strtol(name, &endp, 16);
97
98	/* Select by name */
99	if (*endp) {
100		ret = uclass_get_device_by_name(UCLASS_BOOTMETH, name, &dev);
101		if (ret) {
102			printf("Cannot probe VBE bootmeth '%s' (err=%d)\n", name,
103			       ret);
104			return ret;
105		}
106
107	/* select by number */
108	} else {
109		ret = uclass_get_device_by_seq(UCLASS_BOOTMETH, seq, &dev);
110		if (ret) {
111			printf("Cannot find '%s' (err=%d)\n", name, ret);
112			return ret;
113		}
114	}
115
116	*devp = dev;
117
118	return 0;
119}
120