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