acpi_table.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Based on acpi.c from coreboot
  4. *
  5. * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
  6. * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
  7. */
  8. #include <common.h>
  9. #include <cpu.h>
  10. #include <dm.h>
  11. #include <log.h>
  12. #include <dm/uclass-internal.h>
  13. #include <mapmem.h>
  14. #include <serial.h>
  15. #include <version.h>
  16. #include <acpi/acpigen.h>
  17. #include <acpi/acpi_table.h>
  18. #include <asm/acpi/global_nvs.h>
  19. #include <asm/ioapic.h>
  20. #include <asm/lapic.h>
  21. #include <asm/mpspec.h>
  22. #include <asm/tables.h>
  23. #include <asm/arch/global_nvs.h>
  24. #include <dm/acpi.h>
  25. #include <linux/err.h>
  26. /*
  27. * IASL compiles the dsdt entries and writes the hex values
  28. * to a C array AmlCode[] (see dsdt.c).
  29. */
  30. extern const unsigned char AmlCode[];
  31. /* ACPI RSDP address to be used in boot parameters */
  32. static ulong acpi_rsdp_addr;
  33. static void acpi_create_facs(struct acpi_facs *facs)
  34. {
  35. memset((void *)facs, 0, sizeof(struct acpi_facs));
  36. memcpy(facs->signature, "FACS", 4);
  37. facs->length = sizeof(struct acpi_facs);
  38. facs->hardware_signature = 0;
  39. facs->firmware_waking_vector = 0;
  40. facs->global_lock = 0;
  41. facs->flags = 0;
  42. facs->x_firmware_waking_vector_l = 0;
  43. facs->x_firmware_waking_vector_h = 0;
  44. facs->version = 1;
  45. }
  46. static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
  47. u8 cpu, u8 apic)
  48. {
  49. lapic->type = ACPI_APIC_LAPIC;
  50. lapic->length = sizeof(struct acpi_madt_lapic);
  51. lapic->flags = LOCAL_APIC_FLAG_ENABLED;
  52. lapic->processor_id = cpu;
  53. lapic->apic_id = apic;
  54. return lapic->length;
  55. }
  56. int acpi_create_madt_lapics(u32 current)
  57. {
  58. struct udevice *dev;
  59. int total_length = 0;
  60. for (uclass_find_first_device(UCLASS_CPU, &dev);
  61. dev;
  62. uclass_find_next_device(&dev)) {
  63. struct cpu_platdata *plat = dev_get_parent_platdata(dev);
  64. int length = acpi_create_madt_lapic(
  65. (struct acpi_madt_lapic *)current,
  66. plat->cpu_id, plat->cpu_id);
  67. current += length;
  68. total_length += length;
  69. }
  70. return total_length;
  71. }
  72. int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
  73. u32 addr, u32 gsi_base)
  74. {
  75. ioapic->type = ACPI_APIC_IOAPIC;
  76. ioapic->length = sizeof(struct acpi_madt_ioapic);
  77. ioapic->reserved = 0x00;
  78. ioapic->gsi_base = gsi_base;
  79. ioapic->ioapic_id = id;
  80. ioapic->ioapic_addr = addr;
  81. return ioapic->length;
  82. }
  83. int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
  84. u8 bus, u8 source, u32 gsirq, u16 flags)
  85. {
  86. irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
  87. irqoverride->length = sizeof(struct acpi_madt_irqoverride);
  88. irqoverride->bus = bus;
  89. irqoverride->source = source;
  90. irqoverride->gsirq = gsirq;
  91. irqoverride->flags = flags;
  92. return irqoverride->length;
  93. }
  94. int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
  95. u8 cpu, u16 flags, u8 lint)
  96. {
  97. lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
  98. lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
  99. lapic_nmi->flags = flags;
  100. lapic_nmi->processor_id = cpu;
  101. lapic_nmi->lint = lint;
  102. return lapic_nmi->length;
  103. }
  104. static int acpi_create_madt_irq_overrides(u32 current)
  105. {
  106. struct acpi_madt_irqoverride *irqovr;
  107. u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
  108. int length = 0;
  109. irqovr = (void *)current;
  110. length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
  111. irqovr = (void *)(current + length);
  112. length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
  113. return length;
  114. }
  115. __weak u32 acpi_fill_madt(u32 current)
  116. {
  117. current += acpi_create_madt_lapics(current);
  118. current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
  119. io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
  120. current += acpi_create_madt_irq_overrides(current);
  121. return current;
  122. }
  123. static void acpi_create_madt(struct acpi_madt *madt)
  124. {
  125. struct acpi_table_header *header = &(madt->header);
  126. u32 current = (u32)madt + sizeof(struct acpi_madt);
  127. memset((void *)madt, 0, sizeof(struct acpi_madt));
  128. /* Fill out header fields */
  129. acpi_fill_header(header, "APIC");
  130. header->length = sizeof(struct acpi_madt);
  131. header->revision = ACPI_MADT_REV_ACPI_3_0;
  132. madt->lapic_addr = LAPIC_DEFAULT_BASE;
  133. madt->flags = ACPI_MADT_PCAT_COMPAT;
  134. current = acpi_fill_madt(current);
  135. /* (Re)calculate length and checksum */
  136. header->length = current - (u32)madt;
  137. header->checksum = table_compute_checksum((void *)madt, header->length);
  138. }
  139. int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
  140. u16 seg_nr, u8 start, u8 end)
  141. {
  142. memset(mmconfig, 0, sizeof(*mmconfig));
  143. mmconfig->base_address_l = base;
  144. mmconfig->base_address_h = 0;
  145. mmconfig->pci_segment_group_number = seg_nr;
  146. mmconfig->start_bus_number = start;
  147. mmconfig->end_bus_number = end;
  148. return sizeof(struct acpi_mcfg_mmconfig);
  149. }
  150. __weak u32 acpi_fill_mcfg(u32 current)
  151. {
  152. current += acpi_create_mcfg_mmconfig
  153. ((struct acpi_mcfg_mmconfig *)current,
  154. CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
  155. return current;
  156. }
  157. /* MCFG is defined in the PCI Firmware Specification 3.0 */
  158. static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
  159. {
  160. struct acpi_table_header *header = &(mcfg->header);
  161. u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
  162. memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
  163. /* Fill out header fields */
  164. acpi_fill_header(header, "MCFG");
  165. header->length = sizeof(struct acpi_mcfg);
  166. header->revision = 1;
  167. current = acpi_fill_mcfg(current);
  168. /* (Re)calculate length and checksum */
  169. header->length = current - (u32)mcfg;
  170. header->checksum = table_compute_checksum((void *)mcfg, header->length);
  171. }
  172. __weak u32 acpi_fill_csrt(u32 current)
  173. {
  174. return 0;
  175. }
  176. static int acpi_create_csrt(struct acpi_csrt *csrt)
  177. {
  178. struct acpi_table_header *header = &(csrt->header);
  179. u32 current = (u32)csrt + sizeof(struct acpi_csrt);
  180. uint ptr;
  181. memset((void *)csrt, 0, sizeof(struct acpi_csrt));
  182. /* Fill out header fields */
  183. acpi_fill_header(header, "CSRT");
  184. header->length = sizeof(struct acpi_csrt);
  185. header->revision = 0;
  186. ptr = acpi_fill_csrt(current);
  187. if (!ptr)
  188. return -ENOENT;
  189. current = ptr;
  190. /* (Re)calculate length and checksum */
  191. header->length = current - (u32)csrt;
  192. header->checksum = table_compute_checksum((void *)csrt, header->length);
  193. return 0;
  194. }
  195. static void acpi_create_spcr(struct acpi_spcr *spcr)
  196. {
  197. struct acpi_table_header *header = &(spcr->header);
  198. struct serial_device_info serial_info = {0};
  199. ulong serial_address, serial_offset;
  200. struct udevice *dev;
  201. uint serial_config;
  202. uint serial_width;
  203. int access_size;
  204. int space_id;
  205. int ret = -ENODEV;
  206. memset((void *)spcr, 0, sizeof(struct acpi_spcr));
  207. /* Fill out header fields */
  208. acpi_fill_header(header, "SPCR");
  209. header->length = sizeof(struct acpi_spcr);
  210. header->revision = 2;
  211. /* Read the device once, here. It is reused below */
  212. dev = gd->cur_serial_dev;
  213. if (dev)
  214. ret = serial_getinfo(dev, &serial_info);
  215. if (ret)
  216. serial_info.type = SERIAL_CHIP_UNKNOWN;
  217. /* Encode chip type */
  218. switch (serial_info.type) {
  219. case SERIAL_CHIP_16550_COMPATIBLE:
  220. spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE;
  221. break;
  222. case SERIAL_CHIP_UNKNOWN:
  223. default:
  224. spcr->interface_type = ACPI_DBG2_UNKNOWN;
  225. break;
  226. }
  227. /* Encode address space */
  228. switch (serial_info.addr_space) {
  229. case SERIAL_ADDRESS_SPACE_MEMORY:
  230. space_id = ACPI_ADDRESS_SPACE_MEMORY;
  231. break;
  232. case SERIAL_ADDRESS_SPACE_IO:
  233. default:
  234. space_id = ACPI_ADDRESS_SPACE_IO;
  235. break;
  236. }
  237. serial_width = serial_info.reg_width * 8;
  238. serial_offset = serial_info.reg_offset << serial_info.reg_shift;
  239. serial_address = serial_info.addr + serial_offset;
  240. /* Encode register access size */
  241. switch (serial_info.reg_shift) {
  242. case 0:
  243. access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
  244. break;
  245. case 1:
  246. access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
  247. break;
  248. case 2:
  249. access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
  250. break;
  251. case 3:
  252. access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
  253. break;
  254. default:
  255. access_size = ACPI_ACCESS_SIZE_UNDEFINED;
  256. break;
  257. }
  258. debug("UART type %u @ %lx\n", spcr->interface_type, serial_address);
  259. /* Fill GAS */
  260. spcr->serial_port.space_id = space_id;
  261. spcr->serial_port.bit_width = serial_width;
  262. spcr->serial_port.bit_offset = 0;
  263. spcr->serial_port.access_size = access_size;
  264. spcr->serial_port.addrl = lower_32_bits(serial_address);
  265. spcr->serial_port.addrh = upper_32_bits(serial_address);
  266. /* Encode baud rate */
  267. switch (serial_info.baudrate) {
  268. case 9600:
  269. spcr->baud_rate = 3;
  270. break;
  271. case 19200:
  272. spcr->baud_rate = 4;
  273. break;
  274. case 57600:
  275. spcr->baud_rate = 6;
  276. break;
  277. case 115200:
  278. spcr->baud_rate = 7;
  279. break;
  280. default:
  281. spcr->baud_rate = 0;
  282. break;
  283. }
  284. serial_config = SERIAL_DEFAULT_CONFIG;
  285. if (dev)
  286. ret = serial_getconfig(dev, &serial_config);
  287. spcr->parity = SERIAL_GET_PARITY(serial_config);
  288. spcr->stop_bits = SERIAL_GET_STOP(serial_config);
  289. /* No PCI devices for now */
  290. spcr->pci_device_id = 0xffff;
  291. spcr->pci_vendor_id = 0xffff;
  292. /*
  293. * SPCR has no clue if the UART base clock speed is different
  294. * to the default one. However, the SPCR 1.04 defines baud rate
  295. * 0 as a preconfigured state of UART and OS is supposed not
  296. * to touch the configuration of the serial device.
  297. */
  298. if (serial_info.clock != SERIAL_DEFAULT_CLOCK)
  299. spcr->baud_rate = 0;
  300. /* Fix checksum */
  301. header->checksum = table_compute_checksum((void *)spcr, header->length);
  302. }
  303. void acpi_create_ssdt(struct acpi_ctx *ctx, struct acpi_table_header *ssdt,
  304. const char *oem_table_id)
  305. {
  306. memset((void *)ssdt, '\0', sizeof(struct acpi_table_header));
  307. acpi_fill_header(ssdt, "SSDT");
  308. ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT);
  309. ssdt->aslc_revision = 1;
  310. ssdt->length = sizeof(struct acpi_table_header);
  311. acpi_inc(ctx, sizeof(struct acpi_table_header));
  312. acpi_fill_ssdt(ctx);
  313. /* (Re)calculate length and checksum. */
  314. ssdt->length = ctx->current - (void *)ssdt;
  315. ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
  316. }
  317. /*
  318. * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
  319. */
  320. ulong write_acpi_tables(ulong start_addr)
  321. {
  322. struct acpi_ctx sctx, *ctx = &sctx;
  323. struct acpi_facs *facs;
  324. struct acpi_table_header *dsdt;
  325. struct acpi_fadt *fadt;
  326. struct acpi_table_header *ssdt;
  327. struct acpi_mcfg *mcfg;
  328. struct acpi_madt *madt;
  329. struct acpi_csrt *csrt;
  330. struct acpi_spcr *spcr;
  331. void *start;
  332. ulong addr;
  333. int i;
  334. start = map_sysmem(start_addr, 0);
  335. debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
  336. acpi_setup_base_tables(ctx, start);
  337. debug("ACPI: * FACS\n");
  338. facs = ctx->current;
  339. acpi_inc_align(ctx, sizeof(struct acpi_facs));
  340. acpi_create_facs(facs);
  341. debug("ACPI: * DSDT\n");
  342. dsdt = ctx->current;
  343. /* Put the table header first */
  344. memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
  345. acpi_inc(ctx, sizeof(struct acpi_table_header));
  346. /* If the table is not empty, allow devices to inject things */
  347. if (dsdt->length >= sizeof(struct acpi_table_header))
  348. acpi_inject_dsdt(ctx);
  349. /* Copy in the AML code itself if any (after the header) */
  350. memcpy(ctx->current,
  351. (char *)&AmlCode + sizeof(struct acpi_table_header),
  352. dsdt->length - sizeof(struct acpi_table_header));
  353. acpi_inc(ctx, dsdt->length - sizeof(struct acpi_table_header));
  354. /* Pack GNVS into the ACPI table area */
  355. for (i = 0; i < dsdt->length; i++) {
  356. u32 *gnvs = (u32 *)((u32)dsdt + i);
  357. if (*gnvs == ACPI_GNVS_ADDR) {
  358. ulong addr = (ulong)map_to_sysmem(ctx->current);
  359. debug("Fix up global NVS in DSDT to %#08lx\n", addr);
  360. *gnvs = addr;
  361. break;
  362. }
  363. }
  364. /*
  365. * Recalculate the length and update the DSDT checksum since we patched
  366. * the GNVS address. Set the checksum to zero since it is part of the
  367. * region being checksummed.
  368. */
  369. dsdt->length = ctx->current - (void *)dsdt;
  370. dsdt->checksum = 0;
  371. dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
  372. acpi_align(ctx);
  373. /*
  374. * Fill in platform-specific global NVS variables. If this fails we
  375. * cannot return the error but this should only happen while debugging.
  376. */
  377. addr = acpi_create_gnvs(ctx->current);
  378. if (IS_ERR_VALUE(addr))
  379. printf("Error: Failed to create GNVS\n");
  380. acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
  381. debug("ACPI: * FADT\n");
  382. fadt = ctx->current;
  383. acpi_inc_align(ctx, sizeof(struct acpi_fadt));
  384. acpi_create_fadt(fadt, facs, dsdt);
  385. acpi_add_table(ctx, fadt);
  386. debug("ACPI: * SSDT\n");
  387. ssdt = (struct acpi_table_header *)ctx->current;
  388. acpi_create_ssdt(ctx, ssdt, OEM_TABLE_ID);
  389. if (ssdt->length > sizeof(struct acpi_table_header)) {
  390. acpi_inc_align(ctx, ssdt->length);
  391. acpi_add_table(ctx, ssdt);
  392. }
  393. debug("ACPI: * MCFG\n");
  394. mcfg = ctx->current;
  395. acpi_create_mcfg(mcfg);
  396. acpi_inc_align(ctx, mcfg->header.length);
  397. acpi_add_table(ctx, mcfg);
  398. debug("ACPI: * MADT\n");
  399. madt = ctx->current;
  400. acpi_create_madt(madt);
  401. acpi_inc_align(ctx, madt->header.length);
  402. acpi_add_table(ctx, madt);
  403. debug("ACPI: * CSRT\n");
  404. csrt = ctx->current;
  405. if (!acpi_create_csrt(csrt)) {
  406. acpi_inc_align(ctx, csrt->header.length);
  407. acpi_add_table(ctx, csrt);
  408. }
  409. debug("ACPI: * SPCR\n");
  410. spcr = ctx->current;
  411. acpi_create_spcr(spcr);
  412. acpi_inc_align(ctx, spcr->header.length);
  413. acpi_add_table(ctx, spcr);
  414. acpi_write_dev_tables(ctx);
  415. addr = map_to_sysmem(ctx->current);
  416. debug("current = %lx\n", addr);
  417. acpi_rsdp_addr = (unsigned long)ctx->rsdp;
  418. debug("ACPI: done\n");
  419. return addr;
  420. }
  421. ulong acpi_get_rsdp_addr(void)
  422. {
  423. return acpi_rsdp_addr;
  424. }