1 // SPDX-License-Identifier: GPL-2.0+
3 * Based on acpi.c from coreboot
5 * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
6 * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
13 #include <dm/uclass-internal.h>
17 #include <acpi/acpigen.h>
18 #include <acpi/acpi_device.h>
19 #include <acpi/acpi_table.h>
20 #include <asm/acpi/global_nvs.h>
21 #include <asm/ioapic.h>
22 #include <asm/lapic.h>
23 #include <asm/mpspec.h>
24 #include <asm/tables.h>
25 #include <asm/arch/global_nvs.h>
27 #include <linux/err.h>
30 * IASL compiles the dsdt entries and writes the hex values
31 * to a C array AmlCode[] (see dsdt.c).
33 extern const unsigned char AmlCode[];
35 /* ACPI RSDP address to be used in boot parameters */
36 static ulong acpi_rsdp_addr;
38 static void acpi_create_facs(struct acpi_facs *facs)
40 memset((void *)facs, 0, sizeof(struct acpi_facs));
42 memcpy(facs->signature, "FACS", 4);
43 facs->length = sizeof(struct acpi_facs);
44 facs->hardware_signature = 0;
45 facs->firmware_waking_vector = 0;
46 facs->global_lock = 0;
48 facs->x_firmware_waking_vector_l = 0;
49 facs->x_firmware_waking_vector_h = 0;
53 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
56 lapic->type = ACPI_APIC_LAPIC;
57 lapic->length = sizeof(struct acpi_madt_lapic);
58 lapic->flags = LOCAL_APIC_FLAG_ENABLED;
59 lapic->processor_id = cpu;
60 lapic->apic_id = apic;
65 int acpi_create_madt_lapics(u32 current)
70 for (uclass_find_first_device(UCLASS_CPU, &dev);
72 uclass_find_next_device(&dev)) {
73 struct cpu_platdata *plat = dev_get_parent_platdata(dev);
74 int length = acpi_create_madt_lapic(
75 (struct acpi_madt_lapic *)current,
76 plat->cpu_id, plat->cpu_id);
78 total_length += length;
84 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
85 u32 addr, u32 gsi_base)
87 ioapic->type = ACPI_APIC_IOAPIC;
88 ioapic->length = sizeof(struct acpi_madt_ioapic);
89 ioapic->reserved = 0x00;
90 ioapic->gsi_base = gsi_base;
91 ioapic->ioapic_id = id;
92 ioapic->ioapic_addr = addr;
94 return ioapic->length;
97 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
98 u8 bus, u8 source, u32 gsirq, u16 flags)
100 irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
101 irqoverride->length = sizeof(struct acpi_madt_irqoverride);
102 irqoverride->bus = bus;
103 irqoverride->source = source;
104 irqoverride->gsirq = gsirq;
105 irqoverride->flags = flags;
107 return irqoverride->length;
110 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
111 u8 cpu, u16 flags, u8 lint)
113 lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
114 lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
115 lapic_nmi->flags = flags;
116 lapic_nmi->processor_id = cpu;
117 lapic_nmi->lint = lint;
119 return lapic_nmi->length;
122 static int acpi_create_madt_irq_overrides(u32 current)
124 struct acpi_madt_irqoverride *irqovr;
125 u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
128 irqovr = (void *)current;
129 length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
131 irqovr = (void *)(current + length);
132 length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
137 __weak u32 acpi_fill_madt(u32 current)
139 current += acpi_create_madt_lapics(current);
141 current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
142 io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
144 current += acpi_create_madt_irq_overrides(current);
149 static void acpi_create_madt(struct acpi_madt *madt)
151 struct acpi_table_header *header = &(madt->header);
152 u32 current = (u32)madt + sizeof(struct acpi_madt);
154 memset((void *)madt, 0, sizeof(struct acpi_madt));
156 /* Fill out header fields */
157 acpi_fill_header(header, "APIC");
158 header->length = sizeof(struct acpi_madt);
159 header->revision = ACPI_MADT_REV_ACPI_3_0;
161 madt->lapic_addr = LAPIC_DEFAULT_BASE;
162 madt->flags = ACPI_MADT_PCAT_COMPAT;
164 current = acpi_fill_madt(current);
166 /* (Re)calculate length and checksum */
167 header->length = current - (u32)madt;
169 header->checksum = table_compute_checksum((void *)madt, header->length);
172 int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
173 u16 seg_nr, u8 start, u8 end)
175 memset(mmconfig, 0, sizeof(*mmconfig));
176 mmconfig->base_address_l = base;
177 mmconfig->base_address_h = 0;
178 mmconfig->pci_segment_group_number = seg_nr;
179 mmconfig->start_bus_number = start;
180 mmconfig->end_bus_number = end;
182 return sizeof(struct acpi_mcfg_mmconfig);
185 __weak u32 acpi_fill_mcfg(u32 current)
187 current += acpi_create_mcfg_mmconfig
188 ((struct acpi_mcfg_mmconfig *)current,
189 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
194 /* MCFG is defined in the PCI Firmware Specification 3.0 */
195 static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
197 struct acpi_table_header *header = &(mcfg->header);
198 u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
200 memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
202 /* Fill out header fields */
203 acpi_fill_header(header, "MCFG");
204 header->length = sizeof(struct acpi_mcfg);
205 header->revision = 1;
207 current = acpi_fill_mcfg(current);
209 /* (Re)calculate length and checksum */
210 header->length = current - (u32)mcfg;
211 header->checksum = table_compute_checksum((void *)mcfg, header->length);
214 __weak u32 acpi_fill_csrt(u32 current)
219 static int acpi_create_csrt(struct acpi_csrt *csrt)
221 struct acpi_table_header *header = &(csrt->header);
222 u32 current = (u32)csrt + sizeof(struct acpi_csrt);
225 memset((void *)csrt, 0, sizeof(struct acpi_csrt));
227 /* Fill out header fields */
228 acpi_fill_header(header, "CSRT");
229 header->length = sizeof(struct acpi_csrt);
230 header->revision = 0;
232 ptr = acpi_fill_csrt(current);
237 /* (Re)calculate length and checksum */
238 header->length = current - (u32)csrt;
239 header->checksum = table_compute_checksum((void *)csrt, header->length);
244 static void acpi_create_spcr(struct acpi_spcr *spcr)
246 struct acpi_table_header *header = &(spcr->header);
247 struct serial_device_info serial_info = {0};
248 ulong serial_address, serial_offset;
256 memset((void *)spcr, 0, sizeof(struct acpi_spcr));
258 /* Fill out header fields */
259 acpi_fill_header(header, "SPCR");
260 header->length = sizeof(struct acpi_spcr);
261 header->revision = 2;
263 /* Read the device once, here. It is reused below */
264 dev = gd->cur_serial_dev;
266 ret = serial_getinfo(dev, &serial_info);
268 serial_info.type = SERIAL_CHIP_UNKNOWN;
270 /* Encode chip type */
271 switch (serial_info.type) {
272 case SERIAL_CHIP_16550_COMPATIBLE:
273 spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE;
275 case SERIAL_CHIP_UNKNOWN:
277 spcr->interface_type = ACPI_DBG2_UNKNOWN;
281 /* Encode address space */
282 switch (serial_info.addr_space) {
283 case SERIAL_ADDRESS_SPACE_MEMORY:
284 space_id = ACPI_ADDRESS_SPACE_MEMORY;
286 case SERIAL_ADDRESS_SPACE_IO:
288 space_id = ACPI_ADDRESS_SPACE_IO;
292 serial_width = serial_info.reg_width * 8;
293 serial_offset = serial_info.reg_offset << serial_info.reg_shift;
294 serial_address = serial_info.addr + serial_offset;
296 /* Encode register access size */
297 switch (serial_info.reg_shift) {
299 access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
302 access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
305 access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
308 access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
311 access_size = ACPI_ACCESS_SIZE_UNDEFINED;
315 debug("UART type %u @ %lx\n", spcr->interface_type, serial_address);
318 spcr->serial_port.space_id = space_id;
319 spcr->serial_port.bit_width = serial_width;
320 spcr->serial_port.bit_offset = 0;
321 spcr->serial_port.access_size = access_size;
322 spcr->serial_port.addrl = lower_32_bits(serial_address);
323 spcr->serial_port.addrh = upper_32_bits(serial_address);
325 /* Encode baud rate */
326 switch (serial_info.baudrate) {
344 serial_config = SERIAL_DEFAULT_CONFIG;
346 ret = serial_getconfig(dev, &serial_config);
348 spcr->parity = SERIAL_GET_PARITY(serial_config);
349 spcr->stop_bits = SERIAL_GET_STOP(serial_config);
351 /* No PCI devices for now */
352 spcr->pci_device_id = 0xffff;
353 spcr->pci_vendor_id = 0xffff;
356 * SPCR has no clue if the UART base clock speed is different
357 * to the default one. However, the SPCR 1.04 defines baud rate
358 * 0 as a preconfigured state of UART and OS is supposed not
359 * to touch the configuration of the serial device.
361 if (serial_info.clock != SERIAL_DEFAULT_CLOCK)
365 header->checksum = table_compute_checksum((void *)spcr, header->length);
368 void acpi_create_ssdt(struct acpi_ctx *ctx, struct acpi_table_header *ssdt,
369 const char *oem_table_id)
371 memset((void *)ssdt, '\0', sizeof(struct acpi_table_header));
373 acpi_fill_header(ssdt, "SSDT");
374 ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT);
375 ssdt->aslc_revision = 1;
376 ssdt->length = sizeof(struct acpi_table_header);
378 acpi_inc(ctx, sizeof(struct acpi_table_header));
382 /* (Re)calculate length and checksum. */
383 ssdt->length = ctx->current - (void *)ssdt;
384 ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
388 * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
390 ulong write_acpi_tables(ulong start_addr)
392 struct acpi_ctx sctx, *ctx = &sctx;
393 struct acpi_facs *facs;
394 struct acpi_table_header *dsdt;
395 struct acpi_fadt *fadt;
396 struct acpi_table_header *ssdt;
397 struct acpi_mcfg *mcfg;
398 struct acpi_madt *madt;
399 struct acpi_csrt *csrt;
400 struct acpi_spcr *spcr;
405 start = map_sysmem(start_addr, 0);
407 debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
409 acpi_setup_base_tables(ctx, start);
411 debug("ACPI: * FACS\n");
413 acpi_inc_align(ctx, sizeof(struct acpi_facs));
415 acpi_create_facs(facs);
417 debug("ACPI: * DSDT\n");
420 /* Put the table header first */
421 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
422 acpi_inc(ctx, sizeof(struct acpi_table_header));
424 /* If the table is not empty, allow devices to inject things */
425 if (dsdt->length >= sizeof(struct acpi_table_header))
426 acpi_inject_dsdt(ctx);
428 /* Copy in the AML code itself if any (after the header) */
430 (char *)&AmlCode + sizeof(struct acpi_table_header),
431 dsdt->length - sizeof(struct acpi_table_header));
433 acpi_inc(ctx, dsdt->length - sizeof(struct acpi_table_header));
434 dsdt->length = ctx->current - (void *)dsdt;
437 if (!IS_ENABLED(CONFIG_ACPI_GNVS_EXTERNAL)) {
438 /* Pack GNVS into the ACPI table area */
439 for (i = 0; i < dsdt->length; i++) {
440 u32 *gnvs = (u32 *)((u32)dsdt + i);
442 if (*gnvs == ACPI_GNVS_ADDR) {
443 *gnvs = map_to_sysmem(ctx->current);
444 debug("Fix up global NVS in DSDT to %#08x\n",
451 * Fill in platform-specific global NVS variables. If this fails
452 * we cannot return the error but this should only happen while
455 addr = acpi_create_gnvs(ctx->current);
456 if (IS_ERR_VALUE(addr))
457 printf("Error: Gailed to create GNVS\n");
458 acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
462 * Recalculate the length and update the DSDT checksum since we patched
463 * the GNVS address. Set the checksum to zero since it is part of the
464 * region being checksummed.
467 dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
470 * Fill in platform-specific global NVS variables. If this fails we
471 * cannot return the error but this should only happen while debugging.
473 addr = acpi_create_gnvs(ctx->current);
474 if (IS_ERR_VALUE(addr))
475 printf("Error: Failed to create GNVS\n");
477 acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
479 debug("ACPI: * FADT\n");
481 acpi_inc_align(ctx, sizeof(struct acpi_fadt));
482 acpi_create_fadt(fadt, facs, dsdt);
483 acpi_add_table(ctx, fadt);
485 debug("ACPI: * SSDT\n");
486 ssdt = (struct acpi_table_header *)ctx->current;
487 acpi_create_ssdt(ctx, ssdt, OEM_TABLE_ID);
488 if (ssdt->length > sizeof(struct acpi_table_header)) {
489 acpi_inc_align(ctx, ssdt->length);
490 acpi_add_table(ctx, ssdt);
493 debug("ACPI: * MCFG\n");
495 acpi_create_mcfg(mcfg);
496 acpi_inc_align(ctx, mcfg->header.length);
497 acpi_add_table(ctx, mcfg);
499 debug("ACPI: * MADT\n");
501 acpi_create_madt(madt);
502 acpi_inc_align(ctx, madt->header.length);
503 acpi_add_table(ctx, madt);
505 debug("ACPI: * CSRT\n");
507 if (!acpi_create_csrt(csrt)) {
508 acpi_inc_align(ctx, csrt->header.length);
509 acpi_add_table(ctx, csrt);
512 debug("ACPI: * SPCR\n");
514 acpi_create_spcr(spcr);
515 acpi_inc_align(ctx, spcr->header.length);
516 acpi_add_table(ctx, spcr);
518 acpi_write_dev_tables(ctx);
520 addr = map_to_sysmem(ctx->current);
521 debug("current = %lx\n", addr);
523 acpi_rsdp_addr = (unsigned long)ctx->rsdp;
524 debug("ACPI: done\n");
529 ulong acpi_get_rsdp_addr(void)
531 return acpi_rsdp_addr;
535 * acpi_write_hpet() - Write out a HPET table
537 * Write out the table for High-Precision Event Timers
539 * @hpet: Place to put HPET table
541 static int acpi_create_hpet(struct acpi_hpet *hpet)
543 struct acpi_table_header *header = &hpet->header;
544 struct acpi_gen_regaddr *addr = &hpet->addr;
547 * See IA-PC HPET (High Precision Event Timers) Specification v1.0a
548 * https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf
550 memset((void *)hpet, '\0', sizeof(struct acpi_hpet));
552 /* Fill out header fields. */
553 acpi_fill_header(header, "HPET");
555 header->aslc_revision = ASL_REVISION;
556 header->length = sizeof(struct acpi_hpet);
557 header->revision = acpi_get_table_revision(ACPITAB_HPET);
559 /* Fill out HPET address */
560 addr->space_id = 0; /* Memory */
561 addr->bit_width = 64;
562 addr->bit_offset = 0;
563 addr->addrl = CONFIG_HPET_ADDRESS & 0xffffffff;
564 addr->addrh = ((unsigned long long)CONFIG_HPET_ADDRESS) >> 32;
566 hpet->id = *(u32 *)CONFIG_HPET_ADDRESS;
568 hpet->min_tick = 0; /* HPET_MIN_TICKS */
570 header->checksum = table_compute_checksum(hpet,
571 sizeof(struct acpi_hpet));
576 int acpi_write_hpet(struct acpi_ctx *ctx)
578 struct acpi_hpet *hpet;
581 log_debug("ACPI: * HPET\n");
584 acpi_inc_align(ctx, sizeof(struct acpi_hpet));
585 acpi_create_hpet(hpet);
586 ret = acpi_add_table(ctx, hpet);
588 return log_msg_ret("add", ret);
593 int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev,
596 struct acpi_dbg2_header *dbg2 = ctx->current;
597 char path[ACPI_PATH_MAX];
598 struct acpi_gen_regaddr address;
602 if (!device_active(dev)) {
603 log_info("Device not enabled\n");
607 * PCI devices don't remember their resource allocation information in
608 * U-Boot at present. We assume that MMIO is used for the UART and that
609 * the address space is 32 bytes: ns16550 uses 8 registers of up to
610 * 32-bits each. This is only for debugging so it is not a big deal.
612 addr = dm_pci_read_bar32(dev, 0);
613 printf("UART addr %lx\n", (ulong)addr);
615 memset(&address, '\0', sizeof(address));
616 address.space_id = ACPI_ADDRESS_SPACE_MEMORY;
617 address.addrl = (uint32_t)addr;
618 address.addrh = (uint32_t)((addr >> 32) & 0xffffffff);
619 address.access_size = access_size;
621 ret = acpi_device_path(dev, path, sizeof(path));
623 return log_msg_ret("path", ret);
624 acpi_create_dbg2(dbg2, ACPI_DBG2_SERIAL_PORT,
625 ACPI_DBG2_16550_COMPATIBLE, &address, 0x1000, path);
627 acpi_inc_align(ctx, dbg2->header.length);
628 acpi_add_table(ctx, dbg2);