acpi-common.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Support for generating ACPI tables and passing them to Guests
  2. *
  3. * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
  4. * Copyright (C) 2006 Fabrice Bellard
  5. * Copyright (C) 2013 Red Hat Inc
  6. *
  7. * Author: Michael S. Tsirkin <mst@redhat.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "qemu/osdep.h"
  21. #include "qapi/error.h"
  22. #include "exec/memory.h"
  23. #include "hw/acpi/acpi.h"
  24. #include "hw/acpi/aml-build.h"
  25. #include "hw/acpi/utils.h"
  26. #include "target/i386/cpu.h"
  27. #include "acpi-build.h"
  28. #include "acpi-common.h"
  29. void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
  30. GArray *entry, bool force_enabled)
  31. {
  32. uint32_t apic_id = apic_ids->cpus[uid].arch_id;
  33. /* Flags – Local APIC Flags */
  34. uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ?
  35. 1 /* Enabled */ : 0;
  36. /* ACPI spec says that LAPIC entry for non present
  37. * CPU may be omitted from MADT or it must be marked
  38. * as disabled. However omitting non present CPU from
  39. * MADT breaks hotplug on linux. So possible CPUs
  40. * should be put in MADT but kept disabled.
  41. */
  42. if (apic_id < 255) {
  43. /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
  44. build_append_int_noprefix(entry, 0, 1); /* Type */
  45. build_append_int_noprefix(entry, 8, 1); /* Length */
  46. build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */
  47. build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
  48. build_append_int_noprefix(entry, flags, 4); /* Flags */
  49. } else {
  50. /* Rev 4.0, 5.2.12.12 Processor Local x2APIC Structure */
  51. build_append_int_noprefix(entry, 9, 1); /* Type */
  52. build_append_int_noprefix(entry, 16, 1); /* Length */
  53. build_append_int_noprefix(entry, 0, 2); /* Reserved */
  54. build_append_int_noprefix(entry, apic_id, 4); /* X2APIC ID */
  55. build_append_int_noprefix(entry, flags, 4); /* Flags */
  56. build_append_int_noprefix(entry, uid, 4); /* ACPI Processor UID */
  57. }
  58. }
  59. static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq)
  60. {
  61. /* Rev 1.0b, 5.2.8.2 IO APIC */
  62. build_append_int_noprefix(entry, 1, 1); /* Type */
  63. build_append_int_noprefix(entry, 12, 1); /* Length */
  64. build_append_int_noprefix(entry, id, 1); /* IO APIC ID */
  65. build_append_int_noprefix(entry, 0, 1); /* Reserved */
  66. build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */
  67. build_append_int_noprefix(entry, irq, 4); /* System Vector Base */
  68. }
  69. static void
  70. build_xrupt_override(GArray *entry, uint8_t src, uint32_t gsi, uint16_t flags)
  71. {
  72. /* Rev 1.0b, 5.2.8.3.1 Interrupt Source Overrides */
  73. build_append_int_noprefix(entry, 2, 1); /* Type */
  74. build_append_int_noprefix(entry, 10, 1); /* Length */
  75. build_append_int_noprefix(entry, 0, 1); /* Bus */
  76. build_append_int_noprefix(entry, src, 1); /* Source */
  77. /* Global System Interrupt Vector */
  78. build_append_int_noprefix(entry, gsi, 4);
  79. build_append_int_noprefix(entry, flags, 2); /* Flags */
  80. }
  81. /*
  82. * ACPI spec, Revision 1.0b
  83. * 5.2.8 Multiple APIC Description Table
  84. */
  85. void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
  86. X86MachineState *x86ms,
  87. const char *oem_id, const char *oem_table_id)
  88. {
  89. int i;
  90. bool x2apic_mode = false;
  91. MachineClass *mc = MACHINE_GET_CLASS(x86ms);
  92. X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
  93. const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
  94. AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
  95. .oem_table_id = oem_table_id };
  96. acpi_table_begin(&table, table_data);
  97. /* Local APIC Address */
  98. build_append_int_noprefix(table_data, APIC_DEFAULT_ADDRESS, 4);
  99. /* Flags. bit 0: PCAT_COMPAT */
  100. build_append_int_noprefix(table_data,
  101. x86ms->pic != ON_OFF_AUTO_OFF ? 1 : 0 , 4);
  102. for (i = 0; i < apic_ids->len; i++) {
  103. pc_madt_cpu_entry(i, apic_ids, table_data, false);
  104. if (apic_ids->cpus[i].arch_id > 254) {
  105. x2apic_mode = true;
  106. }
  107. }
  108. build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, IO_APIC_DEFAULT_ADDRESS, 0);
  109. if (x86ms->ioapic2) {
  110. build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID + 1,
  111. IO_APIC_SECONDARY_ADDRESS, IO_APIC_SECONDARY_IRQBASE);
  112. }
  113. if (x86mc->apic_xrupt_override) {
  114. build_xrupt_override(table_data, 0, 2,
  115. 0 /* Flags: Conforms to the specifications of the bus */);
  116. }
  117. for (i = 1; i < 16; i++) {
  118. if (!(x86ms->pci_irq_mask & (1 << i))) {
  119. /* No need for a INT source override structure. */
  120. continue;
  121. }
  122. build_xrupt_override(table_data, i, i,
  123. 0xd /* Flags: Active high, Level Triggered */);
  124. }
  125. if (x2apic_mode) {
  126. /* Rev 4.0, 5.2.12.13 Local x2APIC NMI Structure*/
  127. build_append_int_noprefix(table_data, 0xA, 1); /* Type */
  128. build_append_int_noprefix(table_data, 12, 1); /* Length */
  129. build_append_int_noprefix(table_data, 0, 2); /* Flags */
  130. /* ACPI Processor UID */
  131. build_append_int_noprefix(table_data, 0xFFFFFFFF /* all processors */,
  132. 4);
  133. /* Local x2APIC LINT# */
  134. build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
  135. build_append_int_noprefix(table_data, 0, 3); /* Reserved */
  136. } else {
  137. /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */
  138. build_append_int_noprefix(table_data, 4, 1); /* Type */
  139. build_append_int_noprefix(table_data, 6, 1); /* Length */
  140. /* ACPI Processor ID */
  141. build_append_int_noprefix(table_data, 0xFF /* all processors */, 1);
  142. build_append_int_noprefix(table_data, 0, 2); /* Flags */
  143. /* Local APIC INTI# */
  144. build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
  145. }
  146. acpi_table_end(linker, &table);
  147. }