vbe_simple_os.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Verified Boot for Embedded (VBE) loading firmware phases
  4. *
  5. * Copyright 2022 Google LLC
  6. * Written by Simon Glass <sjg@chromium.org>
  7. */
  8. #define LOG_CATEGORY LOGC_BOOT
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <bootflow.h>
  12. #include <vbe.h>
  13. #include <version_string.h>
  14. #include <dm/device-internal.h>
  15. #include "vbe_simple.h"
  16. int vbe_simple_fixup_node(ofnode node, struct simple_state *state)
  17. {
  18. const char *version, *str;
  19. int ret;
  20. version = strdup(state->fw_version);
  21. if (!version)
  22. return log_msg_ret("dup", -ENOMEM);
  23. ret = ofnode_write_string(node, "cur-version", version);
  24. if (ret)
  25. return log_msg_ret("ver", ret);
  26. ret = ofnode_write_u32(node, "cur-vernum", state->fw_vernum);
  27. if (ret)
  28. return log_msg_ret("num", ret);
  29. /* Drop the 'U-Boot ' at the start */
  30. str = version_string;
  31. if (!strncmp("U-Boot ", str, 7))
  32. str += 7;
  33. ret = ofnode_write_string(node, "bootloader-version", str);
  34. if (ret)
  35. return log_msg_ret("bl", ret);
  36. return 0;
  37. }
  38. /**
  39. * bootmeth_vbe_simple_ft_fixup() - Write out all VBE simple data to the DT
  40. *
  41. * @ctx: Context for event
  42. * @event: Event to process
  43. * @return 0 if OK, -ve on error
  44. */
  45. static int bootmeth_vbe_simple_ft_fixup(void *ctx, struct event *event)
  46. {
  47. oftree tree = event->data.ft_fixup.tree;
  48. struct udevice *dev;
  49. /*
  50. * Ideally we would have driver model support for fixups, but that does
  51. * not exist yet. It is a step too far to try to do this before VBE is
  52. * in place.
  53. */
  54. for (vbe_find_first_device(&dev); dev; vbe_find_next_device(&dev)) {
  55. struct simple_state state;
  56. ofnode node, subnode, chosen;
  57. int ret;
  58. if (strcmp("vbe_simple", dev->driver->name))
  59. continue;
  60. /* Check if there is a node to fix up, adding if not */
  61. chosen = oftree_path(tree, "/chosen");
  62. if (!ofnode_valid(chosen))
  63. continue;
  64. ret = device_probe(dev);
  65. if (ret) {
  66. /*
  67. * This should become an error when VBE is updated to
  68. * only bind this device when a node exists
  69. */
  70. log_debug("VBE device '%s' failed to probe (err=%d)",
  71. dev->name, ret);
  72. return 0;
  73. }
  74. ret = ofnode_add_subnode(chosen, "fwupd", &node);
  75. if (ret && ret != -EEXIST)
  76. return log_msg_ret("fwu", ret);
  77. ret = ofnode_add_subnode(node, dev->name, &subnode);
  78. if (ret && ret != -EEXIST)
  79. return log_msg_ret("dev", ret);
  80. /* Copy over the vbe properties for fwupd */
  81. log_debug("Fixing up: %s\n", dev->name);
  82. ret = ofnode_copy_props(dev_ofnode(dev), subnode);
  83. if (ret)
  84. return log_msg_ret("cp", ret);
  85. ret = vbe_simple_read_state(dev, &state);
  86. if (ret)
  87. return log_msg_ret("read", ret);
  88. ret = vbe_simple_fixup_node(subnode, &state);
  89. if (ret)
  90. return log_msg_ret("fix", ret);
  91. }
  92. return 0;
  93. }
  94. EVENT_SPY(EVT_FT_FIXUP, bootmeth_vbe_simple_ft_fixup);