Add a VBE-ABrec bootmeth so that the VBE state can be accessed.

Signed-off-by: Simon Glass <s...@chromium.org>
---

Changes in v2:
- Add new patch with a bootmeth driver for abrec

 boot/vbe_abrec.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/boot/vbe_abrec.c b/boot/vbe_abrec.c
index 6d0f622262d..8593082fd79 100644
--- a/boot/vbe_abrec.c
+++ b/boot/vbe_abrec.c
@@ -8,6 +8,7 @@
 
 #define LOG_CATEGORY LOGC_BOOT
 
+#include <bootmeth.h>
 #include <dm.h>
 #include <memalign.h>
 #include <mmc.h>
@@ -81,3 +82,101 @@ int abrec_read_state(struct udevice *dev, struct 
abrec_state *state)
 
        return 0;
 }
+
+static int vbe_abrec_get_state_desc(struct udevice *dev, char *buf,
+                                   int maxsize)
+{
+       struct abrec_state state;
+       int ret;
+
+       ret = abrec_read_state(dev, &state);
+       if (ret)
+               return log_msg_ret("read", ret);
+
+       if (maxsize < 30)
+               return -ENOSPC;
+       snprintf(buf, maxsize, "Version: %s\nVernum: %x/%x", state.fw_version,
+                state.fw_vernum >> FWVER_KEY_SHIFT,
+                state.fw_vernum & FWVER_FW_MASK);
+
+       return 0;
+}
+
+static int vbe_abrec_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+       int ret;
+
+       if (CONFIG_IS_ENABLED(BOOTMETH_VBE_ABREC_FW)) {
+               if (vbe_phase() == VBE_PHASE_FIRMWARE) {
+                       ret = abrec_read_bootflow_fw(dev, bflow);
+                       if (ret)
+                               return log_msg_ret("fw", ret);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int vbe_abrec_read_file(struct udevice *dev, struct bootflow *bflow,
+                              const char *file_path, ulong addr,
+                              enum bootflow_img_t type, ulong *sizep)
+{
+       int ret;
+
+       if (vbe_phase() == VBE_PHASE_OS) {
+               ret = bootmeth_common_read_file(dev, bflow, file_path, addr,
+                                               type, sizep);
+               if (ret)
+                       return log_msg_ret("os", ret);
+       }
+
+       /* To be implemented */
+       return -EINVAL;
+}
+
+static struct bootmeth_ops bootmeth_vbe_abrec_ops = {
+       .get_state_desc = vbe_abrec_get_state_desc,
+       .read_bootflow  = vbe_abrec_read_bootflow,
+       .read_file      = vbe_abrec_read_file,
+};
+
+static int bootmeth_vbe_abrec_probe(struct udevice *dev)
+{
+       struct abrec_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = abrec_read_priv(dev_ofnode(dev), priv);
+       if (ret)
+               return log_msg_ret("abp", ret);
+
+       return 0;
+}
+
+static int bootmeth_vbe_abrec_bind(struct udevice *dev)
+{
+       struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
+
+       plat->desc = "VBE A/B/recovery";
+       plat->flags = BOOTMETHF_GLOBAL;
+
+       return 0;
+}
+
+#if CONFIG_IS_ENABLED(OF_REAL)
+static const struct udevice_id generic_simple_vbe_abrec_ids[] = {
+       { .compatible = "fwupd,vbe-abrec" },
+       { }
+};
+#endif
+
+U_BOOT_DRIVER(vbe_abrec) = {
+       .name   = "vbe_abrec",
+       .id     = UCLASS_BOOTMETH,
+       .of_match = of_match_ptr(generic_simple_vbe_abrec_ids),
+       .ops    = &bootmeth_vbe_abrec_ops,
+       .bind   = bootmeth_vbe_abrec_bind,
+       .probe  = bootmeth_vbe_abrec_probe,
+       .flags  = DM_FLAG_PRE_RELOC,
+       .priv_auto      = sizeof(struct abrec_priv),
+};
-- 
2.43.0

Reply via email to