diff options
author | Tobias Diedrich <ranma+coreboot@tdiedrich.de> | 2017-12-13 23:25:32 +0100 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-12-20 16:48:05 +0000 |
commit | 9d8be5a857dfcd10449fad58c514f7a95e4a7cb8 (patch) | |
tree | cf39d59530133b343625b21984e10c0d9b1f7252 /src/southbridge/intel/common/rcba_pirq.c | |
parent | fd305156cda099ae99b7077c87ef1dc8b33d255d (diff) | |
download | coreboot-9d8be5a857dfcd10449fad58c514f7a95e4a7cb8.tar.xz |
sb/intel/common: Automatically generate ACPI PIRQ
Based on change I2b5d68adabf0840162c6f295af8d10d8d3007a34
(sb/intel/common: Add function to automatically generate ACPI PIRQ).
This adds functionality to generate PIRQ ACPI tables automatically based
on the chipset registers.
Mapping of PCI interrupt pin to PIRQ is done by the chipset-specific
intel_common_map_pirq() function, an shared implementation of which is
provided for the bd82x6x, i82801, i89xx, ibexpeak and lynxpoint
chipsets.
Example generated _PRT:
Scope (\_SB.PCI0)
{
Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
{
If (PICM)
{
Return (Package (0x09)
{
Package (0x04)
{
0x0002FFFF,
0x00000000,
0x00000000,
0x00000010
},
Package (0x04)
{
0x001BFFFF,
0x00000000,
0x00000000,
0x00000010
},
Package (0x04)
{
0x001CFFFF,
0x00000000,
0x00000000,
0x00000011
},
Package (0x04)
{
0x001CFFFF,
0x00000001,
0x00000000,
0x00000015
},
Package (0x04)
{
0x001CFFFF,
0x00000002,
0x00000000,
0x00000013
},
Package (0x04)
{
0x001DFFFF,
0x00000000,
0x00000000,
0x00000013
},
Package (0x04)
{
0x001FFFFF,
0x00000000,
0x00000000,
0x00000011
},
Package (0x04)
{
0x001FFFFF,
0x00000001,
0x00000000,
0x00000017
},
Package (0x04)
{
0x0004FFFF,
0x00000000,
0x00000000,
0x00000010
}
})
}
Else
{
Return (Package (0x09)
{
Package (0x04)
{
0x0002FFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKA,
0x00000000
},
Package (0x04)
{
0x001BFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKA,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKB,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000001,
\_SB.PCI0.LPCB.LNKF,
0x00000000
},
Package (0x04)
{
0x001CFFFF,
0x00000002,
\_SB.PCI0.LPCB.LNKD,
0x00000000
},
Package (0x04)
{
0x001DFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKD,
0x00000000
},
Package (0x04)
{
0x001FFFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKB,
0x00000000
},
Package (0x04)
{
0x001FFFFF,
0x00000001,
\_SB.PCI0.LPCB.LNKH,
0x00000000
},
Package (0x04)
{
0x0004FFFF,
0x00000000,
\_SB.PCI0.LPCB.LNKA,
0x00000000
}
})
}
}
}
Change-Id: Ic6b8ce4a9db50211a9c26221ca10105c5a0829a0
Signed-off-by: Tobias Diedrich <ranma+coreboot@tdiedrich.de>
Reviewed-on: https://review.coreboot.org/22810
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/southbridge/intel/common/rcba_pirq.c')
-rw-r--r-- | src/southbridge/intel/common/rcba_pirq.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/southbridge/intel/common/rcba_pirq.c b/src/southbridge/intel/common/rcba_pirq.c new file mode 100644 index 0000000000..186115472f --- /dev/null +++ b/src/southbridge/intel/common/rcba_pirq.c @@ -0,0 +1,42 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <southbridge/intel/common/acpi_pirq_gen.h> +#include <southbridge/intel/common/rcba_pirq.h> + +#define MAX_SLOT 31 +#define MIN_SLOT 19 + +static const u32 pirq_dir_route_reg[MAX_SLOT - MIN_SLOT + 1] = { + D19IR, D20IR, D21IR, D22IR, D23IR, 0, D25IR, + D26IR, D27IR, D28IR, D29IR, D30IR, D31IR, +}; + +enum pirq intel_common_map_pirq(const device_t dev, const pci_pin_t pci_pin) +{ + u8 slot = PCI_SLOT(dev->path.pci.devfn); + u8 shift = 4 * (pci_pin - PCI_INT_A); + u8 pirq; + u16 reg; + + if (pci_pin < 1 || pci_pin > 4) { + printk(BIOS_ERR, "Slot %d PCI pin %d out of bounds\n", + slot, pci_pin); + return PIRQ_NONE; + } + + if (slot < MIN_SLOT || slot > MAX_SLOT) { + /* non-PCH devices use 1:1 mapping. */ + return pci_pin; + } + + reg = pirq_dir_route_reg[slot - MIN_SLOT]; + + pirq = ((RCBA16(reg) >> shift) & 0xf); + if (pirq > 8) { + printk(BIOS_ERR, "Reg 0x%04x PIRQ %c out of bounds\n", + reg, 'A' + pirq); + return PIRQ_NONE; + } + return PIRQ_A + pirq; +} |