qfw.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
  4. * (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
  5. */
  6. #define LOG_CATEGORY UCLASS_QFW
  7. #include <common.h>
  8. #include <bootdev.h>
  9. #include <bootflow.h>
  10. #include <bootmeth.h>
  11. #include <command.h>
  12. #include <errno.h>
  13. #include <log.h>
  14. #include <malloc.h>
  15. #include <qfw.h>
  16. #include <dm.h>
  17. #include <misc.h>
  18. #include <tables_csum.h>
  19. #include <asm/acpi_table.h>
  20. #if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX)
  21. /*
  22. * This function allocates memory for ACPI tables
  23. *
  24. * @entry : BIOS linker command entry which tells where to allocate memory
  25. * (either high memory or low memory)
  26. * @addr : The address that should be used for low memory allcation. If the
  27. * memory allocation request is 'ZONE_HIGH' then this parameter will
  28. * be ignored.
  29. * @return: 0 on success, or negative value on failure
  30. */
  31. static int bios_linker_allocate(struct udevice *dev,
  32. struct bios_linker_entry *entry, ulong *addr)
  33. {
  34. uint32_t size, align;
  35. struct fw_file *file;
  36. unsigned long aligned_addr;
  37. align = le32_to_cpu(entry->alloc.align);
  38. /* align must be power of 2 */
  39. if (align & (align - 1)) {
  40. printf("error: wrong alignment %u\n", align);
  41. return -EINVAL;
  42. }
  43. file = qfw_find_file(dev, entry->alloc.file);
  44. if (!file) {
  45. printf("error: can't find file %s\n", entry->alloc.file);
  46. return -ENOENT;
  47. }
  48. size = be32_to_cpu(file->cfg.size);
  49. /*
  50. * ZONE_HIGH means we need to allocate from high memory, since
  51. * malloc space is already at the end of RAM, so we directly use it.
  52. * If allocation zone is ZONE_FSEG, then we use the 'addr' passed
  53. * in which is low memory
  54. */
  55. if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
  56. aligned_addr = (unsigned long)memalign(align, size);
  57. if (!aligned_addr) {
  58. printf("error: allocating resource\n");
  59. return -ENOMEM;
  60. }
  61. if (aligned_addr < gd->arch.table_start_high)
  62. gd->arch.table_start_high = aligned_addr;
  63. if (aligned_addr + size > gd->arch.table_end_high)
  64. gd->arch.table_end_high = aligned_addr + size;
  65. } else if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG) {
  66. aligned_addr = ALIGN(*addr, align);
  67. } else {
  68. printf("error: invalid allocation zone\n");
  69. return -EINVAL;
  70. }
  71. debug("bios_linker_allocate: allocate file %s, size %u, zone %d, align %u, addr 0x%lx\n",
  72. file->cfg.name, size, entry->alloc.zone, align, aligned_addr);
  73. qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size,
  74. (void *)aligned_addr);
  75. file->addr = aligned_addr;
  76. /* adjust address for low memory allocation */
  77. if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG)
  78. *addr = (aligned_addr + size);
  79. return 0;
  80. }
  81. /*
  82. * This function patches ACPI tables previously loaded
  83. * by bios_linker_allocate()
  84. *
  85. * @entry : BIOS linker command entry which tells how to patch
  86. * ACPI tables
  87. * @return: 0 on success, or negative value on failure
  88. */
  89. static int bios_linker_add_pointer(struct udevice *dev,
  90. struct bios_linker_entry *entry)
  91. {
  92. struct fw_file *dest, *src;
  93. uint32_t offset = le32_to_cpu(entry->pointer.offset);
  94. uint64_t pointer = 0;
  95. dest = qfw_find_file(dev, entry->pointer.dest_file);
  96. if (!dest || !dest->addr)
  97. return -ENOENT;
  98. src = qfw_find_file(dev, entry->pointer.src_file);
  99. if (!src || !src->addr)
  100. return -ENOENT;
  101. debug("bios_linker_add_pointer: dest->addr 0x%lx, src->addr 0x%lx, offset 0x%x size %u, 0x%llx\n",
  102. dest->addr, src->addr, offset, entry->pointer.size, pointer);
  103. memcpy(&pointer, (char *)dest->addr + offset, entry->pointer.size);
  104. pointer = le64_to_cpu(pointer);
  105. pointer += (unsigned long)src->addr;
  106. pointer = cpu_to_le64(pointer);
  107. memcpy((char *)dest->addr + offset, &pointer, entry->pointer.size);
  108. return 0;
  109. }
  110. /*
  111. * This function updates checksum fields of ACPI tables previously loaded
  112. * by bios_linker_allocate()
  113. *
  114. * @entry : BIOS linker command entry which tells where to update ACPI table
  115. * checksums
  116. * @return: 0 on success, or negative value on failure
  117. */
  118. static int bios_linker_add_checksum(struct udevice *dev,
  119. struct bios_linker_entry *entry)
  120. {
  121. struct fw_file *file;
  122. uint8_t *data, cksum = 0;
  123. uint8_t *cksum_start;
  124. file = qfw_find_file(dev, entry->cksum.file);
  125. if (!file || !file->addr)
  126. return -ENOENT;
  127. data = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.offset));
  128. cksum_start = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.start));
  129. cksum = table_compute_checksum(cksum_start,
  130. le32_to_cpu(entry->cksum.length));
  131. *data = cksum;
  132. return 0;
  133. }
  134. /* This function loads and patches ACPI tables provided by QEMU */
  135. ulong write_acpi_tables(ulong addr)
  136. {
  137. int i, ret;
  138. struct fw_file *file;
  139. struct bios_linker_entry *table_loader;
  140. struct bios_linker_entry *entry;
  141. uint32_t size;
  142. struct udevice *dev;
  143. ret = qfw_get_dev(&dev);
  144. if (ret) {
  145. printf("error: no qfw\n");
  146. return addr;
  147. }
  148. /* make sure fw_list is loaded */
  149. ret = qfw_read_firmware_list(dev);
  150. if (ret) {
  151. printf("error: can't read firmware file list\n");
  152. return addr;
  153. }
  154. file = qfw_find_file(dev, "etc/table-loader");
  155. if (!file) {
  156. printf("error: can't find etc/table-loader\n");
  157. return addr;
  158. }
  159. size = be32_to_cpu(file->cfg.size);
  160. if ((size % sizeof(*entry)) != 0) {
  161. printf("error: table-loader maybe corrupted\n");
  162. return addr;
  163. }
  164. table_loader = malloc(size);
  165. if (!table_loader) {
  166. printf("error: no memory for table-loader\n");
  167. return addr;
  168. }
  169. /* QFW always puts tables at high addresses */
  170. gd->arch.table_start_high = (ulong)table_loader;
  171. gd->arch.table_end_high = (ulong)table_loader;
  172. qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size, table_loader);
  173. for (i = 0; i < (size / sizeof(*entry)); i++) {
  174. entry = table_loader + i;
  175. switch (le32_to_cpu(entry->command)) {
  176. case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
  177. ret = bios_linker_allocate(dev, entry, &addr);
  178. if (ret)
  179. goto out;
  180. break;
  181. case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
  182. ret = bios_linker_add_pointer(dev, entry);
  183. if (ret)
  184. goto out;
  185. break;
  186. case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
  187. ret = bios_linker_add_checksum(dev, entry);
  188. if (ret)
  189. goto out;
  190. break;
  191. default:
  192. break;
  193. }
  194. }
  195. out:
  196. if (ret) {
  197. struct fw_cfg_file_iter iter;
  198. for (file = qfw_file_iter_init(dev, &iter);
  199. !qfw_file_iter_end(&iter);
  200. file = qfw_file_iter_next(&iter)) {
  201. if (file->addr) {
  202. free((void *)file->addr);
  203. file->addr = 0;
  204. }
  205. }
  206. }
  207. free(table_loader);
  208. gd_set_acpi_start(acpi_get_rsdp_addr());
  209. return addr;
  210. }
  211. ulong acpi_get_rsdp_addr(void)
  212. {
  213. int ret;
  214. struct fw_file *file;
  215. struct udevice *dev;
  216. ret = qfw_get_dev(&dev);
  217. if (ret) {
  218. printf("error: no qfw\n");
  219. return 0;
  220. }
  221. file = qfw_find_file(dev, "etc/acpi/rsdp");
  222. return file->addr;
  223. }
  224. #endif
  225. static void qfw_read_entry_io(struct qfw_dev *qdev, u16 entry, u32 size,
  226. void *address)
  227. {
  228. struct dm_qfw_ops *ops = dm_qfw_get_ops(qdev->dev);
  229. debug("%s: entry 0x%x, size %u address %p\n", __func__, entry, size,
  230. address);
  231. ops->read_entry_io(qdev->dev, entry, size, address);
  232. }
  233. static void qfw_read_entry_dma(struct qfw_dev *qdev, u16 entry, u32 size,
  234. void *address)
  235. {
  236. struct dm_qfw_ops *ops = dm_qfw_get_ops(qdev->dev);
  237. struct qfw_dma dma = {
  238. .length = cpu_to_be32(size),
  239. .address = cpu_to_be64((uintptr_t)address),
  240. .control = cpu_to_be32(FW_CFG_DMA_READ),
  241. };
  242. /*
  243. * writing FW_CFG_INVALID will cause read operation to resume at last
  244. * offset, otherwise read will start at offset 0
  245. */
  246. if (entry != FW_CFG_INVALID)
  247. dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16));
  248. debug("%s: entry 0x%x, size %u address %p, control 0x%x\n", __func__,
  249. entry, size, address, be32_to_cpu(dma.control));
  250. barrier();
  251. ops->read_entry_dma(qdev->dev, &dma);
  252. }
  253. void qfw_read_entry(struct udevice *dev, u16 entry, u32 size, void *address)
  254. {
  255. struct qfw_dev *qdev = dev_get_uclass_priv(dev);
  256. if (qdev->dma_present)
  257. qfw_read_entry_dma(qdev, entry, size, address);
  258. else
  259. qfw_read_entry_io(qdev, entry, size, address);
  260. }
  261. int qfw_register(struct udevice *dev)
  262. {
  263. struct qfw_dev *qdev = dev_get_uclass_priv(dev);
  264. u32 qemu, dma_enabled;
  265. qdev->dev = dev;
  266. INIT_LIST_HEAD(&qdev->fw_list);
  267. qfw_read_entry_io(qdev, FW_CFG_SIGNATURE, 4, &qemu);
  268. if (be32_to_cpu(qemu) != QEMU_FW_CFG_SIGNATURE)
  269. return -ENODEV;
  270. qfw_read_entry_io(qdev, FW_CFG_ID, 1, &dma_enabled);
  271. if (dma_enabled & FW_CFG_DMA_ENABLED)
  272. qdev->dma_present = true;
  273. return 0;
  274. }
  275. static int qfw_post_bind(struct udevice *dev)
  276. {
  277. int ret;
  278. ret = bootdev_setup_for_dev(dev, "qfw_bootdev");
  279. if (ret)
  280. return log_msg_ret("dev", ret);
  281. return 0;
  282. }
  283. static int qfw_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
  284. struct bootflow *bflow)
  285. {
  286. const struct udevice *media = dev_get_parent(dev);
  287. int ret;
  288. if (!CONFIG_IS_ENABLED(BOOTSTD))
  289. return -ENOSYS;
  290. log_debug("media=%s\n", media->name);
  291. ret = bootmeth_check(bflow->method, iter);
  292. if (ret)
  293. return log_msg_ret("check", ret);
  294. log_debug("iter->part=%d\n", iter->part);
  295. /* We only support the whole device, not partitions */
  296. if (iter->part)
  297. return log_msg_ret("max", -ESHUTDOWN);
  298. log_debug("reading bootflow with method: %s\n", bflow->method->name);
  299. ret = bootmeth_read_bootflow(bflow->method, bflow);
  300. if (ret)
  301. return log_msg_ret("method", ret);
  302. return 0;
  303. }
  304. static int qfw_bootdev_bind(struct udevice *dev)
  305. {
  306. struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
  307. ucp->prio = BOOTDEVP_4_SCAN_FAST;
  308. return 0;
  309. }
  310. static int qfw_bootdev_hunt(struct bootdev_hunter *info, bool show)
  311. {
  312. int ret;
  313. ret = uclass_probe_all(UCLASS_QFW);
  314. if (ret && ret != -ENOENT)
  315. return log_msg_ret("vir", ret);
  316. return 0;
  317. }
  318. UCLASS_DRIVER(qfw) = {
  319. .id = UCLASS_QFW,
  320. .name = "qfw",
  321. .post_bind = qfw_post_bind,
  322. .per_device_auto = sizeof(struct qfw_dev),
  323. };
  324. struct bootdev_ops qfw_bootdev_ops = {
  325. .get_bootflow = qfw_get_bootflow,
  326. };
  327. static const struct udevice_id qfw_bootdev_ids[] = {
  328. { .compatible = "u-boot,bootdev-qfw" },
  329. { }
  330. };
  331. U_BOOT_DRIVER(qfw_bootdev) = {
  332. .name = "qfw_bootdev",
  333. .id = UCLASS_BOOTDEV,
  334. .ops = &qfw_bootdev_ops,
  335. .bind = qfw_bootdev_bind,
  336. .of_match = qfw_bootdev_ids,
  337. };
  338. BOOTDEV_HUNTER(qfw_bootdev_hunter) = {
  339. .prio = BOOTDEVP_4_SCAN_FAST,
  340. .uclass = UCLASS_QFW,
  341. .hunt = qfw_bootdev_hunt,
  342. .drv = DM_DRIVER_REF(qfw_bootdev),
  343. };