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 <asm/acpi_table.h> 15 #include <asm/lapic.h> 16 #include <asm/tables.h> 17 18 /* 19 * IASL compiles the dsdt entries and writes the hex values 20 * to a C array AmlCode[] (see dsdt.c). 21 */ 22 extern const unsigned char AmlCode[]; 23 24 static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, 25 struct acpi_xsdt *xsdt) 26 { 27 memset(rsdp, 0, sizeof(struct acpi_rsdp)); 28 29 memcpy(rsdp->signature, RSDP_SIG, 8); 30 memcpy(rsdp->oem_id, OEM_ID, 6); 31 32 rsdp->length = sizeof(struct acpi_rsdp); 33 rsdp->rsdt_address = (u32)rsdt; 34 35 /* 36 * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2 37 * 38 * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2. 39 * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR 40 * revision 0) 41 */ 42 if (xsdt == NULL) { 43 rsdp->revision = ACPI_RSDP_REV_ACPI_1_0; 44 } else { 45 rsdp->xsdt_address = (u64)(u32)xsdt; 46 rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; 47 } 48 49 /* Calculate checksums */ 50 rsdp->checksum = table_compute_checksum((void *)rsdp, 20); 51 rsdp->ext_checksum = table_compute_checksum((void *)rsdp, 52 sizeof(struct acpi_rsdp)); 53 } 54 55 void acpi_fill_header(struct acpi_table_header *header, char *signature) 56 { 57 memcpy(header->signature, signature, 4); 58 memcpy(header->oem_id, OEM_ID, 6); 59 memcpy(header->oem_table_id, OEM_TABLE_ID, 8); 60 memcpy(header->aslc_id, ASLC_ID, 4); 61 } 62 63 static void acpi_write_rsdt(struct acpi_rsdt *rsdt) 64 { 65 struct acpi_table_header *header = &(rsdt->header); 66 67 /* Fill out header fields */ 68 acpi_fill_header(header, "RSDT"); 69 header->length = sizeof(struct acpi_rsdt); 70 header->revision = 1; 71 72 /* Entries are filled in later, we come with an empty set */ 73 74 /* Fix checksum */ 75 header->checksum = table_compute_checksum((void *)rsdt, 76 sizeof(struct acpi_rsdt)); 77 } 78 79 static void acpi_write_xsdt(struct acpi_xsdt *xsdt) 80 { 81 struct acpi_table_header *header = &(xsdt->header); 82 83 /* Fill out header fields */ 84 acpi_fill_header(header, "XSDT"); 85 header->length = sizeof(struct acpi_xsdt); 86 header->revision = 1; 87 88 /* Entries are filled in later, we come with an empty set */ 89 90 /* Fix checksum */ 91 header->checksum = table_compute_checksum((void *)xsdt, 92 sizeof(struct acpi_xsdt)); 93 } 94 95 /** 96 * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length 97 * and checksum. 98 */ 99 static void acpi_add_table(struct acpi_rsdp *rsdp, void *table) 100 { 101 int i, entries_num; 102 struct acpi_rsdt *rsdt; 103 struct acpi_xsdt *xsdt = NULL; 104 105 /* The RSDT is mandatory while the XSDT is not */ 106 rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; 107 108 if (rsdp->xsdt_address) 109 xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address); 110 111 /* This should always be MAX_ACPI_TABLES */ 112 entries_num = ARRAY_SIZE(rsdt->entry); 113 114 for (i = 0; i < entries_num; i++) { 115 if (rsdt->entry[i] == 0) 116 break; 117 } 118 119 if (i >= entries_num) { 120 debug("ACPI: Error: too many tables\n"); 121 return; 122 } 123 124 /* Add table to the RSDT */ 125 rsdt->entry[i] = (u32)table; 126 127 /* Fix RSDT length or the kernel will assume invalid entries */ 128 rsdt->header.length = sizeof(struct acpi_table_header) + 129 (sizeof(u32) * (i + 1)); 130 131 /* Re-calculate checksum */ 132 rsdt->header.checksum = 0; 133 rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, 134 rsdt->header.length); 135 136 /* 137 * And now the same thing for the XSDT. We use the same index as for 138 * now we want the XSDT and RSDT to always be in sync in U-Boot 139 */ 140 if (xsdt) { 141 /* Add table to the XSDT */ 142 xsdt->entry[i] = (u64)(u32)table; 143 144 /* Fix XSDT length */ 145 xsdt->header.length = sizeof(struct acpi_table_header) + 146 (sizeof(u64) * (i + 1)); 147 148 /* Re-calculate checksum */ 149 xsdt->header.checksum = 0; 150 xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, 151 xsdt->header.length); 152 } 153 } 154 155 static void acpi_create_facs(struct acpi_facs *facs) 156 { 157 memset((void *)facs, 0, sizeof(struct acpi_facs)); 158 159 memcpy(facs->signature, "FACS", 4); 160 facs->length = sizeof(struct acpi_facs); 161 facs->hardware_signature = 0; 162 facs->firmware_waking_vector = 0; 163 facs->global_lock = 0; 164 facs->flags = 0; 165 facs->x_firmware_waking_vector_l = 0; 166 facs->x_firmware_waking_vector_h = 0; 167 facs->version = 1; 168 } 169 170 static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, 171 u8 cpu, u8 apic) 172 { 173 lapic->type = ACPI_APIC_LAPIC; 174 lapic->length = sizeof(struct acpi_madt_lapic); 175 lapic->flags = LOCAL_APIC_FLAG_ENABLED; 176 lapic->processor_id = cpu; 177 lapic->apic_id = apic; 178 179 return lapic->length; 180 } 181 182 u32 acpi_create_madt_lapics(u32 current) 183 { 184 struct udevice *dev; 185 186 for (uclass_find_first_device(UCLASS_CPU, &dev); 187 dev; 188 uclass_find_next_device(&dev)) { 189 struct cpu_platdata *plat = dev_get_parent_platdata(dev); 190 191 current += acpi_create_madt_lapic( 192 (struct acpi_madt_lapic *)current, 193 plat->cpu_id, plat->cpu_id); 194 } 195 196 return current; 197 } 198 199 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, 200 u32 addr, u32 gsi_base) 201 { 202 ioapic->type = ACPI_APIC_IOAPIC; 203 ioapic->length = sizeof(struct acpi_madt_ioapic); 204 ioapic->reserved = 0x00; 205 ioapic->gsi_base = gsi_base; 206 ioapic->ioapic_id = id; 207 ioapic->ioapic_addr = addr; 208 209 return ioapic->length; 210 } 211 212 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, 213 u8 bus, u8 source, u32 gsirq, u16 flags) 214 { 215 irqoverride->type = ACPI_APIC_IRQ_SRC_OVERRIDE; 216 irqoverride->length = sizeof(struct acpi_madt_irqoverride); 217 irqoverride->bus = bus; 218 irqoverride->source = source; 219 irqoverride->gsirq = gsirq; 220 irqoverride->flags = flags; 221 222 return irqoverride->length; 223 } 224 225 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, 226 u8 cpu, u16 flags, u8 lint) 227 { 228 lapic_nmi->type = ACPI_APIC_LAPIC_NMI; 229 lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi); 230 lapic_nmi->flags = flags; 231 lapic_nmi->processor_id = cpu; 232 lapic_nmi->lint = lint; 233 234 return lapic_nmi->length; 235 } 236 237 static void acpi_create_madt(struct acpi_madt *madt) 238 { 239 struct acpi_table_header *header = &(madt->header); 240 u32 current = (u32)madt + sizeof(struct acpi_madt); 241 242 memset((void *)madt, 0, sizeof(struct acpi_madt)); 243 244 /* Fill out header fields */ 245 acpi_fill_header(header, "APIC"); 246 header->length = sizeof(struct acpi_madt); 247 header->revision = 4; 248 249 madt->lapic_addr = LAPIC_DEFAULT_BASE; 250 madt->flags = ACPI_MADT_PCAT_COMPAT; 251 252 current = acpi_fill_madt(current); 253 254 /* (Re)calculate length and checksum */ 255 header->length = current - (u32)madt; 256 257 header->checksum = table_compute_checksum((void *)madt, header->length); 258 } 259 260 static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, 261 u32 base, u16 seg_nr, u8 start, u8 end) 262 { 263 memset(mmconfig, 0, sizeof(*mmconfig)); 264 mmconfig->base_address_l = base; 265 mmconfig->base_address_h = 0; 266 mmconfig->pci_segment_group_number = seg_nr; 267 mmconfig->start_bus_number = start; 268 mmconfig->end_bus_number = end; 269 270 return sizeof(struct acpi_mcfg_mmconfig); 271 } 272 273 static u32 acpi_fill_mcfg(u32 current) 274 { 275 current += acpi_create_mcfg_mmconfig 276 ((struct acpi_mcfg_mmconfig *)current, 277 CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255); 278 279 return current; 280 } 281 282 /* MCFG is defined in the PCI Firmware Specification 3.0 */ 283 static void acpi_create_mcfg(struct acpi_mcfg *mcfg) 284 { 285 struct acpi_table_header *header = &(mcfg->header); 286 u32 current = (u32)mcfg + sizeof(struct acpi_mcfg); 287 288 memset((void *)mcfg, 0, sizeof(struct acpi_mcfg)); 289 290 /* Fill out header fields */ 291 acpi_fill_header(header, "MCFG"); 292 header->length = sizeof(struct acpi_mcfg); 293 header->revision = 1; 294 295 current = acpi_fill_mcfg(current); 296 297 /* (Re)calculate length and checksum */ 298 header->length = current - (u32)mcfg; 299 header->checksum = table_compute_checksum((void *)mcfg, header->length); 300 } 301 302 /* 303 * QEMU's version of write_acpi_tables is defined in 304 * arch/x86/cpu/qemu/fw_cfg.c 305 */ 306 u32 write_acpi_tables(u32 start) 307 { 308 u32 current; 309 struct acpi_rsdp *rsdp; 310 struct acpi_rsdt *rsdt; 311 struct acpi_xsdt *xsdt; 312 struct acpi_facs *facs; 313 struct acpi_table_header *dsdt; 314 struct acpi_fadt *fadt; 315 struct acpi_mcfg *mcfg; 316 struct acpi_madt *madt; 317 318 current = start; 319 320 /* Align ACPI tables to 16 byte */ 321 current = ALIGN(current, 16); 322 323 debug("ACPI: Writing ACPI tables at %x\n", start); 324 325 /* We need at least an RSDP and an RSDT Table */ 326 rsdp = (struct acpi_rsdp *)current; 327 current += sizeof(struct acpi_rsdp); 328 current = ALIGN(current, 16); 329 rsdt = (struct acpi_rsdt *)current; 330 current += sizeof(struct acpi_rsdt); 331 current = ALIGN(current, 16); 332 xsdt = (struct acpi_xsdt *)current; 333 current += sizeof(struct acpi_xsdt); 334 /* 335 * Per ACPI spec, the FACS table address must be aligned to a 64 byte 336 * boundary (Windows checks this, but Linux does not). 337 */ 338 current = ALIGN(current, 64); 339 340 /* clear all table memory */ 341 memset((void *)start, 0, current - start); 342 343 acpi_write_rsdp(rsdp, rsdt, xsdt); 344 acpi_write_rsdt(rsdt); 345 acpi_write_xsdt(xsdt); 346 347 debug("ACPI: * FACS\n"); 348 facs = (struct acpi_facs *)current; 349 current += sizeof(struct acpi_facs); 350 current = ALIGN(current, 16); 351 352 acpi_create_facs(facs); 353 354 debug("ACPI: * DSDT\n"); 355 dsdt = (struct acpi_table_header *)current; 356 memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); 357 if (dsdt->length >= sizeof(struct acpi_table_header)) { 358 current += sizeof(struct acpi_table_header); 359 memcpy((char *)current, 360 (char *)&AmlCode + sizeof(struct acpi_table_header), 361 dsdt->length - sizeof(struct acpi_table_header)); 362 current += dsdt->length - sizeof(struct acpi_table_header); 363 364 /* (Re)calculate length and checksum */ 365 dsdt->length = current - (u32)dsdt; 366 dsdt->checksum = 0; 367 dsdt->checksum = table_compute_checksum((void *)dsdt, 368 dsdt->length); 369 } 370 current = ALIGN(current, 16); 371 372 debug("ACPI: * FADT\n"); 373 fadt = (struct acpi_fadt *)current; 374 current += sizeof(struct acpi_fadt); 375 current = ALIGN(current, 16); 376 acpi_create_fadt(fadt, facs, dsdt); 377 acpi_add_table(rsdp, fadt); 378 379 debug("ACPI: * MADT\n"); 380 madt = (struct acpi_madt *)current; 381 acpi_create_madt(madt); 382 if (madt->header.length > sizeof(struct acpi_madt)) { 383 current += madt->header.length; 384 acpi_add_table(rsdp, madt); 385 } 386 current = ALIGN(current, 16); 387 388 debug("ACPI: * MCFG\n"); 389 mcfg = (struct acpi_mcfg *)current; 390 acpi_create_mcfg(mcfg); 391 if (mcfg->header.length > sizeof(struct acpi_mcfg)) { 392 current += mcfg->header.length; 393 current = ALIGN(current, 16); 394 acpi_add_table(rsdp, mcfg); 395 } 396 397 debug("current = %x\n", current); 398 399 debug("ACPI: done\n"); 400 401 return current; 402 } 403