aboutsummaryrefslogtreecommitdiff
path: root/hw/i386/acpi-build.c
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2015-12-28 18:02:51 +0100
committerMichael S. Tsirkin <mst@redhat.com>2016-01-09 23:20:19 +0200
commit22b5b8bf313fa7fa60d4201a882fd82e4bb5ba8a (patch)
treea365048b3963702891f3e391203b7ba6f6773deb /hw/i386/acpi-build.c
parent0dafe3b33603dd64d1385f8943dd056d4058cbf5 (diff)
pc: acpi: q35: move PRTA routing table into SSDT
Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/acpi-build.c')
-rw-r--r--hw/i386/acpi-build.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 0c23c22ff2..e64c662a73 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1631,6 +1631,64 @@ static void build_piix4_pci0_int(Aml *table)
aml_append(table, sb_scope);
}
+static void append_q35_prt_entry(Aml *ctx, uint32_t nr, const char *name)
+{
+ int i;
+ int head;
+ Aml *pkg;
+ char base = name[3] < 'E' ? 'A' : 'E';
+ char *s = g_strdup(name);
+ Aml *a_nr = aml_int((nr << 16) | 0xffff);
+
+ assert(strlen(s) == 4);
+
+ head = name[3] - base;
+ for (i = 0; i < 4; i++) {
+ if (head + i > 3) {
+ head = i * -1;
+ }
+ s[3] = base + head + i;
+ pkg = aml_package(4);
+ aml_append(pkg, a_nr);
+ aml_append(pkg, aml_int(i));
+ aml_append(pkg, aml_name("%s", s));
+ aml_append(pkg, aml_int(0));
+ aml_append(ctx, pkg);
+ }
+ g_free(s);
+}
+
+static Aml *build_q35_routing_table(const char *str)
+{
+ int i;
+ Aml *pkg;
+ char *name = g_strdup_printf("%s ", str);
+
+ pkg = aml_package(128);
+ for (i = 0; i < 0x18; i++) {
+ name[3] = 'E' + (i & 0x3);
+ append_q35_prt_entry(pkg, i, name);
+ }
+
+ name[3] = 'E';
+ append_q35_prt_entry(pkg, 0x18, name);
+
+ /* INTA -> PIRQA for slot 25 - 31, see the default value of D<N>IR */
+ for (i = 0x0019; i < 0x1e; i++) {
+ name[3] = 'A';
+ append_q35_prt_entry(pkg, i, name);
+ }
+
+ /* PCIe->PCI bridge. use PIRQ[E-H] */
+ name[3] = 'E';
+ append_q35_prt_entry(pkg, 0x1e, name);
+ name[3] = 'A';
+ append_q35_prt_entry(pkg, 0x1f, name);
+
+ g_free(name);
+ return pkg;
+}
+
static void build_q35_pci0_int(Aml *table)
{
Aml *field;
@@ -1638,6 +1696,9 @@ static void build_q35_pci0_int(Aml *table)
Aml *sb_scope = aml_scope("_SB");
Aml *pci0_scope = aml_scope("PCI0");
+ aml_append(pci0_scope,
+ aml_name_decl("PRTA", build_q35_routing_table("GSI")));
+
method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
{
Aml *if_ctx;