blob: ff8cee51d600875a6bd3cbbfeeb130d793afb08b [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Saket Sinha331141a2015-08-22 12:20:55 +05302/*
3 * Based on acpi.c from coreboot
4 *
5 * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
Bin Meng44256b02016-05-07 07:46:25 -07006 * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
Saket Sinha331141a2015-08-22 12:20:55 +05307 */
8
9#include <common.h>
10#include <cpu.h>
11#include <dm.h>
12#include <dm/uclass-internal.h>
Simon Glass0e113842020-04-26 09:19:47 -060013#include <mapmem.h>
Andy Shevchenko4ca48c92018-11-20 23:52:38 +020014#include <serial.h>
Andy Shevchenko87e95372017-07-21 22:32:02 +030015#include <version.h>
Simon Glass858fed12020-04-08 16:57:36 -060016#include <acpi/acpi_table.h>
Bin Mengd9050c62016-06-17 02:13:16 -070017#include <asm/acpi/global_nvs.h>
Andy Shevchenko13a5d872017-07-21 22:32:04 +030018#include <asm/ioapic.h>
Saket Sinha331141a2015-08-22 12:20:55 +053019#include <asm/lapic.h>
Andy Shevchenko13a5d872017-07-21 22:32:04 +030020#include <asm/mpspec.h>
Saket Sinha331141a2015-08-22 12:20:55 +053021#include <asm/tables.h>
Bin Mengd9050c62016-06-17 02:13:16 -070022#include <asm/arch/global_nvs.h>
Simon Glass0e113842020-04-26 09:19:47 -060023#include <dm/acpi.h>
Saket Sinha331141a2015-08-22 12:20:55 +053024
25/*
Bin Mengb063d5f2016-05-07 07:46:24 -070026 * IASL compiles the dsdt entries and writes the hex values
27 * to a C array AmlCode[] (see dsdt.c).
Saket Sinha331141a2015-08-22 12:20:55 +053028 */
29extern const unsigned char AmlCode[];
30
Andy Shevchenko66d3e632018-01-10 19:40:15 +020031/* ACPI RSDP address to be used in boot parameters */
Bin Menge1029252018-01-30 05:01:16 -080032static ulong acpi_rsdp_addr;
Andy Shevchenko66d3e632018-01-10 19:40:15 +020033
Bin Meng44256b02016-05-07 07:46:25 -070034static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
35 struct acpi_xsdt *xsdt)
36{
37 memset(rsdp, 0, sizeof(struct acpi_rsdp));
38
39 memcpy(rsdp->signature, RSDP_SIG, 8);
40 memcpy(rsdp->oem_id, OEM_ID, 6);
41
42 rsdp->length = sizeof(struct acpi_rsdp);
43 rsdp->rsdt_address = (u32)rsdt;
44
Simon Glass7fa8cf62020-04-26 09:19:49 -060045 rsdp->xsdt_address = (u64)(u32)xsdt;
46 rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
Bin Meng44256b02016-05-07 07:46:25 -070047
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));
52}
53
Bin Meng44256b02016-05-07 07:46:25 -070054static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
55{
56 struct acpi_table_header *header = &(rsdt->header);
57
58 /* Fill out header fields */
59 acpi_fill_header(header, "RSDT");
60 header->length = sizeof(struct acpi_rsdt);
Bin Mengf662fe42016-05-07 07:46:28 -070061 header->revision = 1;
Bin Meng44256b02016-05-07 07:46:25 -070062
63 /* Entries are filled in later, we come with an empty set */
64
65 /* Fix checksum */
66 header->checksum = table_compute_checksum((void *)rsdt,
67 sizeof(struct acpi_rsdt));
68}
69
70static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
71{
72 struct acpi_table_header *header = &(xsdt->header);
73
74 /* Fill out header fields */
75 acpi_fill_header(header, "XSDT");
76 header->length = sizeof(struct acpi_xsdt);
Bin Mengf662fe42016-05-07 07:46:28 -070077 header->revision = 1;
Bin Meng44256b02016-05-07 07:46:25 -070078
79 /* Entries are filled in later, we come with an empty set */
80
81 /* Fix checksum */
82 header->checksum = table_compute_checksum((void *)xsdt,
83 sizeof(struct acpi_xsdt));
84}
85
Bin Meng44256b02016-05-07 07:46:25 -070086static void acpi_create_facs(struct acpi_facs *facs)
87{
88 memset((void *)facs, 0, sizeof(struct acpi_facs));
89
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;
95 facs->flags = 0;
96 facs->x_firmware_waking_vector_l = 0;
97 facs->x_firmware_waking_vector_h = 0;
98 facs->version = 1;
99}
100
Saket Sinha331141a2015-08-22 12:20:55 +0530101static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
Bin Meng44256b02016-05-07 07:46:25 -0700102 u8 cpu, u8 apic)
Saket Sinha331141a2015-08-22 12:20:55 +0530103{
Bin Meng44256b02016-05-07 07:46:25 -0700104 lapic->type = ACPI_APIC_LAPIC;
Saket Sinha331141a2015-08-22 12:20:55 +0530105 lapic->length = sizeof(struct acpi_madt_lapic);
Bin Meng44256b02016-05-07 07:46:25 -0700106 lapic->flags = LOCAL_APIC_FLAG_ENABLED;
Saket Sinha331141a2015-08-22 12:20:55 +0530107 lapic->processor_id = cpu;
108 lapic->apic_id = apic;
109
110 return lapic->length;
111}
112
Bin Meng3c5234e2016-05-07 07:46:30 -0700113int acpi_create_madt_lapics(u32 current)
Saket Sinha331141a2015-08-22 12:20:55 +0530114{
115 struct udevice *dev;
George McCollister5a49f872016-06-07 13:40:18 -0500116 int total_length = 0;
Saket Sinha331141a2015-08-22 12:20:55 +0530117
118 for (uclass_find_first_device(UCLASS_CPU, &dev);
119 dev;
120 uclass_find_next_device(&dev)) {
121 struct cpu_platdata *plat = dev_get_parent_platdata(dev);
George McCollister5a49f872016-06-07 13:40:18 -0500122 int length = acpi_create_madt_lapic(
123 (struct acpi_madt_lapic *)current,
124 plat->cpu_id, plat->cpu_id);
Bin Meng3c5234e2016-05-07 07:46:30 -0700125 current += length;
George McCollister5a49f872016-06-07 13:40:18 -0500126 total_length += length;
Bin Meng44256b02016-05-07 07:46:25 -0700127 }
128
George McCollister5a49f872016-06-07 13:40:18 -0500129 return total_length;
Saket Sinha331141a2015-08-22 12:20:55 +0530130}
131
Bin Meng44256b02016-05-07 07:46:25 -0700132int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
133 u32 addr, u32 gsi_base)
Saket Sinha331141a2015-08-22 12:20:55 +0530134{
Bin Meng6a421582016-05-07 07:46:21 -0700135 ioapic->type = ACPI_APIC_IOAPIC;
Saket Sinha331141a2015-08-22 12:20:55 +0530136 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;
141
142 return ioapic->length;
143}
144
145int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
Bin Meng44256b02016-05-07 07:46:25 -0700146 u8 bus, u8 source, u32 gsirq, u16 flags)
Saket Sinha331141a2015-08-22 12:20:55 +0530147{
Bin Meng6a421582016-05-07 07:46:21 -0700148 irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
Saket Sinha331141a2015-08-22 12:20:55 +0530149 irqoverride->length = sizeof(struct acpi_madt_irqoverride);
150 irqoverride->bus = bus;
151 irqoverride->source = source;
152 irqoverride->gsirq = gsirq;
153 irqoverride->flags = flags;
154
155 return irqoverride->length;
156}
157
158int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
Bin Meng44256b02016-05-07 07:46:25 -0700159 u8 cpu, u16 flags, u8 lint)
Saket Sinha331141a2015-08-22 12:20:55 +0530160{
Bin Meng6a421582016-05-07 07:46:21 -0700161 lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
Saket Sinha331141a2015-08-22 12:20:55 +0530162 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;
166
167 return lapic_nmi->length;
168}
169
Andy Shevchenko13a5d872017-07-21 22:32:04 +0300170static int acpi_create_madt_irq_overrides(u32 current)
171{
172 struct acpi_madt_irqoverride *irqovr;
173 u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
174 int length = 0;
175
176 irqovr = (void *)current;
177 length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
178
179 irqovr = (void *)(current + length);
180 length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
181
182 return length;
183}
184
185__weak u32 acpi_fill_madt(u32 current)
186{
187 current += acpi_create_madt_lapics(current);
188
189 current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
190 io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
191
192 current += acpi_create_madt_irq_overrides(current);
193
194 return current;
195}
196
Saket Sinha331141a2015-08-22 12:20:55 +0530197static void acpi_create_madt(struct acpi_madt *madt)
198{
Bin Meng6a421582016-05-07 07:46:21 -0700199 struct acpi_table_header *header = &(madt->header);
Bin Menga1ec7db2016-05-07 07:46:26 -0700200 u32 current = (u32)madt + sizeof(struct acpi_madt);
Saket Sinha331141a2015-08-22 12:20:55 +0530201
202 memset((void *)madt, 0, sizeof(struct acpi_madt));
203
204 /* Fill out header fields */
Bin Mengb063d5f2016-05-07 07:46:24 -0700205 acpi_fill_header(header, "APIC");
Saket Sinha331141a2015-08-22 12:20:55 +0530206 header->length = sizeof(struct acpi_madt);
Bin Mengf662fe42016-05-07 07:46:28 -0700207 header->revision = 4;
Saket Sinha331141a2015-08-22 12:20:55 +0530208
209 madt->lapic_addr = LAPIC_DEFAULT_BASE;
Bin Meng6a421582016-05-07 07:46:21 -0700210 madt->flags = ACPI_MADT_PCAT_COMPAT;
Saket Sinha331141a2015-08-22 12:20:55 +0530211
212 current = acpi_fill_madt(current);
213
214 /* (Re)calculate length and checksum */
Bin Menga1ec7db2016-05-07 07:46:26 -0700215 header->length = current - (u32)madt;
Saket Sinha331141a2015-08-22 12:20:55 +0530216
217 header->checksum = table_compute_checksum((void *)madt, header->length);
218}
219
Andy Shevchenkoc1ae9802017-07-21 22:32:05 +0300220int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
221 u16 seg_nr, u8 start, u8 end)
Saket Sinha331141a2015-08-22 12:20:55 +0530222{
223 memset(mmconfig, 0, sizeof(*mmconfig));
Bin Meng6a421582016-05-07 07:46:21 -0700224 mmconfig->base_address_l = base;
225 mmconfig->base_address_h = 0;
Saket Sinha331141a2015-08-22 12:20:55 +0530226 mmconfig->pci_segment_group_number = seg_nr;
227 mmconfig->start_bus_number = start;
228 mmconfig->end_bus_number = end;
229
230 return sizeof(struct acpi_mcfg_mmconfig);
231}
232
Andy Shevchenkoc1ae9802017-07-21 22:32:05 +0300233__weak u32 acpi_fill_mcfg(u32 current)
Saket Sinha331141a2015-08-22 12:20:55 +0530234{
235 current += acpi_create_mcfg_mmconfig
236 ((struct acpi_mcfg_mmconfig *)current,
Bin Meng44256b02016-05-07 07:46:25 -0700237 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
Saket Sinha331141a2015-08-22 12:20:55 +0530238
239 return current;
240}
241
242/* MCFG is defined in the PCI Firmware Specification 3.0 */
243static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
244{
Bin Meng6a421582016-05-07 07:46:21 -0700245 struct acpi_table_header *header = &(mcfg->header);
Bin Menga1ec7db2016-05-07 07:46:26 -0700246 u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
Saket Sinha331141a2015-08-22 12:20:55 +0530247
248 memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
249
250 /* Fill out header fields */
Bin Mengb063d5f2016-05-07 07:46:24 -0700251 acpi_fill_header(header, "MCFG");
Saket Sinha331141a2015-08-22 12:20:55 +0530252 header->length = sizeof(struct acpi_mcfg);
Bin Mengf662fe42016-05-07 07:46:28 -0700253 header->revision = 1;
Saket Sinha331141a2015-08-22 12:20:55 +0530254
255 current = acpi_fill_mcfg(current);
256
257 /* (Re)calculate length and checksum */
Bin Menga1ec7db2016-05-07 07:46:26 -0700258 header->length = current - (u32)mcfg;
Saket Sinha331141a2015-08-22 12:20:55 +0530259 header->checksum = table_compute_checksum((void *)mcfg, header->length);
260}
261
Andy Shevchenko607dbd12019-07-14 19:23:57 +0300262__weak u32 acpi_fill_csrt(u32 current)
263{
264 return current;
265}
266
267static void acpi_create_csrt(struct acpi_csrt *csrt)
268{
269 struct acpi_table_header *header = &(csrt->header);
270 u32 current = (u32)csrt + sizeof(struct acpi_csrt);
271
272 memset((void *)csrt, 0, sizeof(struct acpi_csrt));
273
274 /* Fill out header fields */
275 acpi_fill_header(header, "CSRT");
276 header->length = sizeof(struct acpi_csrt);
277 header->revision = 0;
278
279 current = acpi_fill_csrt(current);
280
281 /* (Re)calculate length and checksum */
282 header->length = current - (u32)csrt;
283 header->checksum = table_compute_checksum((void *)csrt, header->length);
284}
285
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200286static void acpi_create_spcr(struct acpi_spcr *spcr)
287{
288 struct acpi_table_header *header = &(spcr->header);
289 struct serial_device_info serial_info = {0};
290 ulong serial_address, serial_offset;
Simon Glassdaaff932018-12-28 14:23:08 -0700291 struct udevice *dev;
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200292 uint serial_config;
293 uint serial_width;
294 int access_size;
295 int space_id;
Andy Shevchenkobf9c8e32019-02-28 17:19:54 +0200296 int ret = -ENODEV;
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200297
298 /* Fill out header fields */
299 acpi_fill_header(header, "SPCR");
300 header->length = sizeof(struct acpi_spcr);
301 header->revision = 2;
302
Simon Glass896c1642018-12-28 14:23:10 -0700303 /* Read the device once, here. It is reused below */
Andy Shevchenkobf9c8e32019-02-28 17:19:54 +0200304 dev = gd->cur_serial_dev;
305 if (dev)
Simon Glass896c1642018-12-28 14:23:10 -0700306 ret = serial_getinfo(dev, &serial_info);
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200307 if (ret)
308 serial_info.type = SERIAL_CHIP_UNKNOWN;
309
310 /* Encode chip type */
311 switch (serial_info.type) {
312 case SERIAL_CHIP_16550_COMPATIBLE:
313 spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE;
314 break;
315 case SERIAL_CHIP_UNKNOWN:
316 default:
317 spcr->interface_type = ACPI_DBG2_UNKNOWN;
318 break;
319 }
320
321 /* Encode address space */
322 switch (serial_info.addr_space) {
323 case SERIAL_ADDRESS_SPACE_MEMORY:
324 space_id = ACPI_ADDRESS_SPACE_MEMORY;
325 break;
326 case SERIAL_ADDRESS_SPACE_IO:
327 default:
328 space_id = ACPI_ADDRESS_SPACE_IO;
329 break;
330 }
331
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;
335
336 /* Encode register access size */
337 switch (serial_info.reg_shift) {
338 case 0:
339 access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
340 break;
341 case 1:
342 access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
343 break;
344 case 2:
345 access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
346 break;
347 case 3:
348 access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
349 break;
350 default:
351 access_size = ACPI_ACCESS_SIZE_UNDEFINED;
352 break;
353 }
354
355 debug("UART type %u @ %lx\n", spcr->interface_type, serial_address);
356
357 /* Fill GAS */
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);
364
365 /* Encode baud rate */
366 switch (serial_info.baudrate) {
367 case 9600:
368 spcr->baud_rate = 3;
369 break;
370 case 19200:
371 spcr->baud_rate = 4;
372 break;
373 case 57600:
374 spcr->baud_rate = 6;
375 break;
376 case 115200:
377 spcr->baud_rate = 7;
378 break;
379 default:
380 spcr->baud_rate = 0;
381 break;
382 }
383
Simon Glass896c1642018-12-28 14:23:10 -0700384 serial_config = SERIAL_DEFAULT_CONFIG;
385 if (dev)
Simon Glassdaaff932018-12-28 14:23:08 -0700386 ret = serial_getconfig(dev, &serial_config);
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200387
388 spcr->parity = SERIAL_GET_PARITY(serial_config);
389 spcr->stop_bits = SERIAL_GET_STOP(serial_config);
390
391 /* No PCI devices for now */
392 spcr->pci_device_id = 0xffff;
393 spcr->pci_vendor_id = 0xffff;
394
Andy Shevchenko225cc8a2020-02-27 17:21:56 +0200395 /*
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.
400 */
401 if (serial_info.clock != SERIAL_DEFAULT_CLOCK)
402 spcr->baud_rate = 0;
403
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200404 /* Fix checksum */
405 header->checksum = table_compute_checksum((void *)spcr, header->length);
406}
407
Miao Yan3b68c522016-01-20 01:57:06 -0800408/*
Andy Shevchenko4b05bac2018-01-10 19:33:10 +0200409 * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
Miao Yan3b68c522016-01-20 01:57:06 -0800410 */
Simon Glass0e113842020-04-26 09:19:47 -0600411ulong write_acpi_tables(ulong start_addr)
Saket Sinha331141a2015-08-22 12:20:55 +0530412{
Simon Glass0e113842020-04-26 09:19:47 -0600413 struct acpi_ctx sctx, *ctx = &sctx;
Saket Sinha331141a2015-08-22 12:20:55 +0530414 struct acpi_xsdt *xsdt;
415 struct acpi_facs *facs;
Bin Meng6a421582016-05-07 07:46:21 -0700416 struct acpi_table_header *dsdt;
Saket Sinha331141a2015-08-22 12:20:55 +0530417 struct acpi_fadt *fadt;
418 struct acpi_mcfg *mcfg;
419 struct acpi_madt *madt;
Andy Shevchenko607dbd12019-07-14 19:23:57 +0300420 struct acpi_csrt *csrt;
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200421 struct acpi_spcr *spcr;
Simon Glass0e113842020-04-26 09:19:47 -0600422 void *start;
423 ulong addr;
Bin Mengd9050c62016-06-17 02:13:16 -0700424 int i;
Saket Sinha331141a2015-08-22 12:20:55 +0530425
Simon Glass0e113842020-04-26 09:19:47 -0600426 start = map_sysmem(start_addr, 0);
427 ctx->current = start;
Saket Sinha331141a2015-08-22 12:20:55 +0530428
Bin Meng44256b02016-05-07 07:46:25 -0700429 /* Align ACPI tables to 16 byte */
Simon Glass0e113842020-04-26 09:19:47 -0600430 acpi_align(ctx);
Saket Sinha331141a2015-08-22 12:20:55 +0530431
Simon Glass0e113842020-04-26 09:19:47 -0600432 debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
Saket Sinha331141a2015-08-22 12:20:55 +0530433
434 /* We need at least an RSDP and an RSDT Table */
Simon Glass575a5472020-04-26 09:19:50 -0600435 ctx->rsdp = ctx->current;
Simon Glass0e113842020-04-26 09:19:47 -0600436 acpi_inc_align(ctx, sizeof(struct acpi_rsdp));
Simon Glass575a5472020-04-26 09:19:50 -0600437 ctx->rsdt = ctx->current;
Simon Glass0e113842020-04-26 09:19:47 -0600438 acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
439 xsdt = ctx->current;
440 acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
Bin Meng3d938d12016-05-07 07:46:27 -0700441 /*
442 * Per ACPI spec, the FACS table address must be aligned to a 64 byte
443 * boundary (Windows checks this, but Linux does not).
444 */
Simon Glass0e113842020-04-26 09:19:47 -0600445 acpi_align64(ctx);
Saket Sinha331141a2015-08-22 12:20:55 +0530446
447 /* clear all table memory */
Simon Glass0e113842020-04-26 09:19:47 -0600448 memset((void *)start, 0, ctx->current - start);
Saket Sinha331141a2015-08-22 12:20:55 +0530449
Simon Glass575a5472020-04-26 09:19:50 -0600450 acpi_write_rsdp(ctx->rsdp, ctx->rsdt, xsdt);
451 acpi_write_rsdt(ctx->rsdt);
Saket Sinha331141a2015-08-22 12:20:55 +0530452 acpi_write_xsdt(xsdt);
453
454 debug("ACPI: * FACS\n");
Simon Glass0e113842020-04-26 09:19:47 -0600455 facs = ctx->current;
456 acpi_inc_align(ctx, sizeof(struct acpi_facs));
Saket Sinha331141a2015-08-22 12:20:55 +0530457
458 acpi_create_facs(facs);
459
460 debug("ACPI: * DSDT\n");
Simon Glass0e113842020-04-26 09:19:47 -0600461 dsdt = ctx->current;
Bin Meng6a421582016-05-07 07:46:21 -0700462 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
Simon Glass0e113842020-04-26 09:19:47 -0600463 acpi_inc(ctx, sizeof(struct acpi_table_header));
464 memcpy(ctx->current,
Bin Mengd90434b2016-05-11 07:45:05 -0700465 (char *)&AmlCode + sizeof(struct acpi_table_header),
466 dsdt->length - sizeof(struct acpi_table_header));
Simon Glass0e113842020-04-26 09:19:47 -0600467 acpi_inc_align(ctx, dsdt->length - sizeof(struct acpi_table_header));
Saket Sinha331141a2015-08-22 12:20:55 +0530468
Bin Mengd9050c62016-06-17 02:13:16 -0700469 /* 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) {
Simon Glass0e113842020-04-26 09:19:47 -0600473 ulong addr = (ulong)map_to_sysmem(ctx->current);
474
475 debug("Fix up global NVS in DSDT to %#08lx\n", addr);
476 *gnvs = addr;
Bin Mengd9050c62016-06-17 02:13:16 -0700477 break;
478 }
479 }
480
481 /* Update DSDT checksum since we patched the GNVS address */
482 dsdt->checksum = 0;
483 dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
484
485 /* Fill in platform-specific global NVS variables */
Simon Glass0e113842020-04-26 09:19:47 -0600486 acpi_create_gnvs(ctx->current);
487 acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
Bin Mengd9050c62016-06-17 02:13:16 -0700488
Saket Sinha331141a2015-08-22 12:20:55 +0530489 debug("ACPI: * FADT\n");
Simon Glass0e113842020-04-26 09:19:47 -0600490 fadt = ctx->current;
491 acpi_inc_align(ctx, sizeof(struct acpi_fadt));
Saket Sinha331141a2015-08-22 12:20:55 +0530492 acpi_create_fadt(fadt, facs, dsdt);
Simon Glass575a5472020-04-26 09:19:50 -0600493 acpi_add_table(ctx, fadt);
Saket Sinha331141a2015-08-22 12:20:55 +0530494
Saket Sinha331141a2015-08-22 12:20:55 +0530495 debug("ACPI: * MADT\n");
Simon Glass0e113842020-04-26 09:19:47 -0600496 madt = ctx->current;
Saket Sinha331141a2015-08-22 12:20:55 +0530497 acpi_create_madt(madt);
Simon Glass0e113842020-04-26 09:19:47 -0600498 acpi_inc_align(ctx, madt->header.length);
Simon Glass575a5472020-04-26 09:19:50 -0600499 acpi_add_table(ctx, madt);
Saket Sinha331141a2015-08-22 12:20:55 +0530500
Bin Meng44256b02016-05-07 07:46:25 -0700501 debug("ACPI: * MCFG\n");
Simon Glass0e113842020-04-26 09:19:47 -0600502 mcfg = ctx->current;
Bin Meng44256b02016-05-07 07:46:25 -0700503 acpi_create_mcfg(mcfg);
Simon Glass0e113842020-04-26 09:19:47 -0600504 acpi_inc_align(ctx, mcfg->header.length);
Simon Glass575a5472020-04-26 09:19:50 -0600505 acpi_add_table(ctx, mcfg);
Bin Meng44256b02016-05-07 07:46:25 -0700506
Andy Shevchenko607dbd12019-07-14 19:23:57 +0300507 debug("ACPI: * CSRT\n");
Simon Glass0e113842020-04-26 09:19:47 -0600508 csrt = ctx->current;
Andy Shevchenko607dbd12019-07-14 19:23:57 +0300509 acpi_create_csrt(csrt);
Simon Glass0e113842020-04-26 09:19:47 -0600510 acpi_inc_align(ctx, csrt->header.length);
Simon Glass575a5472020-04-26 09:19:50 -0600511 acpi_add_table(ctx, csrt);
Andy Shevchenko607dbd12019-07-14 19:23:57 +0300512
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200513 debug("ACPI: * SPCR\n");
Simon Glass0e113842020-04-26 09:19:47 -0600514 spcr = ctx->current;
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200515 acpi_create_spcr(spcr);
Simon Glass0e113842020-04-26 09:19:47 -0600516 acpi_inc_align(ctx, spcr->header.length);
Simon Glass575a5472020-04-26 09:19:50 -0600517 acpi_add_table(ctx, spcr);
Andy Shevchenko4ca48c92018-11-20 23:52:38 +0200518
Simon Glass179fb822020-04-26 09:19:48 -0600519 acpi_write_dev_tables(ctx);
520
Simon Glass0e113842020-04-26 09:19:47 -0600521 addr = map_to_sysmem(ctx->current);
522 debug("current = %lx\n", addr);
Saket Sinha331141a2015-08-22 12:20:55 +0530523
Simon Glass575a5472020-04-26 09:19:50 -0600524 acpi_rsdp_addr = (unsigned long)ctx->rsdp;
Bin Mengd2d22182016-05-07 07:46:12 -0700525 debug("ACPI: done\n");
Saket Sinha331141a2015-08-22 12:20:55 +0530526
Simon Glass0e113842020-04-26 09:19:47 -0600527 return addr;
Saket Sinha331141a2015-08-22 12:20:55 +0530528}
Bin Meng34bc74a2017-04-21 07:24:36 -0700529
Bin Menge1029252018-01-30 05:01:16 -0800530ulong acpi_get_rsdp_addr(void)
531{
532 return acpi_rsdp_addr;
533}