x86: zImage: Propagate acpi_rsdp_addr to kernel via boot parameters
[oweals/u-boot.git] / arch / x86 / lib / acpi_table.c
1 /*
2  * Based on acpi.c from coreboot
3  *
4  * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
5  * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
6  *
7  * SPDX-License-Identifier: GPL-2.0+
8  */
9
10 #include <common.h>
11 #include <cpu.h>
12 #include <dm.h>
13 #include <dm/uclass-internal.h>
14 #include <version.h>
15 #include <asm/acpi/global_nvs.h>
16 #include <asm/acpi_table.h>
17 #include <asm/io.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>
23 #include "acpi_table.h"
24
25 /*
26  * IASL compiles the dsdt entries and writes the hex values
27  * to a C array AmlCode[] (see dsdt.c).
28  */
29 extern const unsigned char AmlCode[];
30
31 /* ACPI RSDP address to be used in boot parameters */
32 unsigned long acpi_rsdp_addr;
33
34 static 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
45         /*
46          * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2
47          *
48          * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2.
49          * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR
50          * revision 0)
51          */
52         if (xsdt == NULL) {
53                 rsdp->revision = ACPI_RSDP_REV_ACPI_1_0;
54         } else {
55                 rsdp->xsdt_address = (u64)(u32)xsdt;
56                 rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
57         }
58
59         /* Calculate checksums */
60         rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
61         rsdp->ext_checksum = table_compute_checksum((void *)rsdp,
62                         sizeof(struct acpi_rsdp));
63 }
64
65 void acpi_fill_header(struct acpi_table_header *header, char *signature)
66 {
67         memcpy(header->signature, signature, 4);
68         memcpy(header->oem_id, OEM_ID, 6);
69         memcpy(header->oem_table_id, OEM_TABLE_ID, 8);
70         header->oem_revision = U_BOOT_BUILD_DATE;
71         memcpy(header->aslc_id, ASLC_ID, 4);
72 }
73
74 static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
75 {
76         struct acpi_table_header *header = &(rsdt->header);
77
78         /* Fill out header fields */
79         acpi_fill_header(header, "RSDT");
80         header->length = sizeof(struct acpi_rsdt);
81         header->revision = 1;
82
83         /* Entries are filled in later, we come with an empty set */
84
85         /* Fix checksum */
86         header->checksum = table_compute_checksum((void *)rsdt,
87                         sizeof(struct acpi_rsdt));
88 }
89
90 static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
91 {
92         struct acpi_table_header *header = &(xsdt->header);
93
94         /* Fill out header fields */
95         acpi_fill_header(header, "XSDT");
96         header->length = sizeof(struct acpi_xsdt);
97         header->revision = 1;
98
99         /* Entries are filled in later, we come with an empty set */
100
101         /* Fix checksum */
102         header->checksum = table_compute_checksum((void *)xsdt,
103                         sizeof(struct acpi_xsdt));
104 }
105
106 /**
107  * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
108  * and checksum.
109  */
110 static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
111 {
112         int i, entries_num;
113         struct acpi_rsdt *rsdt;
114         struct acpi_xsdt *xsdt = NULL;
115
116         /* The RSDT is mandatory while the XSDT is not */
117         rsdt = (struct acpi_rsdt *)rsdp->rsdt_address;
118
119         if (rsdp->xsdt_address)
120                 xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address);
121
122         /* This should always be MAX_ACPI_TABLES */
123         entries_num = ARRAY_SIZE(rsdt->entry);
124
125         for (i = 0; i < entries_num; i++) {
126                 if (rsdt->entry[i] == 0)
127                         break;
128         }
129
130         if (i >= entries_num) {
131                 debug("ACPI: Error: too many tables\n");
132                 return;
133         }
134
135         /* Add table to the RSDT */
136         rsdt->entry[i] = (u32)table;
137
138         /* Fix RSDT length or the kernel will assume invalid entries */
139         rsdt->header.length = sizeof(struct acpi_table_header) +
140                                 (sizeof(u32) * (i + 1));
141
142         /* Re-calculate checksum */
143         rsdt->header.checksum = 0;
144         rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
145                         rsdt->header.length);
146
147         /*
148          * And now the same thing for the XSDT. We use the same index as for
149          * now we want the XSDT and RSDT to always be in sync in U-Boot
150          */
151         if (xsdt) {
152                 /* Add table to the XSDT */
153                 xsdt->entry[i] = (u64)(u32)table;
154
155                 /* Fix XSDT length */
156                 xsdt->header.length = sizeof(struct acpi_table_header) +
157                         (sizeof(u64) * (i + 1));
158
159                 /* Re-calculate checksum */
160                 xsdt->header.checksum = 0;
161                 xsdt->header.checksum = table_compute_checksum((u8 *)xsdt,
162                                 xsdt->header.length);
163         }
164 }
165
166 static void acpi_create_facs(struct acpi_facs *facs)
167 {
168         memset((void *)facs, 0, sizeof(struct acpi_facs));
169
170         memcpy(facs->signature, "FACS", 4);
171         facs->length = sizeof(struct acpi_facs);
172         facs->hardware_signature = 0;
173         facs->firmware_waking_vector = 0;
174         facs->global_lock = 0;
175         facs->flags = 0;
176         facs->x_firmware_waking_vector_l = 0;
177         facs->x_firmware_waking_vector_h = 0;
178         facs->version = 1;
179 }
180
181 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
182                                   u8 cpu, u8 apic)
183 {
184         lapic->type = ACPI_APIC_LAPIC;
185         lapic->length = sizeof(struct acpi_madt_lapic);
186         lapic->flags = LOCAL_APIC_FLAG_ENABLED;
187         lapic->processor_id = cpu;
188         lapic->apic_id = apic;
189
190         return lapic->length;
191 }
192
193 int acpi_create_madt_lapics(u32 current)
194 {
195         struct udevice *dev;
196         int total_length = 0;
197
198         for (uclass_find_first_device(UCLASS_CPU, &dev);
199              dev;
200              uclass_find_next_device(&dev)) {
201                 struct cpu_platdata *plat = dev_get_parent_platdata(dev);
202                 int length = acpi_create_madt_lapic(
203                                 (struct acpi_madt_lapic *)current,
204                                 plat->cpu_id, plat->cpu_id);
205                 current += length;
206                 total_length += length;
207         }
208
209         return total_length;
210 }
211
212 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
213                             u32 addr, u32 gsi_base)
214 {
215         ioapic->type = ACPI_APIC_IOAPIC;
216         ioapic->length = sizeof(struct acpi_madt_ioapic);
217         ioapic->reserved = 0x00;
218         ioapic->gsi_base = gsi_base;
219         ioapic->ioapic_id = id;
220         ioapic->ioapic_addr = addr;
221
222         return ioapic->length;
223 }
224
225 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
226                                  u8 bus, u8 source, u32 gsirq, u16 flags)
227 {
228         irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
229         irqoverride->length = sizeof(struct acpi_madt_irqoverride);
230         irqoverride->bus = bus;
231         irqoverride->source = source;
232         irqoverride->gsirq = gsirq;
233         irqoverride->flags = flags;
234
235         return irqoverride->length;
236 }
237
238 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
239                                u8 cpu, u16 flags, u8 lint)
240 {
241         lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
242         lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
243         lapic_nmi->flags = flags;
244         lapic_nmi->processor_id = cpu;
245         lapic_nmi->lint = lint;
246
247         return lapic_nmi->length;
248 }
249
250 static int acpi_create_madt_irq_overrides(u32 current)
251 {
252         struct acpi_madt_irqoverride *irqovr;
253         u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
254         int length = 0;
255
256         irqovr = (void *)current;
257         length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
258
259         irqovr = (void *)(current + length);
260         length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
261
262         return length;
263 }
264
265 __weak u32 acpi_fill_madt(u32 current)
266 {
267         current += acpi_create_madt_lapics(current);
268
269         current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
270                         io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
271
272         current += acpi_create_madt_irq_overrides(current);
273
274         return current;
275 }
276
277 static void acpi_create_madt(struct acpi_madt *madt)
278 {
279         struct acpi_table_header *header = &(madt->header);
280         u32 current = (u32)madt + sizeof(struct acpi_madt);
281
282         memset((void *)madt, 0, sizeof(struct acpi_madt));
283
284         /* Fill out header fields */
285         acpi_fill_header(header, "APIC");
286         header->length = sizeof(struct acpi_madt);
287         header->revision = 4;
288
289         madt->lapic_addr = LAPIC_DEFAULT_BASE;
290         madt->flags = ACPI_MADT_PCAT_COMPAT;
291
292         current = acpi_fill_madt(current);
293
294         /* (Re)calculate length and checksum */
295         header->length = current - (u32)madt;
296
297         header->checksum = table_compute_checksum((void *)madt, header->length);
298 }
299
300 int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
301                               u16 seg_nr, u8 start, u8 end)
302 {
303         memset(mmconfig, 0, sizeof(*mmconfig));
304         mmconfig->base_address_l = base;
305         mmconfig->base_address_h = 0;
306         mmconfig->pci_segment_group_number = seg_nr;
307         mmconfig->start_bus_number = start;
308         mmconfig->end_bus_number = end;
309
310         return sizeof(struct acpi_mcfg_mmconfig);
311 }
312
313 __weak u32 acpi_fill_mcfg(u32 current)
314 {
315         current += acpi_create_mcfg_mmconfig
316                 ((struct acpi_mcfg_mmconfig *)current,
317                 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
318
319         return current;
320 }
321
322 /* MCFG is defined in the PCI Firmware Specification 3.0 */
323 static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
324 {
325         struct acpi_table_header *header = &(mcfg->header);
326         u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
327
328         memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
329
330         /* Fill out header fields */
331         acpi_fill_header(header, "MCFG");
332         header->length = sizeof(struct acpi_mcfg);
333         header->revision = 1;
334
335         current = acpi_fill_mcfg(current);
336
337         /* (Re)calculate length and checksum */
338         header->length = current - (u32)mcfg;
339         header->checksum = table_compute_checksum((void *)mcfg, header->length);
340 }
341
342 void enter_acpi_mode(int pm1_cnt)
343 {
344         u16 val = inw(pm1_cnt);
345
346         /*
347          * PM1_CNT register bit0 selects the power management event to be
348          * either an SCI or SMI interrupt. When this bit is set, then power
349          * management events will generate an SCI interrupt. When this bit
350          * is reset power management events will generate an SMI interrupt.
351          *
352          * Per ACPI spec, it is the responsibility of the hardware to set
353          * or reset this bit. OSPM always preserves this bit position.
354          *
355          * U-Boot does not support SMI. And we don't have plan to support
356          * anything running in SMM within U-Boot. To create a legacy-free
357          * system, and expose ourselves to OSPM as working under ACPI mode
358          * already, turn this bit on.
359          */
360         outw(val | PM1_CNT_SCI_EN, pm1_cnt);
361 }
362
363 /*
364  * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
365  */
366 ulong write_acpi_tables(ulong start)
367 {
368         u32 current;
369         struct acpi_rsdp *rsdp;
370         struct acpi_rsdt *rsdt;
371         struct acpi_xsdt *xsdt;
372         struct acpi_facs *facs;
373         struct acpi_table_header *dsdt;
374         struct acpi_fadt *fadt;
375         struct acpi_mcfg *mcfg;
376         struct acpi_madt *madt;
377         int i;
378
379         current = start;
380
381         /* Align ACPI tables to 16 byte */
382         current = ALIGN(current, 16);
383
384         debug("ACPI: Writing ACPI tables at %lx\n", start);
385
386         /* We need at least an RSDP and an RSDT Table */
387         rsdp = (struct acpi_rsdp *)current;
388         current += sizeof(struct acpi_rsdp);
389         current = ALIGN(current, 16);
390         rsdt = (struct acpi_rsdt *)current;
391         current += sizeof(struct acpi_rsdt);
392         current = ALIGN(current, 16);
393         xsdt = (struct acpi_xsdt *)current;
394         current += sizeof(struct acpi_xsdt);
395         /*
396          * Per ACPI spec, the FACS table address must be aligned to a 64 byte
397          * boundary (Windows checks this, but Linux does not).
398          */
399         current = ALIGN(current, 64);
400
401         /* clear all table memory */
402         memset((void *)start, 0, current - start);
403
404         acpi_write_rsdp(rsdp, rsdt, xsdt);
405         acpi_write_rsdt(rsdt);
406         acpi_write_xsdt(xsdt);
407
408         debug("ACPI:    * FACS\n");
409         facs = (struct acpi_facs *)current;
410         current += sizeof(struct acpi_facs);
411         current = ALIGN(current, 16);
412
413         acpi_create_facs(facs);
414
415         debug("ACPI:    * DSDT\n");
416         dsdt = (struct acpi_table_header *)current;
417         memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
418         current += sizeof(struct acpi_table_header);
419         memcpy((char *)current,
420                (char *)&AmlCode + sizeof(struct acpi_table_header),
421                dsdt->length - sizeof(struct acpi_table_header));
422         current += dsdt->length - sizeof(struct acpi_table_header);
423         current = ALIGN(current, 16);
424
425         /* Pack GNVS into the ACPI table area */
426         for (i = 0; i < dsdt->length; i++) {
427                 u32 *gnvs = (u32 *)((u32)dsdt + i);
428                 if (*gnvs == ACPI_GNVS_ADDR) {
429                         debug("Fix up global NVS in DSDT to 0x%08x\n", current);
430                         *gnvs = current;
431                         break;
432                 }
433         }
434
435         /* Update DSDT checksum since we patched the GNVS address */
436         dsdt->checksum = 0;
437         dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
438
439         /* Fill in platform-specific global NVS variables */
440         acpi_create_gnvs((struct acpi_global_nvs *)current);
441         current += sizeof(struct acpi_global_nvs);
442         current = ALIGN(current, 16);
443
444         debug("ACPI:    * FADT\n");
445         fadt = (struct acpi_fadt *)current;
446         current += sizeof(struct acpi_fadt);
447         current = ALIGN(current, 16);
448         acpi_create_fadt(fadt, facs, dsdt);
449         acpi_add_table(rsdp, fadt);
450
451         debug("ACPI:    * MADT\n");
452         madt = (struct acpi_madt *)current;
453         acpi_create_madt(madt);
454         current += madt->header.length;
455         acpi_add_table(rsdp, madt);
456         current = ALIGN(current, 16);
457
458         debug("ACPI:    * MCFG\n");
459         mcfg = (struct acpi_mcfg *)current;
460         acpi_create_mcfg(mcfg);
461         current += mcfg->header.length;
462         acpi_add_table(rsdp, mcfg);
463         current = ALIGN(current, 16);
464
465         debug("current = %x\n", current);
466
467         acpi_rsdp_addr = (unsigned long)rsdp;
468         debug("ACPI: done\n");
469
470         /* Don't touch ACPI hardware on HW reduced platforms */
471         if (fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)
472                 return current;
473
474         /*
475          * Other than waiting for OSPM to request us to switch to ACPI mode,
476          * do it by ourselves, since SMI will not be triggered.
477          */
478         enter_acpi_mode(fadt->pm1a_cnt_blk);
479
480         return current;
481 }
482
483 static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp)
484 {
485         if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
486                 return NULL;
487
488         debug("Looking on %p for valid checksum\n", rsdp);
489
490         if (table_compute_checksum((void *)rsdp, 20) != 0)
491                 return NULL;
492         debug("acpi rsdp checksum 1 passed\n");
493
494         if ((rsdp->revision > 1) &&
495             (table_compute_checksum((void *)rsdp, rsdp->length) != 0))
496                 return NULL;
497         debug("acpi rsdp checksum 2 passed\n");
498
499         return rsdp;
500 }
501
502 struct acpi_fadt *acpi_find_fadt(void)
503 {
504         char *p, *end;
505         struct acpi_rsdp *rsdp = NULL;
506         struct acpi_rsdt *rsdt;
507         struct acpi_fadt *fadt = NULL;
508         int i;
509
510         /* Find RSDP */
511         for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) {
512                 rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p);
513                 if (rsdp)
514                         break;
515         }
516
517         if (rsdp == NULL)
518                 return NULL;
519
520         debug("RSDP found at %p\n", rsdp);
521         rsdt = (struct acpi_rsdt *)rsdp->rsdt_address;
522
523         end = (char *)rsdt + rsdt->header.length;
524         debug("RSDT found at %p ends at %p\n", rsdt, end);
525
526         for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) {
527                 fadt = (struct acpi_fadt *)rsdt->entry[i];
528                 if (strncmp((char *)fadt, "FACP", 4) == 0)
529                         break;
530                 fadt = NULL;
531         }
532
533         if (fadt == NULL)
534                 return NULL;
535
536         debug("FADT found at %p\n", fadt);
537         return fadt;
538 }
539
540 void *acpi_find_wakeup_vector(struct acpi_fadt *fadt)
541 {
542         struct acpi_facs *facs;
543         void *wake_vec;
544
545         debug("Trying to find the wakeup vector...\n");
546
547         facs = (struct acpi_facs *)fadt->firmware_ctrl;
548
549         if (facs == NULL) {
550                 debug("No FACS found, wake up from S3 not possible.\n");
551                 return NULL;
552         }
553
554         debug("FACS found at %p\n", facs);
555         wake_vec = (void *)facs->firmware_waking_vector;
556         debug("OS waking vector is %p\n", wake_vec);
557
558         return wake_vec;
559 }