@samitouri / QOSamiQemu / commits / a504993500

hw/acpi/aml-build.c: add aml_irq() representing the 3-byte IRQ descriptor

The existing aml_interrupt() uses the Extended Interrupt Descriptor to store the interrupt information, however newer Windows will only parse the standard IRQ Descriptor when enumerating ISA serial ports. Signed-off-by: Mark Cave-Ayland <mark.caveayland@nutanix.com> Reviewed-by: Ani Sinha <anisinha@redhat.com> Reviewed-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260515150634.2637533-2-mark.caveayland@nutanix.com>

Mark Cave-Ayland committed May 15, 2026 at 16:05 UTC a50499350010ec0d238185f3c835f3fb39e58032
3 files changed +35
hw/acpi/aml-build-stub.c
+6
@@ -67,6 +67,12 @@ Aml *aml_irq_no_flags(uint8_t irq)
67 return NULL;
68 }
69
70 +Aml *aml_irq(uint8_t irq, AmlLevelAndEdge level_and_edge,
71 + AmlActiveHighAndLow high_and_low, AmlShared shared)
72 +{
73 + return NULL;
74 +}
75 +
76 Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
77 AmlLevelAndEdge level_and_edge,
78 AmlActiveHighAndLow high_and_low, AmlShared shared,
hw/acpi/aml-build.c
+27
@@ -1061,6 +1061,33 @@ Aml *aml_irq_no_flags(uint8_t irq)
1061 return var;
1062 }
1063
1064 +/*
1065 + * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
1066 + *
1067 + * More verbose description at:
1068 + * ACPI 5.0: 19.5.63 IRQ (Interrupt Resource Descriptor Macro)
1069 + * 6.4.2.1 IRQ Descriptor
1070 + */
1071 +Aml *aml_irq(uint8_t irq, AmlLevelAndEdge level_and_edge,
1072 + AmlActiveHighAndLow high_and_low, AmlShared shared)
1073 +{
1074 + uint16_t irq_mask;
1075 + Aml *var = aml_alloc();
1076 + uint8_t irq_flags = level_and_edge | (high_and_low << 3) |
1077 + (shared << 4);
1078 +
1079 + assert((level_and_edge == AML_EDGE && high_and_low == AML_ACTIVE_HIGH) ||
1080 + (level_and_edge == AML_LEVEL && high_and_low == AML_ACTIVE_LOW));
1081 + assert(irq < 16);
1082 + build_append_byte(var->buf, 0x23); /* IRQ descriptor 3 byte form */
1083 +
1084 + irq_mask = 1U << irq;
1085 + build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
1086 + build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
1087 + build_append_byte(var->buf, irq_flags); /* IRQ flags */
1088 + return var;
1089 +}
1090 +
1091 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
1092 Aml *aml_lnot(Aml *arg)
1093 {
include/hw/acpi/aml-build.h
+2
@@ -343,6 +343,8 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
343 Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
344 Aml *offset, uint32_t len);
345 Aml *aml_irq_no_flags(uint8_t irq);
346 +Aml *aml_irq(uint8_t irq, AmlLevelAndEdge level_and_edge,
347 + AmlActiveHighAndLow high_and_low, AmlShared shared);
348 Aml *aml_named_field(const char *name, unsigned length);
349 Aml *aml_reserved_field(unsigned length);
350 Aml *aml_local(int num);