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