1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2017 Intel Corporation 4 * 5 * Partially based on acpi.c for other x86 platforms 6 */ 7 8 #include <common.h> 9 #include <cpu.h> 10 #include <dm.h> 11 #include <dm/uclass-internal.h> 12 #include <asm/acpi_table.h> 13 #include <asm/ioapic.h> 14 #include <asm/mpspec.h> 15 #include <asm/tables.h> 16 #include <asm/arch/global_nvs.h> 17 18 void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, 19 void *dsdt) 20 { 21 struct acpi_table_header *header = &(fadt->header); 22 23 memset((void *)fadt, 0, sizeof(struct acpi_fadt)); 24 25 acpi_fill_header(header, "FACP"); 26 header->length = sizeof(struct acpi_fadt); 27 header->revision = 6; 28 29 fadt->firmware_ctrl = (u32)facs; 30 fadt->dsdt = (u32)dsdt; 31 fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED; 32 33 fadt->iapc_boot_arch = ACPI_FADT_VGA_NOT_PRESENT | 34 ACPI_FADT_NO_PCIE_ASPM_CONTROL; 35 fadt->flags = 36 ACPI_FADT_WBINVD | 37 ACPI_FADT_POWER_BUTTON | ACPI_FADT_SLEEP_BUTTON | 38 ACPI_FADT_SEALED_CASE | ACPI_FADT_HEADLESS | 39 ACPI_FADT_HW_REDUCED_ACPI; 40 41 fadt->minor_revision = 2; 42 43 fadt->x_firmware_ctl_l = (u32)facs; 44 fadt->x_firmware_ctl_h = 0; 45 fadt->x_dsdt_l = (u32)dsdt; 46 fadt->x_dsdt_h = 0; 47 48 header->checksum = table_compute_checksum(fadt, header->length); 49 } 50 51 u32 acpi_fill_madt(u32 current) 52 { 53 current += acpi_create_madt_lapics(current); 54 55 current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current, 56 io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0); 57 58 return current; 59 } 60 61 u32 acpi_fill_mcfg(u32 current) 62 { 63 /* TODO: Derive parameters from SFI MCFG table */ 64 current += acpi_create_mcfg_mmconfig 65 ((struct acpi_mcfg_mmconfig *)current, 66 0x3f500000, 0x0, 0x0, 0x0); 67 68 return current; 69 } 70 71 void acpi_create_gnvs(struct acpi_global_nvs *gnvs) 72 { 73 struct udevice *dev; 74 int ret; 75 76 /* at least we have one processor */ 77 gnvs->pcnt = 1; 78 79 /* override the processor count with actual number */ 80 ret = uclass_find_first_device(UCLASS_CPU, &dev); 81 if (ret == 0 && dev != NULL) { 82 ret = cpu_get_count(dev); 83 if (ret > 0) 84 gnvs->pcnt = ret; 85 } 86 } 87