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