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