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>
12 #include <dm/uclass-internal.h>
16 #include <acpi/acpi_table.h>
17 #include <asm/acpi/global_nvs.h>
18 #include <asm/ioapic.h>
19 #include <asm/lapic.h>
20 #include <asm/mpspec.h>
21 #include <asm/tables.h>
22 #include <asm/arch/global_nvs.h>
26 * IASL compiles the dsdt entries and writes the hex values
27 * to a C array AmlCode[] (see dsdt.c).
29 extern const unsigned char AmlCode
[];
31 /* ACPI RSDP address to be used in boot parameters */
32 static ulong acpi_rsdp_addr
;
34 static void acpi_write_rsdp(struct acpi_rsdp
*rsdp
, struct acpi_rsdt
*rsdt
,
35 struct acpi_xsdt
*xsdt
)
37 memset(rsdp
, 0, sizeof(struct acpi_rsdp
));
39 memcpy(rsdp
->signature
, RSDP_SIG
, 8);
40 memcpy(rsdp
->oem_id
, OEM_ID
, 6);
42 rsdp
->length
= sizeof(struct acpi_rsdp
);
43 rsdp
->rsdt_address
= (u32
)rsdt
;
45 rsdp
->xsdt_address
= (u64
)(u32
)xsdt
;
46 rsdp
->revision
= ACPI_RSDP_REV_ACPI_2_0
;
48 /* Calculate checksums */
49 rsdp
->checksum
= table_compute_checksum((void *)rsdp
, 20);
50 rsdp
->ext_checksum
= table_compute_checksum((void *)rsdp
,
51 sizeof(struct acpi_rsdp
));
54 static void acpi_write_rsdt(struct acpi_rsdt
*rsdt
)
56 struct acpi_table_header
*header
= &(rsdt
->header
);
58 /* Fill out header fields */
59 acpi_fill_header(header
, "RSDT");
60 header
->length
= sizeof(struct acpi_rsdt
);
63 /* Entries are filled in later, we come with an empty set */
66 header
->checksum
= table_compute_checksum((void *)rsdt
,
67 sizeof(struct acpi_rsdt
));
70 static void acpi_write_xsdt(struct acpi_xsdt
*xsdt
)
72 struct acpi_table_header
*header
= &(xsdt
->header
);
74 /* Fill out header fields */
75 acpi_fill_header(header
, "XSDT");
76 header
->length
= sizeof(struct acpi_xsdt
);
79 /* Entries are filled in later, we come with an empty set */
82 header
->checksum
= table_compute_checksum((void *)xsdt
,
83 sizeof(struct acpi_xsdt
));
86 static void acpi_create_facs(struct acpi_facs
*facs
)
88 memset((void *)facs
, 0, sizeof(struct acpi_facs
));
90 memcpy(facs
->signature
, "FACS", 4);
91 facs
->length
= sizeof(struct acpi_facs
);
92 facs
->hardware_signature
= 0;
93 facs
->firmware_waking_vector
= 0;
94 facs
->global_lock
= 0;
96 facs
->x_firmware_waking_vector_l
= 0;
97 facs
->x_firmware_waking_vector_h
= 0;
101 static int acpi_create_madt_lapic(struct acpi_madt_lapic
*lapic
,
104 lapic
->type
= ACPI_APIC_LAPIC
;
105 lapic
->length
= sizeof(struct acpi_madt_lapic
);
106 lapic
->flags
= LOCAL_APIC_FLAG_ENABLED
;
107 lapic
->processor_id
= cpu
;
108 lapic
->apic_id
= apic
;
110 return lapic
->length
;
113 int acpi_create_madt_lapics(u32 current
)
116 int total_length
= 0;
118 for (uclass_find_first_device(UCLASS_CPU
, &dev
);
120 uclass_find_next_device(&dev
)) {
121 struct cpu_platdata
*plat
= dev_get_parent_platdata(dev
);
122 int length
= acpi_create_madt_lapic(
123 (struct acpi_madt_lapic
*)current
,
124 plat
->cpu_id
, plat
->cpu_id
);
126 total_length
+= length
;
132 int acpi_create_madt_ioapic(struct acpi_madt_ioapic
*ioapic
, u8 id
,
133 u32 addr
, u32 gsi_base
)
135 ioapic
->type
= ACPI_APIC_IOAPIC
;
136 ioapic
->length
= sizeof(struct acpi_madt_ioapic
);
137 ioapic
->reserved
= 0x00;
138 ioapic
->gsi_base
= gsi_base
;
139 ioapic
->ioapic_id
= id
;
140 ioapic
->ioapic_addr
= addr
;
142 return ioapic
->length
;
145 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride
*irqoverride
,
146 u8 bus
, u8 source
, u32 gsirq
, u16 flags
)
148 irqoverride
->type
= ACPI_APIC_IRQ_SRC_OVERRIDE
;
149 irqoverride
->length
= sizeof(struct acpi_madt_irqoverride
);
150 irqoverride
->bus
= bus
;
151 irqoverride
->source
= source
;
152 irqoverride
->gsirq
= gsirq
;
153 irqoverride
->flags
= flags
;
155 return irqoverride
->length
;
158 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi
*lapic_nmi
,
159 u8 cpu
, u16 flags
, u8 lint
)
161 lapic_nmi
->type
= ACPI_APIC_LAPIC_NMI
;
162 lapic_nmi
->length
= sizeof(struct acpi_madt_lapic_nmi
);
163 lapic_nmi
->flags
= flags
;
164 lapic_nmi
->processor_id
= cpu
;
165 lapic_nmi
->lint
= lint
;
167 return lapic_nmi
->length
;
170 static int acpi_create_madt_irq_overrides(u32 current
)
172 struct acpi_madt_irqoverride
*irqovr
;
173 u16 sci_flags
= MP_IRQ_TRIGGER_LEVEL
| MP_IRQ_POLARITY_HIGH
;
176 irqovr
= (void *)current
;
177 length
+= acpi_create_madt_irqoverride(irqovr
, 0, 0, 2, 0);
179 irqovr
= (void *)(current
+ length
);
180 length
+= acpi_create_madt_irqoverride(irqovr
, 0, 9, 9, sci_flags
);
185 __weak u32
acpi_fill_madt(u32 current
)
187 current
+= acpi_create_madt_lapics(current
);
189 current
+= acpi_create_madt_ioapic((struct acpi_madt_ioapic
*)current
,
190 io_apic_read(IO_APIC_ID
) >> 24, IO_APIC_ADDR
, 0);
192 current
+= acpi_create_madt_irq_overrides(current
);
197 static void acpi_create_madt(struct acpi_madt
*madt
)
199 struct acpi_table_header
*header
= &(madt
->header
);
200 u32 current
= (u32
)madt
+ sizeof(struct acpi_madt
);
202 memset((void *)madt
, 0, sizeof(struct acpi_madt
));
204 /* Fill out header fields */
205 acpi_fill_header(header
, "APIC");
206 header
->length
= sizeof(struct acpi_madt
);
207 header
->revision
= 4;
209 madt
->lapic_addr
= LAPIC_DEFAULT_BASE
;
210 madt
->flags
= ACPI_MADT_PCAT_COMPAT
;
212 current
= acpi_fill_madt(current
);
214 /* (Re)calculate length and checksum */
215 header
->length
= current
- (u32
)madt
;
217 header
->checksum
= table_compute_checksum((void *)madt
, header
->length
);
220 int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig
*mmconfig
, u32 base
,
221 u16 seg_nr
, u8 start
, u8 end
)
223 memset(mmconfig
, 0, sizeof(*mmconfig
));
224 mmconfig
->base_address_l
= base
;
225 mmconfig
->base_address_h
= 0;
226 mmconfig
->pci_segment_group_number
= seg_nr
;
227 mmconfig
->start_bus_number
= start
;
228 mmconfig
->end_bus_number
= end
;
230 return sizeof(struct acpi_mcfg_mmconfig
);
233 __weak u32
acpi_fill_mcfg(u32 current
)
235 current
+= acpi_create_mcfg_mmconfig
236 ((struct acpi_mcfg_mmconfig
*)current
,
237 CONFIG_PCIE_ECAM_BASE
, 0x0, 0x0, 255);
242 /* MCFG is defined in the PCI Firmware Specification 3.0 */
243 static void acpi_create_mcfg(struct acpi_mcfg
*mcfg
)
245 struct acpi_table_header
*header
= &(mcfg
->header
);
246 u32 current
= (u32
)mcfg
+ sizeof(struct acpi_mcfg
);
248 memset((void *)mcfg
, 0, sizeof(struct acpi_mcfg
));
250 /* Fill out header fields */
251 acpi_fill_header(header
, "MCFG");
252 header
->length
= sizeof(struct acpi_mcfg
);
253 header
->revision
= 1;
255 current
= acpi_fill_mcfg(current
);
257 /* (Re)calculate length and checksum */
258 header
->length
= current
- (u32
)mcfg
;
259 header
->checksum
= table_compute_checksum((void *)mcfg
, header
->length
);
262 __weak u32
acpi_fill_csrt(u32 current
)
267 static void acpi_create_csrt(struct acpi_csrt
*csrt
)
269 struct acpi_table_header
*header
= &(csrt
->header
);
270 u32 current
= (u32
)csrt
+ sizeof(struct acpi_csrt
);
272 memset((void *)csrt
, 0, sizeof(struct acpi_csrt
));
274 /* Fill out header fields */
275 acpi_fill_header(header
, "CSRT");
276 header
->length
= sizeof(struct acpi_csrt
);
277 header
->revision
= 0;
279 current
= acpi_fill_csrt(current
);
281 /* (Re)calculate length and checksum */
282 header
->length
= current
- (u32
)csrt
;
283 header
->checksum
= table_compute_checksum((void *)csrt
, header
->length
);
286 static void acpi_create_spcr(struct acpi_spcr
*spcr
)
288 struct acpi_table_header
*header
= &(spcr
->header
);
289 struct serial_device_info serial_info
= {0};
290 ulong serial_address
, serial_offset
;
298 /* Fill out header fields */
299 acpi_fill_header(header
, "SPCR");
300 header
->length
= sizeof(struct acpi_spcr
);
301 header
->revision
= 2;
303 /* Read the device once, here. It is reused below */
304 dev
= gd
->cur_serial_dev
;
306 ret
= serial_getinfo(dev
, &serial_info
);
308 serial_info
.type
= SERIAL_CHIP_UNKNOWN
;
310 /* Encode chip type */
311 switch (serial_info
.type
) {
312 case SERIAL_CHIP_16550_COMPATIBLE
:
313 spcr
->interface_type
= ACPI_DBG2_16550_COMPATIBLE
;
315 case SERIAL_CHIP_UNKNOWN
:
317 spcr
->interface_type
= ACPI_DBG2_UNKNOWN
;
321 /* Encode address space */
322 switch (serial_info
.addr_space
) {
323 case SERIAL_ADDRESS_SPACE_MEMORY
:
324 space_id
= ACPI_ADDRESS_SPACE_MEMORY
;
326 case SERIAL_ADDRESS_SPACE_IO
:
328 space_id
= ACPI_ADDRESS_SPACE_IO
;
332 serial_width
= serial_info
.reg_width
* 8;
333 serial_offset
= serial_info
.reg_offset
<< serial_info
.reg_shift
;
334 serial_address
= serial_info
.addr
+ serial_offset
;
336 /* Encode register access size */
337 switch (serial_info
.reg_shift
) {
339 access_size
= ACPI_ACCESS_SIZE_BYTE_ACCESS
;
342 access_size
= ACPI_ACCESS_SIZE_WORD_ACCESS
;
345 access_size
= ACPI_ACCESS_SIZE_DWORD_ACCESS
;
348 access_size
= ACPI_ACCESS_SIZE_QWORD_ACCESS
;
351 access_size
= ACPI_ACCESS_SIZE_UNDEFINED
;
355 debug("UART type %u @ %lx\n", spcr
->interface_type
, serial_address
);
358 spcr
->serial_port
.space_id
= space_id
;
359 spcr
->serial_port
.bit_width
= serial_width
;
360 spcr
->serial_port
.bit_offset
= 0;
361 spcr
->serial_port
.access_size
= access_size
;
362 spcr
->serial_port
.addrl
= lower_32_bits(serial_address
);
363 spcr
->serial_port
.addrh
= upper_32_bits(serial_address
);
365 /* Encode baud rate */
366 switch (serial_info
.baudrate
) {
384 serial_config
= SERIAL_DEFAULT_CONFIG
;
386 ret
= serial_getconfig(dev
, &serial_config
);
388 spcr
->parity
= SERIAL_GET_PARITY(serial_config
);
389 spcr
->stop_bits
= SERIAL_GET_STOP(serial_config
);
391 /* No PCI devices for now */
392 spcr
->pci_device_id
= 0xffff;
393 spcr
->pci_vendor_id
= 0xffff;
396 * SPCR has no clue if the UART base clock speed is different
397 * to the default one. However, the SPCR 1.04 defines baud rate
398 * 0 as a preconfigured state of UART and OS is supposed not
399 * to touch the configuration of the serial device.
401 if (serial_info
.clock
!= SERIAL_DEFAULT_CLOCK
)
405 header
->checksum
= table_compute_checksum((void *)spcr
, header
->length
);
409 * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
411 ulong
write_acpi_tables(ulong start_addr
)
413 struct acpi_ctx sctx
, *ctx
= &sctx
;
414 struct acpi_xsdt
*xsdt
;
415 struct acpi_facs
*facs
;
416 struct acpi_table_header
*dsdt
;
417 struct acpi_fadt
*fadt
;
418 struct acpi_mcfg
*mcfg
;
419 struct acpi_madt
*madt
;
420 struct acpi_csrt
*csrt
;
421 struct acpi_spcr
*spcr
;
426 start
= map_sysmem(start_addr
, 0);
427 ctx
->current
= start
;
429 /* Align ACPI tables to 16 byte */
432 debug("ACPI: Writing ACPI tables at %lx\n", start_addr
);
434 /* We need at least an RSDP and an RSDT Table */
435 ctx
->rsdp
= ctx
->current
;
436 acpi_inc_align(ctx
, sizeof(struct acpi_rsdp
));
437 ctx
->rsdt
= ctx
->current
;
438 acpi_inc_align(ctx
, sizeof(struct acpi_rsdt
));
440 acpi_inc_align(ctx
, sizeof(struct acpi_xsdt
));
442 * Per ACPI spec, the FACS table address must be aligned to a 64 byte
443 * boundary (Windows checks this, but Linux does not).
447 /* clear all table memory */
448 memset((void *)start
, 0, ctx
->current
- start
);
450 acpi_write_rsdp(ctx
->rsdp
, ctx
->rsdt
, xsdt
);
451 acpi_write_rsdt(ctx
->rsdt
);
452 acpi_write_xsdt(xsdt
);
454 debug("ACPI: * FACS\n");
456 acpi_inc_align(ctx
, sizeof(struct acpi_facs
));
458 acpi_create_facs(facs
);
460 debug("ACPI: * DSDT\n");
462 memcpy(dsdt
, &AmlCode
, sizeof(struct acpi_table_header
));
463 acpi_inc(ctx
, sizeof(struct acpi_table_header
));
465 (char *)&AmlCode
+ sizeof(struct acpi_table_header
),
466 dsdt
->length
- sizeof(struct acpi_table_header
));
467 acpi_inc_align(ctx
, dsdt
->length
- sizeof(struct acpi_table_header
));
469 /* Pack GNVS into the ACPI table area */
470 for (i
= 0; i
< dsdt
->length
; i
++) {
471 u32
*gnvs
= (u32
*)((u32
)dsdt
+ i
);
472 if (*gnvs
== ACPI_GNVS_ADDR
) {
473 ulong addr
= (ulong
)map_to_sysmem(ctx
->current
);
475 debug("Fix up global NVS in DSDT to %#08lx\n", addr
);
481 /* Update DSDT checksum since we patched the GNVS address */
483 dsdt
->checksum
= table_compute_checksum((void *)dsdt
, dsdt
->length
);
485 /* Fill in platform-specific global NVS variables */
486 acpi_create_gnvs(ctx
->current
);
487 acpi_inc_align(ctx
, sizeof(struct acpi_global_nvs
));
489 debug("ACPI: * FADT\n");
491 acpi_inc_align(ctx
, sizeof(struct acpi_fadt
));
492 acpi_create_fadt(fadt
, facs
, dsdt
);
493 acpi_add_table(ctx
, fadt
);
495 debug("ACPI: * MADT\n");
497 acpi_create_madt(madt
);
498 acpi_inc_align(ctx
, madt
->header
.length
);
499 acpi_add_table(ctx
, madt
);
501 debug("ACPI: * MCFG\n");
503 acpi_create_mcfg(mcfg
);
504 acpi_inc_align(ctx
, mcfg
->header
.length
);
505 acpi_add_table(ctx
, mcfg
);
507 debug("ACPI: * CSRT\n");
509 acpi_create_csrt(csrt
);
510 acpi_inc_align(ctx
, csrt
->header
.length
);
511 acpi_add_table(ctx
, csrt
);
513 debug("ACPI: * SPCR\n");
515 acpi_create_spcr(spcr
);
516 acpi_inc_align(ctx
, spcr
->header
.length
);
517 acpi_add_table(ctx
, spcr
);
519 acpi_write_dev_tables(ctx
);
521 addr
= map_to_sysmem(ctx
->current
);
522 debug("current = %lx\n", addr
);
524 acpi_rsdp_addr
= (unsigned long)ctx
->rsdp
;
525 debug("ACPI: done\n");
530 ulong
acpi_get_rsdp_addr(void)
532 return acpi_rsdp_addr
;