qfw_sandbox.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Sandbox interface for QFW
  4. *
  5. * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
  6. * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
  7. */
  8. #define LOG_CATEGORY UCLASS_QFW
  9. #include <asm/types.h>
  10. #include <asm/io.h>
  11. #include <dm.h>
  12. #include <dm/device.h>
  13. #include <qfw.h>
  14. struct qfw_sandbox_plat {
  15. u8 file_dir_offset;
  16. };
  17. static void qfw_sandbox_read_entry_io(struct udevice *dev, u16 entry, u32 size,
  18. void *address)
  19. {
  20. debug("%s: entry 0x%x size %u address %p\n", __func__, entry, size,
  21. address);
  22. switch (entry) {
  23. case FW_CFG_SIGNATURE:
  24. if (size == 4)
  25. *((u32 *)address) = cpu_to_be32(QEMU_FW_CFG_SIGNATURE);
  26. break;
  27. case FW_CFG_ID:
  28. /* Advertise DMA support */
  29. if (size == 1)
  30. *((u8 *)address) = FW_CFG_DMA_ENABLED;
  31. break;
  32. default:
  33. debug("%s got unsupported entry 0x%x\n", __func__, entry);
  34. /*
  35. * Sandbox driver doesn't support other entries here, assume we use DMA
  36. * to read them -- the uclass driver will exclusively use it when
  37. * advertised.
  38. */
  39. }
  40. }
  41. static void qfw_sandbox_read_entry_dma(struct udevice *dev, struct qfw_dma *dma)
  42. {
  43. u16 entry;
  44. u32 control = be32_to_cpu(dma->control);
  45. void *address = (void *)be64_to_cpu(dma->address);
  46. u32 length = be32_to_cpu(dma->length);
  47. struct qfw_sandbox_plat *plat = dev_get_plat(dev);
  48. struct fw_cfg_file *file;
  49. debug("%s\n", __func__);
  50. if (!(control & FW_CFG_DMA_READ))
  51. return;
  52. if (control & FW_CFG_DMA_SELECT) {
  53. /* Start new read. */
  54. entry = control >> 16;
  55. /* Arbitrary values to be used by tests. */
  56. switch (entry) {
  57. case FW_CFG_NB_CPUS:
  58. if (length == 2)
  59. *((u16 *)address) = cpu_to_le16(5);
  60. break;
  61. case FW_CFG_FILE_DIR:
  62. if (length == 4) {
  63. *((u32 *)address) = cpu_to_be32(2);
  64. plat->file_dir_offset = 1;
  65. }
  66. break;
  67. default:
  68. debug("%s got unsupported entry 0x%x\n", __func__,
  69. entry);
  70. }
  71. } else if (plat->file_dir_offset && length == 64) {
  72. file = address;
  73. switch (plat->file_dir_offset) {
  74. case 1:
  75. file->size = cpu_to_be32(8);
  76. file->select = cpu_to_be16(FW_CFG_FILE_FIRST);
  77. strcpy(file->name, "test-one");
  78. plat->file_dir_offset++;
  79. break;
  80. case 2:
  81. file->size = cpu_to_be32(8);
  82. file->select = cpu_to_be16(FW_CFG_FILE_FIRST + 1);
  83. strcpy(file->name, "test-two");
  84. plat->file_dir_offset++;
  85. break;
  86. }
  87. }
  88. /*
  89. * Signal that we are finished. No-one checks this in sandbox --
  90. * normally the platform-specific driver looks for it -- but let's
  91. * replicate the behaviour in case someone relies on it later.
  92. */
  93. dma->control = 0;
  94. }
  95. static int qfw_sandbox_probe(struct udevice *dev)
  96. {
  97. return qfw_register(dev);
  98. }
  99. static struct dm_qfw_ops qfw_sandbox_ops = {
  100. .read_entry_io = qfw_sandbox_read_entry_io,
  101. .read_entry_dma = qfw_sandbox_read_entry_dma,
  102. };
  103. U_BOOT_DRIVER(qfw_sandbox) = {
  104. .name = "qfw_sandbox",
  105. .id = UCLASS_QFW,
  106. .plat_auto = sizeof(struct qfw_sandbox_plat),
  107. .probe = qfw_sandbox_probe,
  108. .ops = &qfw_sandbox_ops,
  109. };
  110. U_BOOT_DRVINFO(qfw_sandbox) = {
  111. .name = "qfw_sandbox",
  112. };