summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch
diff options
context:
space:
mode:
authorFrancis Rowe <info@gluglug.org.uk>2016-01-02 17:10:32 (EST)
committer Francis Rowe <info@gluglug.org.uk>2016-01-04 15:28:39 (EST)
commitd1f408f3725aa02bc1d76c4c6aadb4697bd073c0 (patch)
tree7eed036543ae1f8c57b56825880a722a8efbedf1 /resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch
parent91aec7e72005dcda72d19f2d024a02d8c0f86590 (diff)
downloadlibreboot-d1f408f3725aa02bc1d76c4c6aadb4697bd073c0.zip
libreboot-d1f408f3725aa02bc1d76c4c6aadb4697bd073c0.tar.gz
libreboot-d1f408f3725aa02bc1d76c4c6aadb4697bd073c0.tar.bz2
Use different coreboot revisions and patches per board
The release archives will be bigger, but this is a necessary change that makes libreboot development easier. At present, there are boards maintained in libreboot by different people. By doing it this way, that becomes much easier. This is in contrast to the present situation, where a change to one board potentially affects all other boards, especially when updating to a new version of coreboot. Coreboot-libre scripts, download scripts, build scripts - everything. The entire build system has been modified to reflect this change of development. For reasons of consistency, cbfstool and nvramtool are no longer included in the util archives.
Diffstat (limited to 'resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch')
-rw-r--r--resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch621
1 files changed, 621 insertions, 0 deletions
diff --git a/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch b/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch
new file mode 100644
index 0000000..3b3da91
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch
@@ -0,0 +1,621 @@
+From ccebca23a1e58cc82d9e2d48642ee604ebbcd3b9 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Sat, 5 Sep 2015 17:46:38 -0500
+Subject: [PATCH 008/143] southbridge/amd/sr5650: Fix boot failure on ASUS
+ KGPE-D16
+
+Change-Id: Ia13ba58118a826e830a4dc6e2378b76110fcabad
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/southbridge/amd/sr5650/acpi/sr5650.asl | 388 ++++++++++++++++++++++++++++
+ src/southbridge/amd/sr5650/early_setup.c | 7 +-
+ src/southbridge/amd/sr5650/ht.c | 3 +-
+ src/southbridge/amd/sr5650/pcie.c | 37 ++-
+ src/southbridge/amd/sr5650/sr5650.c | 51 ++--
+ 5 files changed, 456 insertions(+), 30 deletions(-)
+ create mode 100644 src/southbridge/amd/sr5650/acpi/sr5650.asl
+
+diff --git a/src/southbridge/amd/sr5650/acpi/sr5650.asl b/src/southbridge/amd/sr5650/acpi/sr5650.asl
+new file mode 100644
+index 0000000..a6ab114
+--- /dev/null
++++ b/src/southbridge/amd/sr5650/acpi/sr5650.asl
+@@ -0,0 +1,388 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2009 Advanced Micro Devices, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++Scope(\) {
++ Name(PCBA, 0xE0000000) /* Base address of PCIe config space */
++ Name(HPBA, 0xFED00000) /* Base address of HPET table */
++
++ /* PIC IRQ mapping registers, C00h-C01h */
++ OperationRegion(PRQM, SystemIO, 0x00000C00, 0x00000002)
++ Field(PRQM, ByteAcc, NoLock, Preserve) {
++ PRQI, 0x00000008,
++ PRQD, 0x00000008, /* Offset: 1h */
++ }
++ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) {
++ PINA, 0x00000008, /* Index 0 */
++ PINB, 0x00000008, /* Index 1 */
++ PINC, 0x00000008, /* Index 2 */
++ PIND, 0x00000008, /* Index 3 */
++ AINT, 0x00000008, /* Index 4 */
++ SINT, 0x00000008, /* Index 5 */
++ , 0x00000008, /* Index 6 */
++ AAUD, 0x00000008, /* Index 7 */
++ AMOD, 0x00000008, /* Index 8 */
++ PINE, 0x00000008, /* Index 9 */
++ PINF, 0x00000008, /* Index A */
++ PING, 0x00000008, /* Index B */
++ PINH, 0x00000008, /* Index C */
++ }
++
++ /* PCI Error control register */
++ OperationRegion(PERC, SystemIO, 0x00000C14, 0x00000001)
++ Field(PERC, ByteAcc, NoLock, Preserve) {
++ SENS, 0x00000001,
++ PENS, 0x00000001,
++ SENE, 0x00000001,
++ PENE, 0x00000001,
++ }
++
++ Scope(\_SB) {
++ /* PCIe Configuration Space for 16 busses */
++ OperationRegion(PCFG, SystemMemory, PCBA, 0x01000000) /* Each bus consumes 1MB */
++ Field(PCFG, ByteAcc, NoLock, Preserve) {
++ /* Byte offsets are computed using the following technique:
++ * ((bus number + 1) * ((device number * 8) * 4096)) + register offset
++ * The 8 comes from 8 functions per device, and 4096 bytes per function config space
++ */
++ Offset(0x00088024), /* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */
++ STB5, 32,
++ Offset(0x00098042), /* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */
++ PT0D, 1,
++ PT1D, 1,
++ PT2D, 1,
++ PT3D, 1,
++ PT4D, 1,
++ PT5D, 1,
++ PT6D, 1,
++ PT7D, 1,
++ PT8D, 1,
++ PT9D, 1,
++ Offset(0x000A0004), /* Byte offset to SMBUS register 4h - Bus 0, Device 20, Function 0 */
++ SBIE, 1,
++ SBME, 1,
++ Offset(0x000A0008), /* Byte offset to SMBUS register 8h - Bus 0, Device 20, Function 0 */
++ SBRI, 8,
++ Offset(0x000A0014), /* Byte offset to SMBUS register 14h - Bus 0, Device 20, Function 0 */
++ SBB1, 32,
++ Offset(0x000A0078), /* Byte offset to SMBUS register 78h - Bus 0, Device 20, Function 0 */
++ ,14,
++ P92E, 1, /* Port92 decode enable */
++ }
++
++ OperationRegion(SB5, SystemMemory, STB5, 0x1000)
++ Field(SB5, AnyAcc, NoLock, Preserve){
++ /* Port 0 */
++ Offset(0x120), /* Port 0 Task file status */
++ P0ER, 1,
++ , 2,
++ P0DQ, 1,
++ , 3,
++ P0BY, 1,
++ Offset(0x128), /* Port 0 Serial ATA status */
++ P0DD, 4,
++ , 4,
++ P0IS, 4,
++ Offset(0x12C), /* Port 0 Serial ATA control */
++ P0DI, 4,
++ Offset(0x130), /* Port 0 Serial ATA error */
++ , 16,
++ P0PR, 1,
++
++ /* Port 1 */
++ offset(0x1A0), /* Port 1 Task file status */
++ P1ER, 1,
++ , 2,
++ P1DQ, 1,
++ , 3,
++ P1BY, 1,
++ Offset(0x1A8), /* Port 1 Serial ATA status */
++ P1DD, 4,
++ , 4,
++ P1IS, 4,
++ Offset(0x1AC), /* Port 1 Serial ATA control */
++ P1DI, 4,
++ Offset(0x1B0), /* Port 1 Serial ATA error */
++ , 16,
++ P1PR, 1,
++
++ /* Port 2 */
++ Offset(0x220), /* Port 2 Task file status */
++ P2ER, 1,
++ , 2,
++ P2DQ, 1,
++ , 3,
++ P2BY, 1,
++ Offset(0x228), /* Port 2 Serial ATA status */
++ P2DD, 4,
++ , 4,
++ P2IS, 4,
++ Offset(0x22C), /* Port 2 Serial ATA control */
++ P2DI, 4,
++ Offset(0x230), /* Port 2 Serial ATA error */
++ , 16,
++ P2PR, 1,
++
++ /* Port 3 */
++ Offset(0x2A0), /* Port 3 Task file status */
++ P3ER, 1,
++ , 2,
++ P3DQ, 1,
++ , 3,
++ P3BY, 1,
++ Offset(0x2A8), /* Port 3 Serial ATA status */
++ P3DD, 4,
++ , 4,
++ P3IS, 4,
++ Offset(0x2AC), /* Port 3 Serial ATA control */
++ P3DI, 4,
++ Offset(0x2B0), /* Port 3 Serial ATA error */
++ , 16,
++ P3PR, 1,
++ }
++
++ Method(CIRQ, 0x00, NotSerialized){
++ Store(0, PINA)
++ Store(0, PINB)
++ Store(0, PINC)
++ Store(0, PIND)
++ Store(0, PINE)
++ Store(0, PINF)
++ Store(0, PING)
++ Store(0, PINH)
++ }
++
++ /* set "A", 8259 interrupts */
++ Name (PRSA, ResourceTemplate () {
++ IRQ(Level, ActiveLow, Exclusive) {4, 7, 10, 11, 12, 14, 15}
++ })
++
++ Method (CRSA, 1, Serialized) {
++ Name (LRTL, ResourceTemplate() {
++ IRQ(Level, ActiveLow, Shared) {15}
++ })
++ CreateWordField(LRTL, 1, LIRQ)
++ ShiftLeft(1, Arg0, LIRQ)
++ Return (LRTL)
++ }
++
++ Method (SRSA, 1, Serialized) {
++ CreateWordField(Arg0, 1, LIRQ)
++ FindSetRightBit(LIRQ, Local0)
++ if (Local0) {
++ Decrement(Local0)
++ }
++ Return (Local0)
++ }
++
++ Device(LNKA) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 1)
++ Method(_STA, 0) {
++ if (PINA) {
++ Return(0x0B) /* LNKA is invisible */
++ } else {
++ Return(0x09) /* LNKA is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINA)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINA))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINA)
++ }
++ }
++
++ Device(LNKB) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 2)
++ Method(_STA, 0) {
++ if (PINB) {
++ Return(0x0B) /* LNKB is invisible */
++ } else {
++ Return(0x09) /* LNKB is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINB)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINB))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINB)
++ }
++ }
++
++ Device(LNKC) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 3)
++ Method(_STA, 0) {
++ if (PINC) {
++ Return(0x0B) /* LNKC is invisible */
++ } else {
++ Return(0x09) /* LNKC is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINC)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINC))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINC)
++ }
++ }
++
++ Device(LNKD) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 4)
++ Method(_STA, 0) {
++ if (PIND) {
++ Return(0x0B) /* LNKD is invisible */
++ } else {
++ Return(0x09) /* LNKD is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PIND)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PIND))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PIND)
++ }
++ }
++
++ Device(LNKE) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 5)
++ Method(_STA, 0) {
++ if (PINE) {
++ Return(0x0B) /* LNKE is invisible */
++ } else {
++ Return(0x09) /* LNKE is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINE)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINE))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINE)
++ }
++ }
++
++ Device(LNKF) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 6)
++ Method(_STA, 0) {
++ if (PINF) {
++ Return(0x0B) /* LNKF is invisible */
++ } else {
++ Return(0x09) /* LNKF is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINF)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINF))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINF)
++ }
++ }
++
++ Device(LNKG) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 7)
++ Method(_STA, 0) {
++ if (PING) {
++ Return(0x0B) /* LNKG is invisible */
++ } else {
++ Return(0x09) /* LNKG is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PING)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PING))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PING)
++ }
++ }
++
++ Device(LNKH) {
++ Name(_HID, EISAID("PNP0C0F"))
++ Name(_UID, 8)
++ Method(_STA, 0) {
++ if (PINH) {
++ Return(0x0B) /* LNKH is invisible */
++ } else {
++ Return(0x09) /* LNKH is disabled */
++ }
++ }
++ Method(_DIS, 0) {
++ Store(0, PINH)
++ }
++ Method(_PRS, 0) {
++ Return (PRSA)
++ }
++ Method (_CRS, 0, Serialized) {
++ Return (CRSA(PINH))
++ }
++ Method (_SRS, 1, Serialized) {
++ Store (SRSA(Arg0), PINH)
++ }
++ }
++
++ } /* End Scope(_SB) */
++
++} /* End Scope(/) */
+diff --git a/src/southbridge/amd/sr5650/early_setup.c b/src/southbridge/amd/sr5650/early_setup.c
+index ec555f8..664f60a 100644
+--- a/src/southbridge/amd/sr5650/early_setup.c
++++ b/src/southbridge/amd/sr5650/early_setup.c
+@@ -3,6 +3,7 @@
+ *
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -504,7 +505,8 @@ void sr5650_early_setup(void)
+ /*ATINB_PrepareInit */
+ get_cpu_rev();
+
+- switch (get_nb_rev(nb_dev)) { /* PCIEMiscInit */
++ uint8_t revno = get_nb_rev(nb_dev);
++ switch (revno) { /* PCIEMiscInit */
+ case REV_SR5650_A11:
+ printk(BIOS_INFO, "NB Revision is A11.\n");
+ break;
+@@ -514,6 +516,9 @@ void sr5650_early_setup(void)
+ case REV_SR5650_A21:
+ printk(BIOS_INFO, "NB Revision is A21.\n");
+ break;
++ default:
++ printk(BIOS_INFO, "NB Revision is %02x (Unrecognized).\n", revno);
++ break;
+ }
+
+ fam10_optimization();
+diff --git a/src/southbridge/amd/sr5650/ht.c b/src/southbridge/amd/sr5650/ht.c
+index c497107..02f4f7f 100644
+--- a/src/southbridge/amd/sr5650/ht.c
++++ b/src/southbridge/amd/sr5650/ht.c
+@@ -2,6 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -55,7 +56,7 @@ static const apic_device_info default_apic_device_info_t [] = {
+ [13] = {4, ABCD, 30} /* Dev13 Grp4 [Int - 16..19] */
+ };
+
+-/* Their name are quite regular. So I undefine them. */
++/* These define names are common, so undefine them to avoid potential issues in other code */
+ #undef ABCD
+ #undef BCDA
+ #undef CDAB
+diff --git a/src/southbridge/amd/sr5650/pcie.c b/src/southbridge/amd/sr5650/pcie.c
+index 3720a61..d306b5a 100644
+--- a/src/southbridge/amd/sr5650/pcie.c
++++ b/src/southbridge/amd/sr5650/pcie.c
+@@ -2,6 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -61,8 +62,10 @@ static void ValidatePortEn(device_t nb_dev)
+ *****************************************************************/
+ static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
+ {
++ printk(BIOS_DEBUG, "PciePowerOffGppPorts() port %d\n", port);
+ u32 reg;
+ u16 state_save;
++ uint8_t i;
+ struct southbridge_amd_sr5650_config *cfg =
+ (struct southbridge_amd_sr5650_config *)nb_dev->chip_info;
+ u16 state = cfg->port_enable;
+@@ -72,6 +75,28 @@ static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
+ state = ~state;
+ state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7);
+ state_save = state << 17;
++ /* Disable ports any that failed training */
++ for (i = 9; i <= 13; i++) {
++ if (!(AtiPcieCfg.PortDetect & 1 << i)) {
++ if ((port >= 9) && (port <= 13)) {
++ state |= (1 << (port + 7));
++ }
++ if (port == 9)
++ state_save |= 1 << 25;
++ if (port == 10)
++ state_save |= 1 << 26;
++ if (port == 11)
++ state_save |= 1 << 6;
++ if (port == 12)
++ state_save |= 1 << 7;
++
++ if (port == 13) {
++ reg = nbmisc_read_index(nb_dev, 0x2a);
++ reg |= 1 << 4;
++ nbmisc_write_index(nb_dev, 0x2a, reg);
++ }
++ }
++ }
+ state &= !(AtiPcieCfg.PortHp);
+ reg = nbmisc_read_index(nb_dev, 0x0c);
+ reg |= state;
+@@ -483,6 +508,8 @@ static void EnableLclkGating(device_t dev)
+ *****************************************/
+ void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
+ {
++ uint8_t training_ok = 1;
++
+ u32 gpp_sb_sel = 0;
+ struct southbridge_amd_sr5650_config *cfg =
+ (struct southbridge_amd_sr5650_config *)nb_dev->chip_info;
+@@ -701,6 +728,12 @@ void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
+ printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res);
+ if (res) {
+ AtiPcieCfg.PortDetect |= 1 << port;
++ } else {
++ /* If the training failed the disable the bridge to prevent subsequent
++ * lockup on bridge configuration register read during the PCI bus scan
++ */
++ training_ok = 0;
++ dev->enabled = 0;
+ }
+ }
+ }
+@@ -747,8 +780,8 @@ void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
+ * wait dev 0x6B bit3 clear
+ */
+
+- if (port == 8){
+- PciePowerOffGppPorts(nb_dev, dev, port); /* , This should be run for all ports that are not hotplug and don't detect devices */
++ if ((port == 8) || (!training_ok)) {
++ PciePowerOffGppPorts(nb_dev, dev, port); /* This is run for all ports that are not hotplug and don't detect devices */
+ }
+ }
+
+diff --git a/src/southbridge/amd/sr5650/sr5650.c b/src/southbridge/amd/sr5650/sr5650.c
+index 441be66..75383de 100644
+--- a/src/southbridge/amd/sr5650/sr5650.c
++++ b/src/southbridge/amd/sr5650/sr5650.c
+@@ -2,6 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -95,32 +96,30 @@ void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data)
+ void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
+ {
+ /* K8 Function1 is address map */
+- device_t k8_f1;
+- device_t np = dev_find_slot(0, PCI_DEVFN(0x19, 1));
+- u16 node;
+-
+- for (node = 0; node < CONFIG_MAX_PHYSICAL_CPUS; node++) {
+- k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18 + node, 1));
+- if (!k8_f1) {
+- break;
+- }
+-
+- if (in_out) {
+- /* Fill MMIO limit/base pair. */
+- pci_write_config32(k8_f1, 0xbc,
+- (((pcie_base_add + 0x10000000 -
+- 1) >> 8) & 0xffffff00) | 0x8 | (np ? 2 << 4 : 0 << 4));
+- pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
+- pci_write_config32(k8_f1, 0xb4,
+- ((mmio_base_add + 0x10000000 -
+- 1) >> 8) | (np ? 2 << 4 : 0 << 4));
+- pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
+- } else {
+- pci_write_config32(k8_f1, 0xb8, 0);
+- pci_write_config32(k8_f1, 0xbc, 0);
+- pci_write_config32(k8_f1, 0xb0, 0);
+- pci_write_config32(k8_f1, 0xb4, 0);
+- }
++ device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
++ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
++
++ if (in_out) {
++ u32 dword, sblk;
++
++ /* Get SBLink value (HyperTransport I/O Hub Link ID). */
++ dword = pci_read_config32(k8_f0, 0x64);
++ sblk = (dword >> 8) & 0x3;
++
++ /* Fill MMIO limit/base pair. */
++ pci_write_config32(k8_f1, 0xbc,
++ (((pcie_base_add + 0x10000000 -
++ 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
++ pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
++ pci_write_config32(k8_f1, 0xb4,
++ (((mmio_base_add + 0x10000000 -
++ 1) >> 8) & 0xffffff00) | (sblk << 4));
++ pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
++ } else {
++ pci_write_config32(k8_f1, 0xb8, 0);
++ pci_write_config32(k8_f1, 0xbc, 0);
++ pci_write_config32(k8_f1, 0xb0, 0);
++ pci_write_config32(k8_f1, 0xb4, 0);
+ }
+ }
+
+--
+1.7.9.5
+