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  */
is_vbe(struct udevice * dev)23 static bool is_vbe(struct udevice *dev)
24 {
25 	return !strncmp("vbe", dev->driver->name, 3);
26 }
27 
vbe_find_next_device(struct udevice ** devp)28 int 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 
vbe_find_first_device(struct udevice ** devp)40 int 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 
vbe_list(void)49 int 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 
vbe_select(struct udevice * dev)77 int 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 
vbe_find_by_any(const char * name,struct udevice ** devp)90 int 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