sf_bootdev.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Read a bootflow from SPI flash
  4. *
  5. * Copyright 2022 Google LLC
  6. */
  7. #include <common.h>
  8. #include <bootdev.h>
  9. #include <bootflow.h>
  10. #include <bootmeth.h>
  11. #include <dm.h>
  12. #include <env.h>
  13. #include <malloc.h>
  14. #include <spi_flash.h>
  15. static int sf_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
  16. struct bootflow *bflow)
  17. {
  18. struct udevice *sf = dev_get_parent(dev);
  19. uint size;
  20. char *buf;
  21. int ret;
  22. /* We only support the whole device, not partitions */
  23. if (iter->part)
  24. return log_msg_ret("max", -ESHUTDOWN);
  25. size = env_get_hex("script_size_f", 0);
  26. if (!size)
  27. return log_msg_ret("sz", -EINVAL);
  28. buf = malloc(size + 1);
  29. if (!buf)
  30. return log_msg_ret("buf", -ENOMEM);
  31. ret = spi_flash_read_dm(sf, env_get_hex("script_offset_f", 0),
  32. size, buf);
  33. if (ret)
  34. return log_msg_ret("cmd", -EINVAL);
  35. bflow->state = BOOTFLOWST_MEDIA;
  36. ret = bootmeth_set_bootflow(bflow->method, bflow, buf, size);
  37. if (ret) {
  38. free(buf);
  39. return log_msg_ret("method", ret);
  40. }
  41. return 0;
  42. }
  43. static int sf_bootdev_bind(struct udevice *dev)
  44. {
  45. struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
  46. ucp->prio = BOOTDEVP_4_SCAN_FAST;
  47. return 0;
  48. }
  49. struct bootdev_ops sf_bootdev_ops = {
  50. .get_bootflow = sf_get_bootflow,
  51. };
  52. static const struct udevice_id sf_bootdev_ids[] = {
  53. { .compatible = "u-boot,bootdev-sf" },
  54. { }
  55. };
  56. U_BOOT_DRIVER(sf_bootdev) = {
  57. .name = "sf_bootdev",
  58. .id = UCLASS_BOOTDEV,
  59. .ops = &sf_bootdev_ops,
  60. .bind = sf_bootdev_bind,
  61. .of_match = sf_bootdev_ids,
  62. };
  63. BOOTDEV_HUNTER(sf_bootdev_hunter) = {
  64. .prio = BOOTDEVP_4_SCAN_FAST,
  65. .uclass = UCLASS_SPI_FLASH,
  66. .drv = DM_DRIVER_REF(sf_bootdev),
  67. };