| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * Verified Boot for Embedded (VBE) access functions | |
| * | |
| * Copyright 2022 Google LLC | |
| * Written by Simon Glass <sjg@chromium.org> | |
| */ | |
| #include <common.h> | |
| #include <bootmeth.h> | |
| #include <bootstd.h> | |
| #include <dm.h> | |
| #include <image.h> | |
| #include <vbe.h> | |
| #include <dm/uclass-internal.h> | |
| /** | |
| * is_vbe() - Check if a device is a VBE method | |
| * | |
| * @dev: Device to check | |
| * @return true if this is a VBE bootmth device, else false | |
| */ | |
| static bool is_vbe(struct udevice *dev) | |
| { | |
| return !strncmp("vbe", dev->driver->name, 3); | |
| } | |
| int vbe_find_next_device(struct udevice **devp) | |
| { | |
| for (uclass_find_next_device(devp); | |
| *devp; | |
| uclass_find_next_device(devp)) { | |
| if (is_vbe(*devp)) | |
| return 0; | |
| } | |
| return 0; | |
| } | |
| int vbe_find_first_device(struct udevice **devp) | |
| { | |
| uclass_find_first_device(UCLASS_BOOTMETH, devp); | |
| if (!*devp || is_vbe(*devp)) | |
| return 0; | |
| return vbe_find_next_device(devp); | |
| } | |
| int vbe_list(void) | |
| { | |
| struct bootstd_priv *std; | |
| struct udevice *dev; | |
| int ret; | |
| ret = bootstd_get_priv(&std); | |
| if (ret) | |
| return ret; | |
| printf("%3s %-3s %-15s %-15s %s\n", "#", "Sel", "Device", "Driver", | |
| "Description"); | |
| printf("%3s %-3s %-15s %-15s %s\n", "---", "---", "--------------", | |
| "--------------", "-----------"); | |
| for (ret = vbe_find_first_device(&dev); dev; | |
| ret = vbe_find_next_device(&dev)) { | |
| const struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev); | |
| printf("%3d %-3s %-15s %-15s %s\n", dev_seq(dev), | |
| std->vbe_bootmeth == dev ? "*" : "", dev->name, | |
| dev->driver->name, plat->desc); | |
| } | |
| printf("%3s %-3s %-15s %-15s %s\n", "---", "---", "--------------", | |
| "--------------", "-----------"); | |
| return 0; | |
| } | |
| int vbe_select(struct udevice *dev) | |
| { | |
| struct bootstd_priv *std; | |
| int ret; | |
| ret = bootstd_get_priv(&std); | |
| if (ret) | |
| return ret; | |
| std->vbe_bootmeth = dev; | |
| return 0; | |
| } | |
| int vbe_find_by_any(const char *name, struct udevice **devp) | |
| { | |
| struct udevice *dev; | |
| int ret, seq; | |
| char *endp; | |
| seq = simple_strtol(name, &endp, 16); | |
| /* Select by name */ | |
| if (*endp) { | |
| ret = uclass_get_device_by_name(UCLASS_BOOTMETH, name, &dev); | |
| if (ret) { | |
| printf("Cannot probe VBE bootmeth '%s' (err=%d)\n", name, | |
| ret); | |
| return ret; | |
| } | |
| /* select by number */ | |
| } else { | |
| ret = uclass_get_device_by_seq(UCLASS_BOOTMETH, seq, &dev); | |
| if (ret) { | |
| printf("Cannot find '%s' (err=%d)\n", name, ret); | |
| return ret; | |
| } | |
| } | |
| *devp = dev; | |
| return 0; | |
| } |