From 28d4275622dd66132b2849c09b33684dd6553ff1 Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Mon, 9 Mar 2020 13:50:31 -0600 Subject: soc/amd/picasso/acpi: Improve PCI Interrupt Link Devices The PCI interrupt devices were only partially implemented. * Lacked support for _DIS to disable the bus. Something the kernel does while booting. * Lacked support for APIC vs PIC. This means the devices can only be used when using the PIC. By looking at the PMOD variable we can handle both PIC and APIC. This means we can stop hard coding the PCI interrupt numbers in the ACPI tables. * I removed INT[E-H] since they are not used. BUG=b:139429446, b:147042464 BRANCH=none TEST=Boot with both the APIC and PIC and saw that the link devices work as expected: PIC MODE: [ 1.959345] ACPI: PCI Interrupt Link [IRQA] (IRQs 1 3 4 5 *6 7 8 9 10 11 12 14 15) [ 2.007344] ACPI: PCI Interrupt Link [IRQB] (IRQs 1 3 4 5 *6 7 8 9 10 11 12 14 15) [ 2.056344] ACPI: PCI Interrupt Link [IRQC] (IRQs 1 3 4 5 6 7 8 9 10 11 12 *14 15) [ 2.104344] ACPI: PCI Interrupt Link [IRQD] (IRQs 1 3 4 5 6 7 8 9 10 11 12 14 *15) [ 13.752676] PCI Interrupt Link [IRQA] enabled at IRQ 6 [ 13.816755] PCI Interrupt Link [IRQD] enabled at IRQ 15 [ 27.788798] PCI Interrupt Link [IRQB] enabled at IRQ 6 [ 27.852873] PCI Interrupt Link [IRQC] enabled at IRQ 14 APIC MODE: [ 19.311764] ACPI: PCI Interrupt Link [IRQA] (IRQs *16 17 18 19 20 21 22 23) [ 19.374765] ACPI: PCI Interrupt Link [IRQB] (IRQs 16 *17 18 19 20 21 22 23) [ 19.438770] ACPI: PCI Interrupt Link [IRQC] (IRQs 16 17 *18 19 20 21 22 23) [ 19.501764] ACPI: PCI Interrupt Link [IRQD] (IRQs 16 17 18 *19 20 21 22 23) [ 34.719072] PCI Interrupt Link [IRQA] enabled at IRQ 23 [ 34.798994] PCI Interrupt Link [IRQD] enabled at IRQ 22 [ 66.469510] PCI Interrupt Link [IRQB] enabled at IRQ 21 [ 66.542395] PCI Interrupt Link [IRQC] enabled at IRQ 20 Change-Id: I1bb84813b65c89b4b5479602be3e9a9fedb7333d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/2095683 Signed-off-by: Raul E Rangel Reviewed-on: https://review.coreboot.org/c/coreboot/+/41438 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/picasso/acpi/northbridge.asl | 78 ++---- src/soc/amd/picasso/acpi/pci_int.asl | 427 +++++++------------------------ src/soc/amd/picasso/acpi/pcie.asl | 27 +- 3 files changed, 140 insertions(+), 392 deletions(-) (limited to 'src/soc') diff --git a/src/soc/amd/picasso/acpi/northbridge.asl b/src/soc/amd/picasso/acpi/northbridge.asl index 3227c7137a..f2a709f384 100644 --- a/src/soc/amd/picasso/acpi/northbridge.asl +++ b/src/soc/amd/picasso/acpi/northbridge.asl @@ -18,60 +18,38 @@ Method(_STA, 0, NotSerialized) Return(0x0B) /* Status is visible */ } +/* PCI Routing Table */ +Name(PR0, Package(){ + /* Bus 0, Dev 0x00 - F2: IOMMU */ + Package() { 0x0000FFFF, 0, INTA, 0 }, + Package() { 0x0000FFFF, 0, INTB, 0 }, + Package() { 0x0000FFFF, 0, INTC, 0 }, + Package() { 0x0000FFFF, 0, INTD, 0 }, + + /* Bus 0, Dev 0x01 - F[1-7]: GPP PCI Bridges */ + Package() { 0x0001FFFF, 0, INTA, 0 }, + Package() { 0x0001FFFF, 1, INTB, 0 }, + Package() { 0x0001FFFF, 2, INTC, 0 }, + Package() { 0x0001FFFF, 3, INTD, 0 }, + + /* Bus 0, Dev 0x08 - F[1:PCI Bridge to Bus A, 2: PCI Bridge to Bus B] */ + Package() { 0x0008FFFF, 0, INTA, 0 }, + Package() { 0x0008FFFF, 1, INTB, 0 }, + Package() { 0x0008FFFF, 2, INTC, 0 }, + Package() { 0x0008FFFF, 3, INTD, 0 }, + + /* Bus 0, Dev 0x14 - F[0:SMBus 3:LPC] */ + Package() { 0x0014FFFF, 0, INTA, 0 }, + Package() { 0x0014FFFF, 1, INTB, 0 }, + Package() { 0x0014FFFF, 2, INTC, 0 }, + Package() { 0x0014FFFF, 3, INTD, 0 }, +}) + Method(_PRT,0, NotSerialized) { - If(PMOD) - { - Return(APR0) /* APIC mode */ - } - Return (PR0) /* PIC Mode */ + Return(PR0) } Device(AMRT) { Name(_ADR, 0x00000000) } /* end AMRT */ - -/* Gpp 0 */ -Device(PBR4) { - Name(_ADR, 0x00020001) - Method(_PRT,0) { - If(PMOD){ Return(APS4) } /* APIC mode */ - Return (PS4) /* PIC Mode */ - } /* end _PRT */ -} /* end PBR4 */ - -/* Gpp 1 */ -Device(PBR5) { - Name(_ADR, 0x00020002) - Method(_PRT,0) { - If(PMOD){ Return(APS5) } /* APIC mode */ - Return (PS5) /* PIC Mode */ - } /* end _PRT */ -} /* end PBR5 */ - -/* Gpp 2 */ -Device(PBR6) { - Name(_ADR, 0x00020003) - Method(_PRT,0) { - If(PMOD){ Return(APS6) } /* APIC mode */ - Return (PS6) /* PIC Mode */ - } /* end _PRT */ -} /* end PBR6 */ - -/* Gpp 3 */ -Device(PBR7) { - Name(_ADR, 0x00020004) - Method(_PRT,0) { - If(PMOD){ Return(APS7) } /* APIC mode */ - Return (PS7) /* PIC Mode */ - } /* end _PRT */ -} /* end PBR7 */ - -/* Gpp 4 */ -Device(PBR8) { - Name(_ADR, 0x00020005) - Method(_PRT,0) { - If(PMOD){ Return(APS8) } /* APIC mode */ - Return (PS8) /* PIC Mode */ - } /* end _PRT */ -} /* end PBR8 */ diff --git a/src/soc/amd/picasso/acpi/pci_int.asl b/src/soc/amd/picasso/acpi/pci_int.asl index f89a14e795..bd72b22b47 100644 --- a/src/soc/amd/picasso/acpi/pci_int.asl +++ b/src/soc/amd/picasso/acpi/pci_int.asl @@ -116,342 +116,101 @@ Method(CIRQ, 0x00, NotSerialized){ } - Name(IRQB, ResourceTemplate(){ - IRQ(Level,ActiveLow,Shared){15} - }) - - Name(IRQP, ResourceTemplate(){ - IRQ(Level,ActiveLow,Exclusive){3, 4, 5, 7, 10, 11, 12, 15} + /* PIC Possible Resource Values */ + Name(IRQP, ResourceTemplate() { + Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , , PIC){ + 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15 + } }) - Name(PITF, ResourceTemplate(){ - IRQ(Level,ActiveLow,Exclusive){9} + /* IO-APIC Possible Resource Values */ + Name(IRQI, ResourceTemplate() { + Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , APIC) { + 16, 17, 18, 19, 20, 21, 22, 23 + } }) - Device(INTA) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 1) - - Method(_STA, 0) { - if (PIRA) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTA._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKA\\_DIS\n") */ - } /* End Method(_SB.INTA._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKA\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTA._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKA\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRA, IRQN) - Return(IRQB) - } /* Method(_SB.INTA._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKA\\_SRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRA) - } /* End Method(_SB.INTA._SRS) */ - } /* End Device(INTA) */ - - Device(INTB) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 2) - - Method(_STA, 0) { - if (PIRB) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTB._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKB\\_DIS\n") */ - } /* End Method(_SB.INTB._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKB\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTB._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKB\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRB, IRQN) - Return(IRQB) - } /* Method(_SB.INTB._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKB\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRB) - } /* End Method(_SB.INTB._SRS) */ - } /* End Device(INTB) */ - - Device(INTC) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 3) - - Method(_STA, 0) { - if (PIRC) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTC._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKC\\_DIS\n") */ - } /* End Method(_SB.INTC._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKC\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTC._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKC\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRC, IRQN) - Return(IRQB) - } /* Method(_SB.INTC._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKC\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRC) - } /* End Method(_SB.INTC._SRS) */ - } /* End Device(INTC) */ - - Device(INTD) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 4) - - Method(_STA, 0) { - if (PIRD) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTD._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKD\\_DIS\n") */ - } /* End Method(_SB.INTD._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKD\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTD._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKD\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRD, IRQN) - Return(IRQB) - } /* Method(_SB.INTD._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKD\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRD) - } /* End Method(_SB.INTD._SRS) */ - } /* End Device(INTD) */ - - Device(INTE) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 5) - - Method(_STA, 0) { - if (PIRE) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTE._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKE\\_DIS\n") */ - } /* End Method(_SB.INTE._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKE\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTE._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKE\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRE, IRQN) - Return(IRQB) - } /* Method(_SB.INTE._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKE\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRE) - } /* End Method(_SB.INTE._SRS) */ - } /* End Device(INTE) */ - - Device(INTF) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 6) - - Method(_STA, 0) { - if (PIRF) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTF._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKF\\_DIS\n") */ - } /* End Method(_SB.INTF._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKF\\_PRS\n") */ - Return(PITF) - } /* Method(_SB.INTF._PRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKF\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRF, IRQN) - Return(IRQB) - } /* Method(_SB.INTF._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKF\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRF) - } /* End Method(_SB.INTF._SRS) */ - } /* End Device(INTF) */ - - Device(INTG) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 7) - - Method(_STA, 0) { - if (PIRG) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTG._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKG\\_DIS\n") */ - } /* End Method(_SB.INTG._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKG\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTG._CRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKG\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRG, IRQN) - Return(IRQB) - } /* Method(_SB.INTG._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKG\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) - - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRG) - } /* End Method(_SB.INTG._SRS) */ - } /* End Device(INTG) */ - - Device(INTH) { - Name(_HID, EISAID("PNP0C0F")) - Name(_UID, 8) - - Method(_STA, 0) { - if (PIRH) { - Return(0x0b) /* sata is invisible */ - } else { - Return(0x09) /* sata is disabled */ - } - } /* End Method(_SB.INTH._STA) */ - - Method(_DIS ,0) { - /* DBGO("\\_SB\\LNKH\\_DIS\n") */ - } /* End Method(_SB.INTH._DIS) */ - - Method(_PRS ,0) { - /* DBGO("\\_SB\\LNKH\\_PRS\n") */ - Return(IRQP) - } /* Method(_SB.INTH._CRS) */ - - Method(_CRS ,0) { - /* DBGO("\\_SB\\LNKH\\_CRS\n") */ - CreateWordField(IRQB, 0x1, IRQN) - ShiftLeft(1, PIRH, IRQN) - Return(IRQB) - } /* Method(_SB.INTH._CRS) */ - - Method(_SRS, 1) { - /* DBGO("\\_SB\\LNKH\\_CRS\n") */ - CreateWordField(ARG0, 1, IRQM) +#define PCI_LINK(DEV_NAME, PIC_REG, APIC_REG) \ + Device(DEV_NAME) { \ + Name(_HID, EISAID("PNP0C0F")) \ + Name(_UID, 1) \ +\ + Method(_STA, 0) { \ + If (PMOD) { \ + local0=APIC_REG \ + } Else { \ + local0=PIC_REG \ + } \ +\ + If (local0 != 0x1f) { \ + printf("PCI: \\_SB.%s._STA: %o, Enabled", #DEV_NAME, local0) \ + /* Present, Enabled, Functional */ \ + Return(0x0b) \ + } else { \ + printf("PCI: \\_SB.%s._STA: %o, Disabled", #DEV_NAME, local0) \ + /* Present, Functional */ \ + Return(0x09) \ + } \ + } \ +\ + Method(_DIS ,0) { \ + If(PMOD) { \ + printf("PCI: \\_SB.%s._DIS APIC", #DEV_NAME) \ + APIC_REG=0x1f \ + } Else { \ + printf("PCI: \\_SB.%s._DIS PIC", #DEV_NAME) \ + PIC_REG=0x1f \ + } \ + } \ +\ + Method(_PRS ,0) { \ + If(PMOD) { \ + printf("PCI: \\_SB.%s._PRS => APIC", #DEV_NAME) \ + Return(IRQI) \ + } Else { \ + printf("PCI: \\_SB.%s._PRS => PIC", #DEV_NAME) \ + Return(IRQP) \ + } \ + } \ +\ + Method(_CRS ,0) { \ + local0=ResourceTemplate(){ \ + Interrupt ( \ + ResourceConsumer, \ + Level, \ + ActiveLow, \ + Exclusive, , , NUMB) \ + { 0 } \ + } \ + CreateDWordField(local0, NUMB._INT, IRQN) \ + If(PMOD) { \ + printf("PCI: \\_SB.%s._CRS APIC: %o", #DEV_NAME, APIC_REG) \ + IRQN=APIC_REG \ + } Else { \ + printf("PCI: \\_SB.%s._CRS PIC: %o", #DEV_NAME, PIC_REG) \ + IRQN=PIC_REG \ + } \ + If (IRQN == 0x1f) { \ + Return(ResourceTemplate(){}) \ + } Else { \ + Return(local0) \ + } \ + } \ +\ + Method(_SRS, 1) { \ + CreateWordField(ARG0, 0x5, IRQN) \ +\ + If(PMOD) { \ + printf("PCI: \\_SB.%s._SRS APIC: %o", #DEV_NAME, IRQN) \ + APIC_REG=IRQN \ + } Else { \ + printf("PCI: \\_SB.%s._SRS PIC: %o", #DEV_NAME, IRQN) \ + PIC_REG=IRQN \ + } \ + } \ + } - /* Use lowest available IRQ */ - FindSetRightBit(IRQM, Local0) - if (Local0) { - Decrement(Local0) - } - Store(Local0, PIRH) - } /* End Method(_SB.INTH._SRS) */ - } /* End Device(INTH) */ +PCI_LINK(INTA, PIRA, IORA) +PCI_LINK(INTB, PIRB, IORB) +PCI_LINK(INTC, PIRC, IORC) +PCI_LINK(INTD, PIRD, IORD) diff --git a/src/soc/amd/picasso/acpi/pcie.asl b/src/soc/amd/picasso/acpi/pcie.asl index ecb54b9e16..2bbfec56e4 100644 --- a/src/soc/amd/picasso/acpi/pcie.asl +++ b/src/soc/amd/picasso/acpi/pcie.asl @@ -7,14 +7,25 @@ PRQD, 0x00000008, /* Offset: 1h */ } IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { - PIRA, 0x00000008, /* Index 0 */ - PIRB, 0x00000008, /* Index 1 */ - PIRC, 0x00000008, /* Index 2 */ - PIRD, 0x00000008, /* Index 3 */ - PIRE, 0x00000008, /* Index 4 */ - PIRF, 0x00000008, /* Index 5 */ - PIRG, 0x00000008, /* Index 6 */ - PIRH, 0x00000008, /* Index 7 */ + PIRA, 0x00000008, /* Index 0: INTA */ + PIRB, 0x00000008, /* Index 1: INTB */ + PIRC, 0x00000008, /* Index 2: INTC */ + PIRD, 0x00000008, /* Index 3: INTD */ + PIRE, 0x00000008, /* Index 4: INTE */ + PIRF, 0x00000008, /* Index 5: INTF */ + PIRG, 0x00000008, /* Index 6: INTG */ + PIRH, 0x00000008, /* Index 7: INTH */ + + /* IO-APIC IRQs */ + Offset (0x80), + IORA, 0x00000008, /* Index 0x80: INTA */ + IORB, 0x00000008, /* Index 0x81: INTB */ + IORC, 0x00000008, /* Index 0x82: INTC */ + IORD, 0x00000008, /* Index 0x83: INTD */ + IORE, 0x00000008, /* Index 0x84: INTE */ + IORF, 0x00000008, /* Index 0x85: INTF */ + IORG, 0x00000008, /* Index 0x86: INTG */ + IORH, 0x00000008, /* Index 0x87: INTH */ } /* PCI Error control register */ -- cgit v1.2.3