Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / x86 / lib / acpi_table.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Based on acpi.c from coreboot
4  *
5  * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
6  * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
7  */
8
9 #include <common.h>
10 #include <cpu.h>
11 #include <dm.h>
12 #include <log.h>
13 #include <dm/uclass-internal.h>
14 #include <mapmem.h>
15 #include <serial.h>
16 #include <version.h>
17 #include <acpi/acpi_table.h>
18 #include <asm/acpi/global_nvs.h>
19 #include <asm/ioapic.h>
20 #include <asm/lapic.h>
21 #include <asm/mpspec.h>
22 #include <asm/tables.h>
23 #include <asm/arch/global_nvs.h>
24 #include <dm/acpi.h>
25
26 /*
27  * IASL compiles the dsdt entries and writes the hex values
28  * to a C array AmlCode[] (see dsdt.c).
29  */
30 extern const unsigned char AmlCode[];
31
32 /* ACPI RSDP address to be used in boot parameters */
33 static ulong acpi_rsdp_addr;
34
35 static void acpi_create_facs(struct acpi_facs *facs)
36 {
37         memset((void *)facs, 0, sizeof(struct acpi_facs));
38
39         memcpy(facs->signature, "FACS", 4);
40         facs->length = sizeof(struct acpi_facs);
41         facs->hardware_signature = 0;
42         facs->firmware_waking_vector = 0;
43         facs->global_lock = 0;
44         facs->flags = 0;
45         facs->x_firmware_waking_vector_l = 0;
46         facs->x_firmware_waking_vector_h = 0;
47         facs->version = 1;
48 }
49
50 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
51                                   u8 cpu, u8 apic)
52 {
53         lapic->type = ACPI_APIC_LAPIC;
54         lapic->length = sizeof(struct acpi_madt_lapic);
55         lapic->flags = LOCAL_APIC_FLAG_ENABLED;
56         lapic->processor_id = cpu;
57         lapic->apic_id = apic;
58
59         return lapic->length;
60 }
61
62 int acpi_create_madt_lapics(u32 current)
63 {
64         struct udevice *dev;
65         int total_length = 0;
66
67         for (uclass_find_first_device(UCLASS_CPU, &dev);
68              dev;
69              uclass_find_next_device(&dev)) {
70                 struct cpu_platdata *plat = dev_get_parent_platdata(dev);
71                 int length = acpi_create_madt_lapic(
72                                 (struct acpi_madt_lapic *)current,
73                                 plat->cpu_id, plat->cpu_id);
74                 current += length;
75                 total_length += length;
76         }
77
78         return total_length;
79 }
80
81 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
82                             u32 addr, u32 gsi_base)
83 {
84         ioapic->type = ACPI_APIC_IOAPIC;
85         ioapic->length = sizeof(struct acpi_madt_ioapic);
86         ioapic->reserved = 0x00;
87         ioapic->gsi_base = gsi_base;
88         ioapic->ioapic_id = id;
89         ioapic->ioapic_addr = addr;
90
91         return ioapic->length;
92 }
93
94 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
95                                  u8 bus, u8 source, u32 gsirq, u16 flags)
96 {
97         irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE;
98         irqoverride->length = sizeof(struct acpi_madt_irqoverride);
99         irqoverride->bus = bus;
100         irqoverride->source = source;
101         irqoverride->gsirq = gsirq;
102         irqoverride->flags = flags;
103
104         return irqoverride->length;
105 }
106
107 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
108                                u8 cpu, u16 flags, u8 lint)
109 {
110         lapic_nmi->type = ACPI_APIC_LAPIC_NMI;
111         lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
112         lapic_nmi->flags = flags;
113         lapic_nmi->processor_id = cpu;
114         lapic_nmi->lint = lint;
115
116         return lapic_nmi->length;
117 }
118
119 static int acpi_create_madt_irq_overrides(u32 current)
120 {
121         struct acpi_madt_irqoverride *irqovr;
122         u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
123         int length = 0;
124
125         irqovr = (void *)current;
126         length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
127
128         irqovr = (void *)(current + length);
129         length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags);
130
131         return length;
132 }
133
134 __weak u32 acpi_fill_madt(u32 current)
135 {
136         current += acpi_create_madt_lapics(current);
137
138         current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
139                         io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
140
141         current += acpi_create_madt_irq_overrides(current);
142
143         return current;
144 }
145
146 static void acpi_create_madt(struct acpi_madt *madt)
147 {
148         struct acpi_table_header *header = &(madt->header);
149         u32 current = (u32)madt + sizeof(struct acpi_madt);
150
151         memset((void *)madt, 0, sizeof(struct acpi_madt));
152
153         /* Fill out header fields */
154         acpi_fill_header(header, "APIC");
155         header->length = sizeof(struct acpi_madt);
156         header->revision = 4;
157
158         madt->lapic_addr = LAPIC_DEFAULT_BASE;
159         madt->flags = ACPI_MADT_PCAT_COMPAT;
160
161         current = acpi_fill_madt(current);
162
163         /* (Re)calculate length and checksum */
164         header->length = current - (u32)madt;
165
166         header->checksum = table_compute_checksum((void *)madt, header->length);
167 }
168
169 int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
170                               u16 seg_nr, u8 start, u8 end)
171 {
172         memset(mmconfig, 0, sizeof(*mmconfig));
173         mmconfig->base_address_l = base;
174         mmconfig->base_address_h = 0;
175         mmconfig->pci_segment_group_number = seg_nr;
176         mmconfig->start_bus_number = start;
177         mmconfig->end_bus_number = end;
178
179         return sizeof(struct acpi_mcfg_mmconfig);
180 }
181
182 __weak u32 acpi_fill_mcfg(u32 current)
183 {
184         current += acpi_create_mcfg_mmconfig
185                 ((struct acpi_mcfg_mmconfig *)current,
186                 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
187
188         return current;
189 }
190
191 /* MCFG is defined in the PCI Firmware Specification 3.0 */
192 static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
193 {
194         struct acpi_table_header *header = &(mcfg->header);
195         u32 current = (u32)mcfg + sizeof(struct acpi_mcfg);
196
197         memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
198
199         /* Fill out header fields */
200         acpi_fill_header(header, "MCFG");
201         header->length = sizeof(struct acpi_mcfg);
202         header->revision = 1;
203
204         current = acpi_fill_mcfg(current);
205
206         /* (Re)calculate length and checksum */
207         header->length = current - (u32)mcfg;
208         header->checksum = table_compute_checksum((void *)mcfg, header->length);
209 }
210
211 __weak u32 acpi_fill_csrt(u32 current)
212 {
213         return current;
214 }
215
216 static void acpi_create_csrt(struct acpi_csrt *csrt)
217 {
218         struct acpi_table_header *header = &(csrt->header);
219         u32 current = (u32)csrt + sizeof(struct acpi_csrt);
220
221         memset((void *)csrt, 0, sizeof(struct acpi_csrt));
222
223         /* Fill out header fields */
224         acpi_fill_header(header, "CSRT");
225         header->length = sizeof(struct acpi_csrt);
226         header->revision = 0;
227
228         current = acpi_fill_csrt(current);
229
230         /* (Re)calculate length and checksum */
231         header->length = current - (u32)csrt;
232         header->checksum = table_compute_checksum((void *)csrt, header->length);
233 }
234
235 static void acpi_create_spcr(struct acpi_spcr *spcr)
236 {
237         struct acpi_table_header *header = &(spcr->header);
238         struct serial_device_info serial_info = {0};
239         ulong serial_address, serial_offset;
240         struct udevice *dev;
241         uint serial_config;
242         uint serial_width;
243         int access_size;
244         int space_id;
245         int ret = -ENODEV;
246
247         /* Fill out header fields */
248         acpi_fill_header(header, "SPCR");
249         header->length = sizeof(struct acpi_spcr);
250         header->revision = 2;
251
252         /* Read the device once, here. It is reused below */
253         dev = gd->cur_serial_dev;
254         if (dev)
255                 ret = serial_getinfo(dev, &serial_info);
256         if (ret)
257                 serial_info.type = SERIAL_CHIP_UNKNOWN;
258
259         /* Encode chip type */
260         switch (serial_info.type) {
261         case SERIAL_CHIP_16550_COMPATIBLE:
262                 spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE;
263                 break;
264         case SERIAL_CHIP_UNKNOWN:
265         default:
266                 spcr->interface_type = ACPI_DBG2_UNKNOWN;
267                 break;
268         }
269
270         /* Encode address space */
271         switch (serial_info.addr_space) {
272         case SERIAL_ADDRESS_SPACE_MEMORY:
273                 space_id = ACPI_ADDRESS_SPACE_MEMORY;
274                 break;
275         case SERIAL_ADDRESS_SPACE_IO:
276         default:
277                 space_id = ACPI_ADDRESS_SPACE_IO;
278                 break;
279         }
280
281         serial_width = serial_info.reg_width * 8;
282         serial_offset = serial_info.reg_offset << serial_info.reg_shift;
283         serial_address = serial_info.addr + serial_offset;
284
285         /* Encode register access size */
286         switch (serial_info.reg_shift) {
287         case 0:
288                 access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
289                 break;
290         case 1:
291                 access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
292                 break;
293         case 2:
294                 access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
295                 break;
296         case 3:
297                 access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
298                 break;
299         default:
300                 access_size = ACPI_ACCESS_SIZE_UNDEFINED;
301                 break;
302         }
303
304         debug("UART type %u @ %lx\n", spcr->interface_type, serial_address);
305
306         /* Fill GAS */
307         spcr->serial_port.space_id = space_id;
308         spcr->serial_port.bit_width = serial_width;
309         spcr->serial_port.bit_offset = 0;
310         spcr->serial_port.access_size = access_size;
311         spcr->serial_port.addrl = lower_32_bits(serial_address);
312         spcr->serial_port.addrh = upper_32_bits(serial_address);
313
314         /* Encode baud rate */
315         switch (serial_info.baudrate) {
316         case 9600:
317                 spcr->baud_rate = 3;
318                 break;
319         case 19200:
320                 spcr->baud_rate = 4;
321                 break;
322         case 57600:
323                 spcr->baud_rate = 6;
324                 break;
325         case 115200:
326                 spcr->baud_rate = 7;
327                 break;
328         default:
329                 spcr->baud_rate = 0;
330                 break;
331         }
332
333         serial_config = SERIAL_DEFAULT_CONFIG;
334         if (dev)
335                 ret = serial_getconfig(dev, &serial_config);
336
337         spcr->parity = SERIAL_GET_PARITY(serial_config);
338         spcr->stop_bits = SERIAL_GET_STOP(serial_config);
339
340         /* No PCI devices for now */
341         spcr->pci_device_id = 0xffff;
342         spcr->pci_vendor_id = 0xffff;
343
344         /*
345          * SPCR has no clue if the UART base clock speed is different
346          * to the default one. However, the SPCR 1.04 defines baud rate
347          * 0 as a preconfigured state of UART and OS is supposed not
348          * to touch the configuration of the serial device.
349          */
350         if (serial_info.clock != SERIAL_DEFAULT_CLOCK)
351                 spcr->baud_rate = 0;
352
353         /* Fix checksum */
354         header->checksum = table_compute_checksum((void *)spcr, header->length);
355 }
356
357 /*
358  * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
359  */
360 ulong write_acpi_tables(ulong start_addr)
361 {
362         struct acpi_ctx sctx, *ctx = &sctx;
363         struct acpi_facs *facs;
364         struct acpi_table_header *dsdt;
365         struct acpi_fadt *fadt;
366         struct acpi_mcfg *mcfg;
367         struct acpi_madt *madt;
368         struct acpi_csrt *csrt;
369         struct acpi_spcr *spcr;
370         void *start;
371         ulong addr;
372         int i;
373
374         start = map_sysmem(start_addr, 0);
375
376         debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
377
378         acpi_setup_base_tables(ctx, start);
379
380         debug("ACPI:    * FACS\n");
381         facs = ctx->current;
382         acpi_inc_align(ctx, sizeof(struct acpi_facs));
383
384         acpi_create_facs(facs);
385
386         debug("ACPI:    * DSDT\n");
387         dsdt = ctx->current;
388         memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
389         acpi_inc(ctx, sizeof(struct acpi_table_header));
390         memcpy(ctx->current,
391                (char *)&AmlCode + sizeof(struct acpi_table_header),
392                dsdt->length - sizeof(struct acpi_table_header));
393         acpi_inc_align(ctx, dsdt->length - sizeof(struct acpi_table_header));
394
395         /* Pack GNVS into the ACPI table area */
396         for (i = 0; i < dsdt->length; i++) {
397                 u32 *gnvs = (u32 *)((u32)dsdt + i);
398                 if (*gnvs == ACPI_GNVS_ADDR) {
399                         ulong addr = (ulong)map_to_sysmem(ctx->current);
400
401                         debug("Fix up global NVS in DSDT to %#08lx\n", addr);
402                         *gnvs = addr;
403                         break;
404                 }
405         }
406
407         /* Update DSDT checksum since we patched the GNVS address */
408         dsdt->checksum = 0;
409         dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
410
411         /* Fill in platform-specific global NVS variables */
412         acpi_create_gnvs(ctx->current);
413         acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
414
415         debug("ACPI:    * FADT\n");
416         fadt = ctx->current;
417         acpi_inc_align(ctx, sizeof(struct acpi_fadt));
418         acpi_create_fadt(fadt, facs, dsdt);
419         acpi_add_table(ctx, fadt);
420
421         debug("ACPI:    * MADT\n");
422         madt = ctx->current;
423         acpi_create_madt(madt);
424         acpi_inc_align(ctx, madt->header.length);
425         acpi_add_table(ctx, madt);
426
427         debug("ACPI:    * MCFG\n");
428         mcfg = ctx->current;
429         acpi_create_mcfg(mcfg);
430         acpi_inc_align(ctx, mcfg->header.length);
431         acpi_add_table(ctx, mcfg);
432
433         debug("ACPI:    * CSRT\n");
434         csrt = ctx->current;
435         acpi_create_csrt(csrt);
436         acpi_inc_align(ctx, csrt->header.length);
437         acpi_add_table(ctx, csrt);
438
439         debug("ACPI:    * SPCR\n");
440         spcr = ctx->current;
441         acpi_create_spcr(spcr);
442         acpi_inc_align(ctx, spcr->header.length);
443         acpi_add_table(ctx, spcr);
444
445         acpi_write_dev_tables(ctx);
446
447         addr = map_to_sysmem(ctx->current);
448         debug("current = %lx\n", addr);
449
450         acpi_rsdp_addr = (unsigned long)ctx->rsdp;
451         debug("ACPI: done\n");
452
453         return addr;
454 }
455
456 ulong acpi_get_rsdp_addr(void)
457 {
458         return acpi_rsdp_addr;
459 }