|
|
1.1 ! root 1: // Support for generating ACPI tables (on emulators) ! 2: // ! 3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]> ! 4: // Copyright (C) 2006 Fabrice Bellard ! 5: // ! 6: // This file may be distributed under the terms of the GNU LGPLv3 license. ! 7: ! 8: #include "acpi.h" // struct rsdp_descriptor ! 9: #include "util.h" // memcpy ! 10: #include "pci.h" // pci_find_device ! 11: #include "biosvar.h" // GET_EBDA ! 12: #include "pci_ids.h" // PCI_VENDOR_ID_INTEL ! 13: #include "pci_regs.h" // PCI_INTERRUPT_LINE ! 14: #include "paravirt.h" ! 15: ! 16: /****************************************************/ ! 17: /* ACPI tables init */ ! 18: ! 19: /* Table structure from Linux kernel (the ACPI tables are under the ! 20: BSD license) */ ! 21: ! 22: #define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ ! 23: u32 signature; /* ACPI signature (4 ASCII characters) */ \ ! 24: u32 length; /* Length of table, in bytes, including header */ \ ! 25: u8 revision; /* ACPI Specification minor version # */ \ ! 26: u8 checksum; /* To make sum of entire table == 0 */ \ ! 27: u8 oem_id [6]; /* OEM identification */ \ ! 28: u8 oem_table_id [8]; /* OEM table identification */ \ ! 29: u32 oem_revision; /* OEM revision number */ \ ! 30: u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \ ! 31: u32 asl_compiler_revision; /* ASL compiler revision number */ ! 32: ! 33: ! 34: struct acpi_table_header /* ACPI common table header */ ! 35: { ! 36: ACPI_TABLE_HEADER_DEF ! 37: } PACKED; ! 38: ! 39: /* ! 40: * ACPI 1.0 Root System Description Table (RSDT) ! 41: */ ! 42: #define RSDT_SIGNATURE 0x54445352 // RSDT ! 43: struct rsdt_descriptor_rev1 ! 44: { ! 45: ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ! 46: u32 table_offset_entry[0]; /* Array of pointers to other */ ! 47: /* ACPI tables */ ! 48: } PACKED; ! 49: ! 50: /* ! 51: * ACPI 1.0 Firmware ACPI Control Structure (FACS) ! 52: */ ! 53: #define FACS_SIGNATURE 0x53434146 // FACS ! 54: struct facs_descriptor_rev1 ! 55: { ! 56: u32 signature; /* ACPI Signature */ ! 57: u32 length; /* Length of structure, in bytes */ ! 58: u32 hardware_signature; /* Hardware configuration signature */ ! 59: u32 firmware_waking_vector; /* ACPI OS waking vector */ ! 60: u32 global_lock; /* Global Lock */ ! 61: u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ ! 62: u32 reserved1 : 31; /* Must be 0 */ ! 63: u8 resverved3 [40]; /* Reserved - must be zero */ ! 64: } PACKED; ! 65: ! 66: ! 67: /* ! 68: * ACPI 1.0 Fixed ACPI Description Table (FADT) ! 69: */ ! 70: #define FACP_SIGNATURE 0x50434146 // FACP ! 71: struct fadt_descriptor_rev1 ! 72: { ! 73: ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ! 74: u32 firmware_ctrl; /* Physical address of FACS */ ! 75: u32 dsdt; /* Physical address of DSDT */ ! 76: u8 model; /* System Interrupt Model */ ! 77: u8 reserved1; /* Reserved */ ! 78: u16 sci_int; /* System vector of SCI interrupt */ ! 79: u32 smi_cmd; /* Port address of SMI command port */ ! 80: u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ ! 81: u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ ! 82: u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ ! 83: u8 reserved2; /* Reserved - must be zero */ ! 84: u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ ! 85: u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ ! 86: u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ ! 87: u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ ! 88: u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ ! 89: u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ ! 90: u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ ! 91: u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ ! 92: u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ ! 93: u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ ! 94: u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ ! 95: u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ ! 96: u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ ! 97: u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ ! 98: u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ ! 99: u8 reserved3; /* Reserved */ ! 100: u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ ! 101: u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ ! 102: u16 flush_size; /* Size of area read to flush caches */ ! 103: u16 flush_stride; /* Stride used in flushing caches */ ! 104: u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */ ! 105: u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */ ! 106: u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ ! 107: u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ ! 108: u8 century; /* Index to century in RTC CMOS RAM */ ! 109: u8 reserved4; /* Reserved */ ! 110: u8 reserved4a; /* Reserved */ ! 111: u8 reserved4b; /* Reserved */ ! 112: #if 0 ! 113: u32 wb_invd : 1; /* The wbinvd instruction works properly */ ! 114: u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ ! 115: u32 proc_c1 : 1; /* All processors support C1 state */ ! 116: u32 plvl2_up : 1; /* C2 state works on MP system */ ! 117: u32 pwr_button : 1; /* Power button is handled as a generic feature */ ! 118: u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ ! 119: u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ ! 120: u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ ! 121: u32 tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ ! 122: u32 reserved5 : 23; /* Reserved - must be zero */ ! 123: #else ! 124: u32 flags; ! 125: #endif ! 126: } PACKED; ! 127: ! 128: /* ! 129: * MADT values and structures ! 130: */ ! 131: ! 132: /* Values for MADT PCATCompat */ ! 133: ! 134: #define DUAL_PIC 0 ! 135: #define MULTIPLE_APIC 1 ! 136: ! 137: ! 138: /* Master MADT */ ! 139: ! 140: #define APIC_SIGNATURE 0x43495041 // APIC ! 141: struct multiple_apic_table ! 142: { ! 143: ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ! 144: u32 local_apic_address; /* Physical address of local APIC */ ! 145: #if 0 ! 146: u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */ ! 147: u32 reserved1 : 31; ! 148: #else ! 149: u32 flags; ! 150: #endif ! 151: } PACKED; ! 152: ! 153: ! 154: /* Values for Type in APIC sub-headers */ ! 155: ! 156: #define APIC_PROCESSOR 0 ! 157: #define APIC_IO 1 ! 158: #define APIC_XRUPT_OVERRIDE 2 ! 159: #define APIC_NMI 3 ! 160: #define APIC_LOCAL_NMI 4 ! 161: #define APIC_ADDRESS_OVERRIDE 5 ! 162: #define APIC_IO_SAPIC 6 ! 163: #define APIC_LOCAL_SAPIC 7 ! 164: #define APIC_XRUPT_SOURCE 8 ! 165: #define APIC_RESERVED 9 /* 9 and greater are reserved */ ! 166: ! 167: /* ! 168: * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) ! 169: */ ! 170: #define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\ ! 171: u8 type; \ ! 172: u8 length; ! 173: ! 174: /* Sub-structures for MADT */ ! 175: ! 176: struct madt_processor_apic ! 177: { ! 178: ACPI_SUB_HEADER_DEF ! 179: u8 processor_id; /* ACPI processor id */ ! 180: u8 local_apic_id; /* Processor's local APIC id */ ! 181: #if 0 ! 182: u32 processor_enabled: 1; /* Processor is usable if set */ ! 183: u32 reserved2 : 31; /* Reserved, must be zero */ ! 184: #else ! 185: u32 flags; ! 186: #endif ! 187: } PACKED; ! 188: ! 189: struct madt_io_apic ! 190: { ! 191: ACPI_SUB_HEADER_DEF ! 192: u8 io_apic_id; /* I/O APIC ID */ ! 193: u8 reserved; /* Reserved - must be zero */ ! 194: u32 address; /* APIC physical address */ ! 195: u32 interrupt; /* Global system interrupt where INTI ! 196: * lines start */ ! 197: } PACKED; ! 198: ! 199: /* IRQs 5,9,10,11 */ ! 200: #define PCI_ISA_IRQ_MASK 0x0e20 ! 201: ! 202: struct madt_intsrcovr { ! 203: ACPI_SUB_HEADER_DEF ! 204: u8 bus; ! 205: u8 source; ! 206: u32 gsi; ! 207: u16 flags; ! 208: } PACKED; ! 209: ! 210: /* ! 211: * ACPI 2.0 Generic Address Space definition. ! 212: */ ! 213: struct acpi_20_generic_address { ! 214: u8 address_space_id; ! 215: u8 register_bit_width; ! 216: u8 register_bit_offset; ! 217: u8 reserved; ! 218: u64 address; ! 219: } PACKED; ! 220: ! 221: /* ! 222: * HPET Description Table ! 223: */ ! 224: struct acpi_20_hpet { ! 225: ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ! 226: u32 timer_block_id; ! 227: struct acpi_20_generic_address addr; ! 228: u8 hpet_number; ! 229: u16 min_tick; ! 230: u8 page_protect; ! 231: } PACKED; ! 232: #define ACPI_HPET_ADDRESS 0xFED00000UL ! 233: ! 234: /* ! 235: * SRAT (NUMA topology description) table ! 236: */ ! 237: ! 238: #define SRAT_PROCESSOR 0 ! 239: #define SRAT_MEMORY 1 ! 240: ! 241: struct system_resource_affinity_table ! 242: { ! 243: ACPI_TABLE_HEADER_DEF ! 244: u32 reserved1; ! 245: u32 reserved2[2]; ! 246: } PACKED; ! 247: ! 248: struct srat_processor_affinity ! 249: { ! 250: ACPI_SUB_HEADER_DEF ! 251: u8 proximity_lo; ! 252: u8 local_apic_id; ! 253: u32 flags; ! 254: u8 local_sapic_eid; ! 255: u8 proximity_hi[3]; ! 256: u32 reserved; ! 257: } PACKED; ! 258: ! 259: struct srat_memory_affinity ! 260: { ! 261: ACPI_SUB_HEADER_DEF ! 262: u8 proximity[4]; ! 263: u16 reserved1; ! 264: u32 base_addr_low,base_addr_high; ! 265: u32 length_low,length_high; ! 266: u32 reserved2; ! 267: u32 flags; ! 268: u32 reserved3[2]; ! 269: } PACKED; ! 270: ! 271: #include "acpi-dsdt.hex" ! 272: ! 273: static inline u16 cpu_to_le16(u16 x) ! 274: { ! 275: return x; ! 276: } ! 277: ! 278: static inline u32 cpu_to_le32(u32 x) ! 279: { ! 280: return x; ! 281: } ! 282: ! 283: static void ! 284: build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) ! 285: { ! 286: h->signature = sig; ! 287: h->length = cpu_to_le32(len); ! 288: h->revision = rev; ! 289: memcpy(h->oem_id, CONFIG_APPNAME6, 6); ! 290: memcpy(h->oem_table_id, CONFIG_APPNAME4, 4); ! 291: memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4); ! 292: memcpy(h->oem_table_id + 4, (void*)&sig, 4); ! 293: h->oem_revision = cpu_to_le32(1); ! 294: h->asl_compiler_revision = cpu_to_le32(1); ! 295: h->checksum -= checksum(h, len); ! 296: } ! 297: ! 298: static void* ! 299: build_fadt(int bdf) ! 300: { ! 301: struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt)); ! 302: struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs)); ! 303: void *dsdt = malloc_high(sizeof(AmlCode)); ! 304: ! 305: if (!fadt || !facs || !dsdt) { ! 306: dprintf(1, "Not enough memory for fadt!\n"); ! 307: return NULL; ! 308: } ! 309: ! 310: /* FACS */ ! 311: memset(facs, 0, sizeof(*facs)); ! 312: facs->signature = FACS_SIGNATURE; ! 313: facs->length = cpu_to_le32(sizeof(*facs)); ! 314: ! 315: /* DSDT */ ! 316: memcpy(dsdt, AmlCode, sizeof(AmlCode)); ! 317: ! 318: /* FADT */ ! 319: memset(fadt, 0, sizeof(*fadt)); ! 320: fadt->firmware_ctrl = cpu_to_le32((u32)facs); ! 321: fadt->dsdt = cpu_to_le32((u32)dsdt); ! 322: fadt->model = 1; ! 323: fadt->reserved1 = 0; ! 324: int pm_sci_int = pci_config_readb(bdf, PCI_INTERRUPT_LINE); ! 325: fadt->sci_int = cpu_to_le16(pm_sci_int); ! 326: fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD); ! 327: fadt->acpi_enable = 0xf1; ! 328: fadt->acpi_disable = 0xf0; ! 329: fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE); ! 330: fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04); ! 331: fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08); ! 332: fadt->pm1_evt_len = 4; ! 333: fadt->pm1_cnt_len = 2; ! 334: fadt->pm_tmr_len = 4; ! 335: fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported ! 336: fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported ! 337: fadt->gpe0_blk = cpu_to_le32(0xafe0); ! 338: fadt->gpe0_blk_len = 4; ! 339: /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */ ! 340: fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6)); ! 341: ! 342: build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1); ! 343: ! 344: return fadt; ! 345: } ! 346: ! 347: static void* ! 348: build_madt(void) ! 349: { ! 350: int madt_size = (sizeof(struct multiple_apic_table) ! 351: + sizeof(struct madt_processor_apic) * MaxCountCPUs ! 352: + sizeof(struct madt_io_apic) ! 353: + sizeof(struct madt_intsrcovr) * 16); ! 354: struct multiple_apic_table *madt = malloc_high(madt_size); ! 355: if (!madt) { ! 356: dprintf(1, "Not enough memory for madt!\n"); ! 357: return NULL; ! 358: } ! 359: memset(madt, 0, madt_size); ! 360: madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR); ! 361: madt->flags = cpu_to_le32(1); ! 362: struct madt_processor_apic *apic = (void*)&madt[1]; ! 363: int i; ! 364: for (i=0; i<MaxCountCPUs; i++) { ! 365: apic->type = APIC_PROCESSOR; ! 366: apic->length = sizeof(*apic); ! 367: apic->processor_id = i; ! 368: apic->local_apic_id = i; ! 369: if (i < CountCPUs) ! 370: apic->flags = cpu_to_le32(1); ! 371: else ! 372: apic->flags = cpu_to_le32(0); ! 373: apic++; ! 374: } ! 375: struct madt_io_apic *io_apic = (void*)apic; ! 376: io_apic->type = APIC_IO; ! 377: io_apic->length = sizeof(*io_apic); ! 378: io_apic->io_apic_id = CountCPUs; ! 379: io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR); ! 380: io_apic->interrupt = cpu_to_le32(0); ! 381: ! 382: struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1]; ! 383: if (qemu_cfg_irq0_override()) { ! 384: memset(intsrcovr, 0, sizeof(*intsrcovr)); ! 385: intsrcovr->type = APIC_XRUPT_OVERRIDE; ! 386: intsrcovr->length = sizeof(*intsrcovr); ! 387: intsrcovr->source = 0; ! 388: intsrcovr->gsi = 2; ! 389: intsrcovr->flags = 0; /* conforms to bus specifications */ ! 390: intsrcovr++; ! 391: } ! 392: for (i = 1; i < 16; i++) { ! 393: if (!(PCI_ISA_IRQ_MASK & (1 << i))) ! 394: /* No need for a INT source override structure. */ ! 395: continue; ! 396: memset(intsrcovr, 0, sizeof(*intsrcovr)); ! 397: intsrcovr->type = APIC_XRUPT_OVERRIDE; ! 398: intsrcovr->length = sizeof(*intsrcovr); ! 399: intsrcovr->source = i; ! 400: intsrcovr->gsi = i; ! 401: intsrcovr->flags = 0xd; /* active high, level triggered */ ! 402: intsrcovr++; ! 403: } ! 404: ! 405: build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1); ! 406: return madt; ! 407: } ! 408: ! 409: #define SSDT_SIGNATURE 0x54445353 // SSDT ! 410: static void* ! 411: build_ssdt(void) ! 412: { ! 413: int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs; ! 414: // calculate the length of processor block and scope block ! 415: // excluding PkgLength ! 416: int cpu_length = 13 * acpi_cpus + 4; ! 417: ! 418: int length = sizeof(struct acpi_table_header) + 3 + cpu_length; ! 419: u8 *ssdt = malloc_high(length); ! 420: if (! ssdt) { ! 421: dprintf(1, "No space for ssdt!\n"); ! 422: return NULL; ! 423: } ! 424: ! 425: u8 *ssdt_ptr = ssdt; ! 426: ssdt_ptr[9] = 0; // checksum; ! 427: ssdt_ptr += sizeof(struct acpi_table_header); ! 428: ! 429: // build processor scope header ! 430: *(ssdt_ptr++) = 0x10; // ScopeOp ! 431: if (cpu_length <= 0x3e) { ! 432: *(ssdt_ptr++) = cpu_length + 1; ! 433: } else { ! 434: *(ssdt_ptr++) = 0x7F; ! 435: *(ssdt_ptr++) = (cpu_length + 2) >> 6; ! 436: } ! 437: *(ssdt_ptr++) = '_'; // Name ! 438: *(ssdt_ptr++) = 'P'; ! 439: *(ssdt_ptr++) = 'R'; ! 440: *(ssdt_ptr++) = '_'; ! 441: ! 442: // build object for each processor ! 443: int i; ! 444: for (i=0; i<acpi_cpus; i++) { ! 445: *(ssdt_ptr++) = 0x5B; // ProcessorOp ! 446: *(ssdt_ptr++) = 0x83; ! 447: *(ssdt_ptr++) = 0x0B; // Length ! 448: *(ssdt_ptr++) = 'C'; // Name (CPUxx) ! 449: *(ssdt_ptr++) = 'P'; ! 450: if ((i & 0xf0) != 0) ! 451: *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa; ! 452: else ! 453: *(ssdt_ptr++) = 'U'; ! 454: *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa; ! 455: *(ssdt_ptr++) = i; ! 456: *(ssdt_ptr++) = 0x10; // Processor block address ! 457: *(ssdt_ptr++) = 0xb0; ! 458: *(ssdt_ptr++) = 0; ! 459: *(ssdt_ptr++) = 0; ! 460: *(ssdt_ptr++) = 6; // Processor block length ! 461: } ! 462: ! 463: build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1); ! 464: ! 465: return ssdt; ! 466: } ! 467: ! 468: #define HPET_SIGNATURE 0x54455048 //HPET ! 469: static void* ! 470: build_hpet(void) ! 471: { ! 472: struct acpi_20_hpet *hpet = malloc_high(sizeof(*hpet)); ! 473: if (!hpet) { ! 474: dprintf(1, "Not enough memory for hpet!\n"); ! 475: return NULL; ! 476: } ! 477: ! 478: memset(hpet, 0, sizeof(*hpet)); ! 479: /* Note timer_block_id value must be kept in sync with value advertised by ! 480: * emulated hpet ! 481: */ ! 482: hpet->timer_block_id = cpu_to_le32(0x8086a201); ! 483: hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS); ! 484: build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1); ! 485: ! 486: return hpet; ! 487: } ! 488: ! 489: static void ! 490: acpi_build_srat_memory(struct srat_memory_affinity *numamem, ! 491: u64 base, u64 len, int node, int enabled) ! 492: { ! 493: numamem->type = SRAT_MEMORY; ! 494: numamem->length = sizeof(*numamem); ! 495: memset (numamem->proximity, 0 ,4); ! 496: numamem->proximity[0] = node; ! 497: numamem->flags = cpu_to_le32(!!enabled); ! 498: numamem->base_addr_low = base & 0xFFFFFFFF; ! 499: numamem->base_addr_high = base >> 32; ! 500: numamem->length_low = len & 0xFFFFFFFF; ! 501: numamem->length_high = len >> 32; ! 502: } ! 503: ! 504: #define SRAT_SIGNATURE 0x54415253 //HPET ! 505: static void * ! 506: build_srat(void) ! 507: { ! 508: int nb_numa_nodes = qemu_cfg_get_numa_nodes(); ! 509: ! 510: if (nb_numa_nodes == 0) ! 511: return NULL; ! 512: ! 513: u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes)); ! 514: if (!numadata) { ! 515: dprintf(1, "Not enough memory for read numa data from VM!\n"); ! 516: return NULL; ! 517: } ! 518: ! 519: qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes); ! 520: ! 521: struct system_resource_affinity_table *srat; ! 522: int srat_size = sizeof(*srat) + ! 523: sizeof(struct srat_processor_affinity) * MaxCountCPUs + ! 524: sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2); ! 525: ! 526: srat = malloc_high(srat_size); ! 527: if (!srat) { ! 528: dprintf(1, "Not enough memory for srat table!\n"); ! 529: return NULL; ! 530: } ! 531: ! 532: memset(srat, 0, srat_size); ! 533: srat->reserved1=1; ! 534: struct srat_processor_affinity *core = (void*)(srat + 1); ! 535: int i; ! 536: u64 curnode; ! 537: ! 538: for (i = 0; i < MaxCountCPUs; ++i) { ! 539: core->type = SRAT_PROCESSOR; ! 540: core->length = sizeof(*core); ! 541: core->local_apic_id = i; ! 542: curnode = *numadata++; ! 543: core->proximity_lo = curnode; ! 544: memset(core->proximity_hi, 0, 3); ! 545: core->local_sapic_eid = 0; ! 546: if (i < CountCPUs) ! 547: core->flags = cpu_to_le32(1); ! 548: else ! 549: core->flags = 0; ! 550: core++; ! 551: } ! 552: ! 553: ! 554: /* the memory map is a bit tricky, it contains at least one hole ! 555: * from 640k-1M and possibly another one from 3.5G-4G. ! 556: */ ! 557: struct srat_memory_affinity *numamem = (void*)core; ! 558: int slots = 0; ! 559: u64 mem_len, mem_base, next_base = 0; ! 560: ! 561: acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1); ! 562: next_base = 1024 * 1024; ! 563: numamem++; ! 564: slots++; ! 565: for (i = 1; i < nb_numa_nodes + 1; ++i) { ! 566: mem_base = next_base; ! 567: mem_len = *numadata++; ! 568: if (i == 1) ! 569: mem_len -= 1024 * 1024; ! 570: next_base = mem_base + mem_len; ! 571: ! 572: /* Cut out the PCI hole */ ! 573: if (mem_base <= RamSize && next_base > RamSize) { ! 574: mem_len -= next_base - RamSize; ! 575: if (mem_len > 0) { ! 576: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1); ! 577: numamem++; ! 578: slots++; ! 579: } ! 580: mem_base = 1ULL << 32; ! 581: mem_len = next_base - RamSize; ! 582: next_base += (1ULL << 32) - RamSize; ! 583: } ! 584: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1); ! 585: numamem++; ! 586: slots++; ! 587: } ! 588: for (; slots < nb_numa_nodes + 2; slots++) { ! 589: acpi_build_srat_memory(numamem, 0, 0, 0, 0); ! 590: numamem++; ! 591: } ! 592: ! 593: build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1); ! 594: ! 595: return srat; ! 596: } ! 597: ! 598: struct rsdp_descriptor *RsdpAddr; ! 599: ! 600: #define MAX_ACPI_TABLES 20 ! 601: void ! 602: acpi_bios_init(void) ! 603: { ! 604: if (! CONFIG_ACPI) ! 605: return; ! 606: ! 607: dprintf(3, "init ACPI tables\n"); ! 608: ! 609: // This code is hardcoded for PIIX4 Power Management device. ! 610: int bdf = pci_find_device(PCI_VENDOR_ID_INTEL ! 611: , PCI_DEVICE_ID_INTEL_82371AB_3); ! 612: if (bdf < 0) ! 613: // Device not found ! 614: return; ! 615: ! 616: // Create initial rsdt table ! 617: struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp)); ! 618: if (!rsdp) { ! 619: dprintf(1, "Not enough memory for acpi rsdp table!\n"); ! 620: return; ! 621: } ! 622: ! 623: u32 tables[MAX_ACPI_TABLES], tbl_idx = 0; ! 624: ! 625: #define ACPI_INIT_TABLE(X) \ ! 626: do { \ ! 627: tables[tbl_idx] = (u32)(X); \ ! 628: if (tables[tbl_idx]) \ ! 629: tbl_idx++; \ ! 630: } while(0) ! 631: ! 632: // Add tables ! 633: ACPI_INIT_TABLE(build_fadt(bdf)); ! 634: ACPI_INIT_TABLE(build_ssdt()); ! 635: ACPI_INIT_TABLE(build_madt()); ! 636: ACPI_INIT_TABLE(build_hpet()); ! 637: ACPI_INIT_TABLE(build_srat()); ! 638: ! 639: u16 i, external_tables = qemu_cfg_acpi_additional_tables(); ! 640: ! 641: for(i = 0; i < external_tables; i++) { ! 642: u16 len = qemu_cfg_next_acpi_table_len(); ! 643: void *addr = malloc_high(len); ! 644: if (!addr) { ! 645: dprintf(1, "Not enough memory for ext acpi table of size %d!\n" ! 646: , len); ! 647: continue; ! 648: } ! 649: ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len)); ! 650: if (tbl_idx == MAX_ACPI_TABLES) { ! 651: dprintf(1, "Too many external tables!\n"); ! 652: break; ! 653: } ! 654: } ! 655: ! 656: struct rsdt_descriptor_rev1 *rsdt; ! 657: size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx; ! 658: rsdt = malloc_high(rsdt_len); ! 659: ! 660: if (!rsdt) { ! 661: dprintf(1, "Not enough memory for acpi rsdt table!\n"); ! 662: return; ! 663: } ! 664: memset(rsdt, 0, rsdt_len); ! 665: memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx); ! 666: ! 667: build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1); ! 668: ! 669: // Build rsdp pointer table ! 670: memset(rsdp, 0, sizeof(*rsdp)); ! 671: rsdp->signature = RSDP_SIGNATURE; ! 672: memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6); ! 673: rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt); ! 674: rsdp->checksum -= checksum(rsdp, 20); ! 675: RsdpAddr = rsdp; ! 676: dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt); ! 677: } ! 678: ! 679: u32 ! 680: find_resume_vector() ! 681: { ! 682: dprintf(4, "rsdp=%p\n", RsdpAddr); ! 683: if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) ! 684: return 0; ! 685: struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; ! 686: dprintf(4, "rsdt=%p\n", rsdt); ! 687: if (!rsdt || rsdt->signature != RSDT_SIGNATURE) ! 688: return 0; ! 689: void *end = (void*)rsdt + rsdt->length; ! 690: int i; ! 691: for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { ! 692: struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i]; ! 693: if (!fadt || fadt->signature != FACP_SIGNATURE) ! 694: continue; ! 695: dprintf(4, "fadt=%p\n", fadt); ! 696: struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; ! 697: dprintf(4, "facs=%p\n", facs); ! 698: if (! facs || facs->signature != FACS_SIGNATURE) ! 699: return 0; ! 700: // Found it. ! 701: dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); ! 702: return facs->firmware_waking_vector; ! 703: } ! 704: return 0; ! 705: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.