summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx
diff options
context:
space:
mode:
authorKerry Sheh <shekairui@gmail.com>2012-01-31 20:39:37 +0800
committerPatrick Georgi <patrick@georgi-clan.de>2012-02-02 13:54:36 +0100
commit9292d89be84d6abf9257ddb872887d4f53b2a00e (patch)
tree9eaa548f1742745f57fc92a12734649fec8db1cd /src/vendorcode/amd/cimx
parent17670866a0d12839bc2a4c852210ccf11d3cb4b2 (diff)
downloadcoreboot-9292d89be84d6abf9257ddb872887d4f53b2a00e.tar.xz
RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code
Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06 Signed-off-by: Kerry Sheh <kerry.she@amd.com> Signed-off-by: Kerry Sheh <shekairui@gmail.com> Reviewed-on: http://review.coreboot.org/557 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/cimx')
-rw-r--r--src/vendorcode/amd/cimx/Makefile.inc1
-rw-r--r--src/vendorcode/amd/cimx/rd890/HotplugFirmware.h1397
-rw-r--r--src/vendorcode/amd/cimx/rd890/Makefile.inc118
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c236
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h77
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiLib.c186
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiLib.h136
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c148
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h66
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c436
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h54
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdSbLib.c216
-rw-r--r--src/vendorcode/amd/cimx/rd890/amdSbLib.h85
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbDef.h532
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbDispatcher.c201
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbEventLog.c106
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbEventLog.h95
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbHtInit.c626
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbHtInit.h126
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbHtInterface.c125
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbInit.c417
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbInit.h107
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbInitializer.c133
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbInitializer.h57
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbInterface.c312
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbIoApic.c194
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbIoApic.h52
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbIommu.c1737
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbIommu.h326
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbLib.c1138
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbLib.h352
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c121
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h63
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S117
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbMiscInit.c123
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbMiscInit.h57
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbModuleInfo.c70
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcie.h352
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieAspm.c507
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieAspm.h131
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c105
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h52
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c475
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c343
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h62
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c720
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c505
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c486
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieLib.c1604
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c160
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h60
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPciePllControl.c193
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPciePllControl.h63
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c182
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h52
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c753
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieSb.c195
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieSb.h71
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c436
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h65
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c383
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbRecovery.c192
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbRecovery.h53
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c98
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbRegisters.h420
-rw-r--r--src/vendorcode/amd/cimx/rd890/nbType.h1075
66 files changed, 20136 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/Makefile.inc b/src/vendorcode/amd/cimx/Makefile.inc
index bb9b78c88f..36223127ec 100644
--- a/src/vendorcode/amd/cimx/Makefile.inc
+++ b/src/vendorcode/amd/cimx/Makefile.inc
@@ -1,2 +1,3 @@
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += sb800
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += sb900
+subdirs-$(CONFIG_NORTHBRIDGE_AMD_CIMX_RD890) += rd890
diff --git a/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h b/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h
new file mode 100644
index 0000000000..a0b416fd68
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h
@@ -0,0 +1,1397 @@
+/**
+ * @file
+ *
+ * SMU firmware.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 18962 \$ @e \$Date: 2009-09-07 20:35:39 -0700 (Mon, 07 Sep 2009) \$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+
+#ifndef _HOTPLUGFIRMWARE_H_
+#define _HOTPLUGFIRMWARE_H_
+
+UINT32 DataBlock0[] = {
+ 0xbdff018e,
+ 0x16ceee15,
+ 0x1cce1807,
+ 0xa6082000,
+ 0x00a71800,
+ 0x8c081808,
+ 0xf3256716,
+ 0x270000cc,
+ 0x601cce0b,
+ 0x8308006f,
+ 0xf8260100,
+ 0x16bd098d,
+ 0x02fb2003,
+ 0xde1c0206,
+ 0x9f343c06,
+ 0xbd0fc606,
+ 0x06de0004,
+ 0xfece016f,
+ 0xe702c668,
+ 0x69fece00,
+ 0x1806de18,
+ 0x00e701e6,
+ 0xe764fece,
+ 0x18c4c600,
+ 0x1865fece,
+ 0xffc600e7,
+ 0x66fece18,
+ 0xce00e718,
+ 0x00e767fe,
+ 0x1806de18,
+ 0x1cf701e6,
+ 0xf704c600,
+ 0x06bd041c,
+ 0x06de18e0,
+ 0xf701e618,
+ 0xfece001c,
+ 0xf600e764,
+ 0xce18011c,
+ 0xe71865fe,
+ 0x021cf600,
+ 0xe766fece,
+ 0x031cf600,
+ 0x67fece18,
+ 0xf600e718,
+ 0xffce4b1c,
+ 0xf600e78e,
+ 0xffce4a1c,
+ 0xbd00e78d,
+ 0x00cc2b06,
+ 0x7efece01,
+ 0x07bd00ed,
+ 0x0200ce2b,
+ 0x7efece18,
+ 0xbd00efcd,
+ 0x00ce8407,
+ 0xfece1803,
+ 0x00efcd7e,
+ 0xe674fece,
+ 0x2601c100,
+ 0x06de181a,
+ 0x3701e618,
+ 0x081ccc34,
+ 0x31480fbd,
+ 0x6c06de31,
+ 0xc101e601,
+ 0xcee62307,
+ 0xce180400,
+ 0xefcd7efe,
+ 0x4b1cf600,
+ 0x1cf702ca,
+ 0x8effce4b,
+ 0xfece00e7,
+ 0x2600e675,
+ 0x0812bd03,
+ 0xfd8009bd,
+ 0x1c2a101c,
+ 0x180500ce,
+ 0xcd7efece,
+ 0x01c600ef,
+ 0xce540bbd,
+ 0xce180600,
+ 0xefcd7efe,
+ 0xfe200e00,
+ 0x0cbd01c6,
+ 0xbd01c690,
+ 0x00ce9a10,
+ 0xfece1807,
+ 0x00efcd7e,
+ 0x540bbd5f,
+ 0x180800ce,
+ 0xcd7efece,
+ 0xffce00ef,
+ 0xe701c68f,
+ 0x00ce0e00,
+ 0x00efcd09,
+ 0x274e1cf6,
+ 0x1cf75f29,
+ 0x0a00ce4e,
+ 0x7efece18,
+ 0xc600efcd,
+ 0x900cbd01,
+ 0x10bd00c6,
+ 0x0b00ce9a,
+ 0x7efece18,
+ 0xce00efcd,
+ 0x01c68fff,
+ 0xffce00e7,
+ 0xf700e687,
+ 0x01c54d1c,
+ 0x00ce1a27,
+ 0xfece180c,
+ 0x00efcd7e,
+ 0xbd5f1ccc,
+ 0x00cefa0a,
+ 0xfece180d,
+ 0x00efcd7e,
+ 0xe675fece,
+ 0x18a52600,
+ 0x1823f0ce,
+ 0x80c400e6,
+ 0x00cc9a27,
+ 0x7efece10,
+ 0x11bd00ed,
+ 0xf0ce181c,
+ 0x001c1823,
+ 0x1100cc80,
+ 0xed7efece,
+ 0x7c037e00,
+ 0x9f3c06de,
+ 0x3c08de06,
+ 0xd73c0ade,
+ 0x3d10ce0b,
+ 0xf0c400e6,
+ 0x0bd68f18,
+ 0x00dd8f18,
+ 0x01da8f18,
+ 0xdf3800e7,
+ 0x08df380a,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0x08de069f,
+ 0x3c0ade3c,
+ 0x0bee06de,
+ 0x1cf70adf,
+ 0x06de1800,
+ 0x1809ee18,
+ 0x1cf700e6,
+ 0xf718c607,
+ 0xde18061c,
+ 0x08e61806,
+ 0x7f041cf7,
+ 0x007f0900,
+ 0xe006bd08,
+ 0xfdbe05bd,
+ 0x152a101c,
+ 0x1cf709d6,
+ 0x7f032006,
+ 0x06bd061c,
+ 0xfa05bde0,
+ 0x20101cfc,
+ 0x08de1877,
+ 0x240a9c18,
+ 0x1a06de54,
+ 0x081809ee,
+ 0xbd01ef1a,
+ 0x1cfd0e06,
+ 0xdcd82b10,
+ 0xffffc30a,
+ 0x2708931a,
+ 0xf708c638,
+ 0x06bd061c,
+ 0x06de18e0,
+ 0x1801ee18,
+ 0x1cf700e6,
+ 0xf718c607,
+ 0xde18061c,
+ 0x08e61806,
+ 0xbd041cf7,
+ 0x06dee006,
+ 0x1801ee1a,
+ 0x01ef1a08,
+ 0xdf0808de,
+ 0x250a9c08,
+ 0x1cf75fb6,
+ 0xe006bd06,
+ 0x1cf712c6,
+ 0xe006bd06,
+ 0x5ffa05bd,
+ 0xbd061cf7,
+ 0x5f4fe006,
+ 0x380adf38,
+ 0x383808df,
+ 0xde3906df,
+ 0x069f3c06,
+ 0xde3c08de,
+ 0x0cde3c0a,
+ 0xee06de3c,
+ 0x180cdf07,
+ 0xee1806de,
+ 0x0adf1809,
+ 0x7f09007f,
+ 0x1cf70800,
+ 0xf714c600,
+ 0xde18061c,
+ 0x06e61806,
+ 0xbd041cf7,
+ 0x05bde006,
+ 0x101cfdbe,
+ 0x09d6102a,
+ 0xbd061cf7,
+ 0x05bde006,
+ 0x101cfcfa,
+ 0xde185f20,
+ 0x0a9c1808,
+ 0x05bd3d24,
+ 0x0cde18e5,
+ 0x00df08de,
+ 0x00d38f18,
+ 0x1cf68f18,
+ 0x00e71804,
+ 0xffc30adc,
+ 0x08931aff,
+ 0x04c61d27,
+ 0xbd061cf7,
+ 0x14c6e006,
+ 0xbd061cf7,
+ 0xde18e006,
+ 0x18081808,
+ 0x9c1808df,
+ 0x5fc3250a,
+ 0xbd061cf7,
+ 0x12c6e006,
+ 0xbd061cf7,
+ 0x528de006,
+ 0x061cf75f,
+ 0x4fe006bd,
+ 0x0cdf385f,
+ 0x380adf38,
+ 0xdf3808df,
+ 0x06de3906,
+ 0xbd069f3c,
+ 0x1cf67306,
+ 0x2702c505,
+ 0x205f4f04,
+ 0x2708c510,
+ 0xffffcc05,
+ 0x04c50720,
+ 0xffcce527,
+ 0x06df38fe,
+ 0x3c06de39,
+ 0x06bd069f,
+ 0x051cf673,
+ 0xf62701c4,
+ 0xdf385f4f,
+ 0x06de3906,
+ 0x8d069f3c,
+ 0x051cf672,
+ 0xf72740c4,
+ 0xdf385f4f,
+ 0x06de3906,
+ 0x8d069f3c,
+ 0x061cf65e,
+ 0xf72701c5,
+ 0x042602c5,
+ 0x03205f4f,
+ 0x38faffcc,
+ 0xde3906df,
+ 0x069f3c06,
+ 0x001cf75f,
+ 0xf7041c7f,
+ 0x01c6051c,
+ 0x5f061cf7,
+ 0xbd071cf7,
+ 0x0e8de006,
+ 0x5f101cfd,
+ 0xbd061cf7,
+ 0xdf38e006,
+ 0x06de3906,
+ 0x8d069f3c,
+ 0x051cf616,
+ 0x042720c5,
+ 0x07205f4f,
+ 0xef2710c5,
+ 0x38fdffcc,
+ 0xde3906df,
+ 0x9f3c3c06,
+ 0x67fece06,
+ 0xfece00e6,
+ 0xc400e660,
+ 0x831a4f03,
+ 0x08270100,
+ 0x0200831a,
+ 0xe5201a27,
+ 0xe668fece,
+ 0x041cf700,
+ 0xe669fece,
+ 0x06de1800,
+ 0xce01e718,
+ 0x16206afe,
+ 0xe66cfece,
+ 0x041cf700,
+ 0xe66dfece,
+ 0x06de1800,
+ 0xce01e718,
+ 0x00e66efe,
+ 0xe602e718,
+ 0x071cf700,
+ 0x1806de18,
+ 0x1cf702e6,
+ 0x01e61806,
+ 0x38051cf7,
+ 0x3906df38,
+ 0x9f3c06de,
+ 0x001cf606,
+ 0xe764fece,
+ 0x071cf600,
+ 0xe763fece,
+ 0x061cf600,
+ 0xe762fece,
+ 0x051cf600,
+ 0xe761fece,
+ 0x60fece00,
+ 0xe7041cf6,
+ 0xc400e600,
+ 0xce0b2704,
+ 0x00e660fe,
+ 0xf72604c4,
+ 0xfece0920,
+ 0xc400e660,
+ 0x38f72704,
+ 0xde3906df,
+ 0x3c3c3c06,
+ 0x06de069f,
+ 0x0ec6026f,
+ 0x1806de18,
+ 0x183d02a6,
+ 0x1cc303ed,
+ 0x0100ce12,
+ 0x1808183c,
+ 0x0000ce3c,
+ 0x188f183c,
+ 0x05bd00e6,
+ 0x38383803,
+ 0x112600dd,
+ 0xee1a06de,
+ 0xc38f1803,
+ 0x8f181b1c,
+ 0xe71801c6,
+ 0x06de1800,
+ 0x18026c18,
+ 0x03c102e6,
+ 0x3838b823,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0x069f343c,
+ 0x016f06de,
+ 0xde180ec6,
+ 0x01a61806,
+ 0x02ed183d,
+ 0x181b1cc3,
+ 0x00e6188f,
+ 0x712601c1,
+ 0x1806de18,
+ 0x1cc302ec,
+ 0x04ed1812,
+ 0x3c0200ce,
+ 0xc302ec18,
+ 0x3637171c,
+ 0x0400ce18,
+ 0x06de3c18,
+ 0x00e604ee,
+ 0xfd2c04bd,
+ 0x3838101c,
+ 0xce422b38,
+ 0x183c0200,
+ 0xec1806de,
+ 0x131cc302,
+ 0xcd3c3637,
+ 0x00e604ee,
+ 0xfd2c04bd,
+ 0x3838101c,
+ 0xce222b38,
+ 0x183c0200,
+ 0xec1806de,
+ 0x191cc302,
+ 0x00ce3637,
+ 0xee183c06,
+ 0x00e61804,
+ 0xfd2c04bd,
+ 0x3838101c,
+ 0x6c06de38,
+ 0xc101e601,
+ 0x7e032203,
+ 0x5f4f9007,
+ 0x38313838,
+ 0xde3906df,
+ 0x3c3c3c06,
+ 0xde069f3c,
+ 0x0ade3c08,
+ 0x3c0cde3c,
+ 0x01e706de,
+ 0x54545454,
+ 0x1cc34f54,
+ 0x188f1808,
+ 0x03e700e6,
+ 0x08c502ec,
+ 0x087e0326,
+ 0x5801e6eb,
+ 0x09d710c4,
+ 0x585801e6,
+ 0xe7585858,
+ 0x1880c401,
+ 0x1809d68f,
+ 0x1800dd8f,
+ 0x1801da8f,
+ 0xc401e68f,
+ 0x1800dd40,
+ 0x1801da8f,
+ 0xc401e68f,
+ 0x1800dd20,
+ 0xd701da8f,
+ 0xe68f180b,
+ 0x03c45403,
+ 0x02ec06e7,
+ 0xdd01c44f,
+ 0xa60ec608,
+ 0x0cdd3d06,
+ 0x0cd308dc,
+ 0x1cc304ed,
+ 0xd68f1813,
+ 0x00e7180b,
+ 0xc38f0cde,
+ 0x188f121c,
+ 0x180100ce,
+ 0x06de183c,
+ 0xc304ec18,
+ 0x3637131c,
+ 0x00c308dc,
+ 0x1808dd02,
+ 0x3c1808de,
+ 0x04bd00e6,
+ 0x101cfd2c,
+ 0x38383838,
+ 0xdf380cdf,
+ 0x08df380a,
+ 0x38383838,
+ 0xde3906df,
+ 0x02de3c00,
+ 0x3c04de3c,
+ 0x9f3c06de,
+ 0xf701c606,
+ 0xffce4e1c,
+ 0x38006f8f,
+ 0xdf3806df,
+ 0x02df3804,
+ 0x3b00df38,
+ 0xde3c00de,
+ 0x04de3c02,
+ 0x3c06de3c,
+ 0xb407069f,
+ 0x0e06bf00,
+ 0x3806df38,
+ 0xdf3804df,
+ 0x00df3802,
+ 0x3c00de3b,
+ 0xde3c02de,
+ 0x06de3c04,
+ 0x38069f3c,
+ 0xdf3806df,
+ 0x02df3804,
+ 0x3b00df38,
+ 0xde3c00de,
+ 0x04de3c02,
+ 0x3c06de3c,
+ 0xdf38069f,
+ 0x04df3806,
+ 0x3802df38,
+ 0xde3b00df,
+ 0x069f3c06,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0x069f343c,
+ 0xde3c08de,
+ 0x0cde3c0a,
+ 0x6f06de3c,
+ 0x0dd75f01,
+ 0xdd081ccc,
+ 0xde04df02,
+ 0x1800e602,
+ 0xe71806de,
+ 0x04ec1805,
+ 0x08c504de,
+ 0x0a7e0326,
+ 0x05e61836,
+ 0x1803c454,
+ 0x06de02e7,
+ 0x05e68f18,
+ 0x8f1801c4,
+ 0xdf18054f,
+ 0x4f01db00,
+ 0xcc8f0fc4,
+ 0x15bd0100,
+ 0xc60bd7f1,
+ 0xa606de0e,
+ 0x08dd3d02,
+ 0xed1b1cc3,
+ 0x00e68f04,
+ 0x2d2601c1,
+ 0x00df184f,
+ 0x08d301d6,
+ 0x1806de18,
+ 0x1cc304ed,
+ 0x01c68f1c,
+ 0x06de00e7,
+ 0x1804ee1a,
+ 0x1e1cc38f,
+ 0x01e68f18,
+ 0xd600e718,
+ 0x270bd50d,
+ 0xfbffcc05,
+ 0x8f182f20,
+ 0x8f180dd6,
+ 0x8f0bd68f,
+ 0x8f1800df,
+ 0x0dd701da,
+ 0x04df8f18,
+ 0x180802de,
+ 0x6c1806de,
+ 0x01e61801,
+ 0x04de02df,
+ 0x032207c1,
+ 0x4f9d097e,
+ 0x0cdf385f,
+ 0x380adf38,
+ 0x383808df,
+ 0x06df3831,
+ 0x3c06de39,
+ 0x9f3c3c3c,
+ 0xe706de06,
+ 0xf7fec404,
+ 0xffce4a1c,
+ 0xde00e78d,
+ 0xc404e606,
+ 0xfa585801,
+ 0x01ca4b1c,
+ 0xce4b1cf7,
+ 0x00e78eff,
+ 0x1806de18,
+ 0xffce026f,
+ 0x1800e686,
+ 0xe71806de,
+ 0x05ec1806,
+ 0x052710c5,
+ 0xe71801c6,
+ 0x06de1802,
+ 0x27026d18,
+ 0x06e618e1,
+ 0xf64c1cf7,
+ 0x02c44b1c,
+ 0xf704e718,
+ 0xf75f4b1c,
+ 0xffce4a1c,
+ 0x04e6188e,
+ 0xffce00e7,
+ 0x00e75f8d,
+ 0xe686ffce,
+ 0x06de1800,
+ 0xc403e718,
+ 0x18032610,
+ 0x06de02e7,
+ 0xe826026d,
+ 0x1cf703e6,
+ 0x385f4f4c,
+ 0xdf383838,
+ 0x06de3906,
+ 0x069f3c3c,
+ 0x01c68f18,
+ 0x01e706de,
+ 0xe686ffce,
+ 0x4c1cf700,
+ 0xbd00e718,
+ 0x1cf62f08,
+ 0xf710ca4b,
+ 0xffce4b1c,
+ 0xce00e78e,
+ 0x00e687ff,
+ 0x1806de18,
+ 0x01c402e7,
+ 0xe7180326,
+ 0x6d06de01,
+ 0xe6e82601,
+ 0x4d1cf702,
+ 0xc44b1cf6,
+ 0x4b1cf702,
+ 0xe78effce,
+ 0x385f4f00,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0x9f343c3c,
+ 0x3c08de06,
+ 0x026f06de,
+ 0x7e03265d,
+ 0xde18ee0b,
+ 0x02e61806,
+ 0x58585858,
+ 0x01e71858,
+ 0x10011c18,
+ 0xbd01e618,
+ 0x06de610a,
+ 0x02e6026c,
+ 0xde2307c1,
+ 0xde18026f,
+ 0x02e61806,
+ 0x58585858,
+ 0x01e71858,
+ 0x18011c18,
+ 0xbd01e618,
+ 0x06de610a,
+ 0x02e6026c,
+ 0xde2307c1,
+ 0xde18026f,
+ 0x02e61806,
+ 0x58585858,
+ 0x1808ca58,
+ 0x0abd01e7,
+ 0x6c06de61,
+ 0xc102e602,
+ 0x6fe32307,
+ 0x06de1802,
+ 0x5802e618,
+ 0x58585858,
+ 0xbd01e718,
+ 0x06de610a,
+ 0x02e6026c,
+ 0xe52307c1,
+ 0xde187620,
+ 0x026f1806,
+ 0xcd081cce,
+ 0xde1805ef,
+ 0x05ee1806,
+ 0x1800e618,
+ 0xe71806de,
+ 0x03ec1804,
+ 0x402708c5,
+ 0x5404e618,
+ 0xe71803c4,
+ 0x03ec1807,
+ 0xdd01c44f,
+ 0x0ec68f08,
+ 0x9600df8f,
+ 0x07e61801,
+ 0xc308d33d,
+ 0x8f18151c,
+ 0x02e606de,
+ 0x58585858,
+ 0x1801e758,
+ 0x01c400e6,
+ 0x01e701ea,
+ 0xe608011c,
+ 0x610abd01,
+ 0xcd06de18,
+ 0xcd0805ee,
+ 0x6c1805ef,
+ 0x02e61802,
+ 0x962307c1,
+ 0x3808df38,
+ 0x38313838,
+ 0xde3906df,
+ 0x069f3c06,
+ 0xdd3c08de,
+ 0x1a5f4f08,
+ 0x09240893,
+ 0x0100c301,
+ 0x2508931a,
+ 0x08df38f7,
+ 0x3906df38,
+ 0x303c06de,
+ 0xefffc38f,
+ 0x069f358f,
+ 0x05e706de,
+ 0x01ed5f4f,
+ 0x07e703ed,
+ 0x05e608e7,
+ 0x0cc60426,
+ 0xde1807e7,
+ 0x066f1806,
+ 0x06de0ec6,
+ 0xed3d06a6,
+ 0x1b1cc309,
+ 0xe6188f18,
+ 0x2701c100,
+ 0x560e7e03,
+ 0x1809ee1a,
+ 0x1c1cc38f,
+ 0xe6188f18,
+ 0x2701c100,
+ 0xf60d7e03,
+ 0x1809ee1a,
+ 0x1d1cc38f,
+ 0xe6188f18,
+ 0x2701c100,
+ 0x940d7e03,
+ 0x1cc309ec,
+ 0x00ce1812,
+ 0xce3c1802,
+ 0xd38f0300,
+ 0x183c8f06,
+ 0x180000ce,
+ 0x00e68f3c,
+ 0xfd0305bd,
+ 0x3838101c,
+ 0x7e032a38,
+ 0xde18560e,
+ 0x03e61806,
+ 0xe7180fc4,
+ 0x03e7180b,
+ 0xc404e618,
+ 0x0ce7180f,
+ 0xde04e718,
+ 0x09ee1a06,
+ 0x1cc38f18,
+ 0xe68f1815,
+ 0x180de70b,
+ 0x112600e1,
+ 0x1809ee1a,
+ 0x161cc38f,
+ 0x0ce68f18,
+ 0x2700e118,
+ 0x06de180d,
+ 0xc105e618,
+ 0x18032601,
+ 0x0ec6076f,
+ 0x06a606de,
+ 0xc310ed3d,
+ 0x188f151c,
+ 0xe61806de,
+ 0xde00e70d,
+ 0x10ee1a06,
+ 0x1cc38f18,
+ 0xe68f1816,
+ 0x530e7e04,
+ 0x1806de18,
+ 0x1cc309ec,
+ 0x0100ce12,
+ 0x0806de3c,
+ 0x183c0808,
+ 0x180000ce,
+ 0x00e68f3c,
+ 0xfd0305bd,
+ 0x3838101c,
+ 0x7e032a38,
+ 0x06de560e,
+ 0x0fc403e6,
+ 0xde1803e7,
+ 0x09eecd06,
+ 0x151cc38f,
+ 0x0ee7188f,
+ 0x0a2700e1,
+ 0xc105e618,
+ 0x18032601,
+ 0x0ec6076f,
+ 0x1806de18,
+ 0xc33d06a6,
+ 0x8f18151c,
+ 0x0ee606de,
+ 0xde185d20,
+ 0x09ec1806,
+ 0xce121cc3,
+ 0xde3c0100,
+ 0x08080806,
+ 0x00ce183c,
+ 0x8f3c1801,
+ 0x05bd00e6,
+ 0x101cfd03,
+ 0x2b383838,
+ 0xe606de39,
+ 0xe70fc403,
+ 0x06de1803,
+ 0x8f09eecd,
+ 0x8f161cc3,
+ 0xe10fe718,
+ 0x180a2700,
+ 0x01c105e6,
+ 0x6f180326,
+ 0x180ec607,
+ 0xa61806de,
+ 0x1cc33d06,
+ 0xde8f1816,
+ 0x180fe606,
+ 0xde1800e7,
+ 0x066c1806,
+ 0xc106e618,
+ 0x7e032203,
+ 0xe618b80c,
+ 0x260cc107,
+ 0x1801c607,
+ 0x062008e7,
+ 0x1806de18,
+ 0x06de076c,
+ 0x0326086d,
+ 0x30b20c7e,
+ 0x1100c38f,
+ 0xdf38358f,
+ 0x06de3906,
+ 0x3c3c3c3c,
+ 0xde069f3c,
+ 0x0ade3c08,
+ 0x3c0cde3c,
+ 0x08e706de,
+ 0x04e7036f,
+ 0xcd06de18,
+ 0xc38f03ee,
+ 0xe68f081c,
+ 0x06e71800,
+ 0x1803c454,
+ 0xe61801e7,
+ 0x58585808,
+ 0x0bd75858,
+ 0x4f05ec18,
+ 0x0cdd01c4,
+ 0xa6180ec6,
+ 0x08dd3d01,
+ 0x08d30cdc,
+ 0x18151cc3,
+ 0x00e6188f,
+ 0x02e706de,
+ 0x8f1801c4,
+ 0x8f180bd6,
+ 0x8f1800dd,
+ 0x0bd701da,
+ 0x0e6d8f18,
+ 0x02e62c26,
+ 0xc4585858,
+ 0x1800dd10,
+ 0x1801da8f,
+ 0x5802e68f,
+ 0x00dd08c4,
+ 0x01da8f18,
+ 0x02e68f18,
+ 0x02c45454,
+ 0x8f1800dd,
+ 0x0bd701da,
+ 0x0bd68f18,
+ 0xce610abd,
+ 0x00cc7efe,
+ 0x3800ed12,
+ 0xdf380cdf,
+ 0x08df380a,
+ 0x38383838,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0xde069f34,
+ 0x02dd3c08,
+ 0xc44b1cf6,
+ 0x06de18fd,
+ 0x1801e718,
+ 0x188effce,
+ 0x06de00e7,
+ 0x585809e6,
+ 0xfa585858,
+ 0x1cf74a1c,
+ 0x8dffce4a,
+ 0x06de00e7,
+ 0x01ca01e6,
+ 0x184b1cf7,
+ 0x026f00e7,
+ 0xe686ffce,
+ 0x2710c400,
+ 0x1801c608,
+ 0xe71806de,
+ 0x06de1802,
+ 0x27026d18,
+ 0xf700e6e7,
+ 0xffce4c1c,
+ 0xf700e687,
+ 0x02de4d1c,
+ 0x3a09e618,
+ 0xf600e75f,
+ 0x02c44c1c,
+ 0x09d75858,
+ 0x1cf600e7,
+ 0x1804c44c,
+ 0x1809d68f,
+ 0x1800dd8f,
+ 0xd701da8f,
+ 0xd68f1809,
+ 0xf600e709,
+ 0x08c44c1c,
+ 0x00dd5454,
+ 0x01da8f18,
+ 0x8f1809d7,
+ 0x00e709d6,
+ 0xc44d1cf6,
+ 0xe709da01,
+ 0x1cf75f00,
+ 0x4a1cf74b,
+ 0xe78effce,
+ 0x8dffce00,
+ 0xffce00e7,
+ 0x1800e686,
+ 0xe71806de,
+ 0x2610c403,
+ 0x02e71803,
+ 0x026d06de,
+ 0x03e6e826,
+ 0x4f4c1cf7,
+ 0x08df385f,
+ 0xdf383138,
+ 0x06de3906,
+ 0x343c3c3c,
+ 0x06de069f,
+ 0x026f01e7,
+ 0x1803e75f,
+ 0x1a081cce,
+ 0x06de04ef,
+ 0x1804ee1a,
+ 0x08c400e6,
+ 0x03e62b27,
+ 0xffce2126,
+ 0xf700e687,
+ 0x01c54d1c,
+ 0x06de0f27,
+ 0x0abd8f08,
+ 0x1801c6fa,
+ 0xe71806de,
+ 0x6d06de03,
+ 0x18df2703,
+ 0x6f1806de,
+ 0x1a06de03,
+ 0x081804ee,
+ 0x6c04ef1a,
+ 0xc102e602,
+ 0x38b72307,
+ 0xdf383138,
+ 0x06de3906,
+ 0x9f3c3c3c,
+ 0xe706de06,
+ 0xc6026f01,
+ 0xa606de0e,
+ 0x03ed3d02,
+ 0x181b1cc3,
+ 0x00e6188f,
+ 0x502601c1,
+ 0x1803ee1a,
+ 0x1c1cc38f,
+ 0xe6188f18,
+ 0x2601c100,
+ 0x03ee1a16,
+ 0x1cc38f18,
+ 0xe68f181e,
+ 0x18343701,
+ 0x0ebd00e6,
+ 0xde31318e,
+ 0x03ee1a06,
+ 0x1cc38f18,
+ 0x188f181d,
+ 0x01c100e6,
+ 0xee1a1626,
+ 0xc38f1803,
+ 0x8f181f1c,
+ 0x343701e6,
+ 0xbd00e618,
+ 0x31318e0e,
+ 0x026c06de,
+ 0x03c102e6,
+ 0x38389123,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0xde069f3c,
+ 0x0ade3c08,
+ 0x8dffce3c,
+ 0xcc01001c,
+ 0x36376000,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0x1cfd5715,
+ 0x5b1cff5d,
+ 0x378c00cc,
+ 0x375f4f36,
+ 0x6000cc36,
+ 0xfecc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0xfc06de18,
+ 0xed18591c,
+ 0x571cfc03,
+ 0x1801ed18,
+ 0x0add03ec,
+ 0xdd01ec18,
+ 0x840adc08,
+ 0x03ed18df,
+ 0xed1808dc,
+ 0x03eecd01,
+ 0x01eecd3c,
+ 0x6400cc3c,
+ 0xfecc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0xec72fece,
+ 0x6f0cbd00,
+ 0x3c591cfe,
+ 0x3c571cfe,
+ 0x376400cc,
+ 0x00fecc36,
+ 0xfdc63637,
+ 0xfef814bd,
+ 0xfe3c5d1c,
+ 0xcc3c5b1c,
+ 0x36376000,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0xce18f814,
+ 0x1d188dff,
+ 0xf0ce0100,
+ 0xfd00ec0e,
+ 0xfe18551c,
+ 0xfece551c,
+ 0xdd00ec70,
+ 0xd38f1800,
+ 0xce8f1800,
+ 0xef1a16f0,
+ 0xc38f3000,
+ 0x358f2400,
+ 0x380adf38,
+ 0x383808df,
+ 0x3906df38,
+ 0x3c3c06de,
+ 0x9f3c3c3c,
+ 0x3c08de06,
+ 0x183c0ade,
+ 0x5f4f06de,
+ 0x1803ed18,
+ 0xed1801ed,
+ 0x05ed1807,
+ 0x1c8dffce,
+ 0xfece0100,
+ 0x2700e676,
+ 0xbd137e03,
+ 0x374c00cc,
+ 0x00fecc36,
+ 0xfdc63637,
+ 0x185715bd,
+ 0xed1806de,
+ 0x01efcd03,
+ 0xdd03ec18,
+ 0x01ec180a,
+ 0x0adc08dd,
+ 0xca8f08de,
+ 0x08df8f02,
+ 0xdc03ed18,
+ 0x01ed1808,
+ 0x3c03eecd,
+ 0x3c01eecd,
+ 0x374c00cc,
+ 0x00fecc36,
+ 0xfdc63637,
+ 0xccf814bd,
+ 0x36378400,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0xde185715,
+ 0x07ed1806,
+ 0x1805efcd,
+ 0x0add07ec,
+ 0xdd05ec18,
+ 0xca0adc08,
+ 0x07ed1880,
+ 0xed1808dc,
+ 0x07eecd05,
+ 0x05eecd3c,
+ 0x8400cc3c,
+ 0xfecc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0x3701f0cc,
+ 0x375f4f36,
+ 0x1800cc36,
+ 0xfecc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0x3a20c630,
+ 0x77fece35,
+ 0x342600e6,
+ 0x370100cc,
+ 0x375f4f36,
+ 0x01f0cc36,
+ 0xfccc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0x36375f4f,
+ 0x00cc3637,
+ 0xcc363718,
+ 0x363700fe,
+ 0x14bdfdc6,
+ 0xc38f30f8,
+ 0x358f1000,
+ 0x1806de18,
+ 0x0add07ec,
+ 0xdd05ec18,
+ 0xc40adc08,
+ 0x07ed187f,
+ 0xed1808dc,
+ 0x07eecd05,
+ 0x05eecd3c,
+ 0x8400cc3c,
+ 0xfecc3637,
+ 0xc6363700,
+ 0xf814bdfd,
+ 0x1806de18,
+ 0x0add03ec,
+ 0xdd01ec18,
+ 0xde0adc08,
+ 0xfdc48f08,
+ 0x1808df8f,
+ 0x08dc03ed,
+ 0xcd01ed18,
+ 0xcd3c03ee,
+ 0xcc3c01ee,
+ 0x36374c00,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0xde18f814,
+ 0x03ec1806,
+ 0xec180add,
+ 0xdc08dd01,
+ 0x18078a0a,
+ 0x08dc03ed,
+ 0xcd01ed18,
+ 0xcd3c03ee,
+ 0xcc3c01ee,
+ 0x36374c00,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0x8f30f814,
+ 0x8f1800c3,
+ 0x6000cc35,
+ 0xfecc3637,
+ 0xc6363700,
+ 0x5715bdfd,
+ 0xff5d1cfd,
+ 0x00cc5b1c,
+ 0x4f36378c,
+ 0xcc36375f,
+ 0x36376000,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0x00ccf814,
+ 0xcc363764,
+ 0x363700fe,
+ 0x15bdfdc6,
+ 0x591cfd57,
+ 0xfe571cff,
+ 0xfe3c5d1c,
+ 0xcc3c5b1c,
+ 0x36376000,
+ 0x3700fecc,
+ 0xbdfdc636,
+ 0xffcef814,
+ 0x01001d8d,
+ 0x1c24f0ce,
+ 0xf0ce0300,
+ 0xfd00ec0e,
+ 0xfe18551c,
+ 0xfece551c,
+ 0xdd00ec70,
+ 0xd38f1800,
+ 0xce8f1800,
+ 0xef1a16f0,
+ 0x23f0ce00,
+ 0x3080001c,
+ 0x1800c38f,
+ 0xdf38358f,
+ 0x08df380a,
+ 0x38383838,
+ 0x3906df38,
+ 0x8a8cffb6,
+ 0x267f817f,
+ 0x038639f7,
+ 0x398cffb7,
+ 0xffb70186,
+ 0xa618398c,
+ 0x81048403,
+ 0x86042704,
+ 0x8604200f,
+ 0xa70020f0,
+ 0xce183905,
+ 0xe6180038,
+ 0x80ffce08,
+ 0xec1804e7,
+ 0xe703a700,
+ 0x02ec1802,
+ 0xf8c401a7,
+ 0x00e702ca,
+ 0x02cccc8d,
+ 0xe706a700,
+ 0x06ec1807,
+ 0x08e709a7,
+ 0xa704ec18,
+ 0x860ae70b,
+ 0x0ba71802,
+ 0x988da48d,
+ 0x38ce1839,
+ 0x08e61800,
+ 0xe780ffce,
+ 0x00ec1804,
+ 0x02e703a7,
+ 0xa702ec18,
+ 0xcaf8c401,
+ 0x8d00e704,
+ 0x0002cc8d,
+ 0x07e706a7,
+ 0xa7180486,
+ 0x6c14bd0b,
+ 0x395c14bd,
+ 0x343c06de,
+ 0x08de069f,
+ 0x3c0ade3c,
+ 0xde3c0cde,
+ 0x06de3c0e,
+ 0xde1801e7,
+ 0x08ec1806,
+ 0xec180add,
+ 0x1808dd06,
+ 0x0edd0cec,
+ 0xdd0aec18,
+ 0x0838ce0c,
+ 0xe701e618,
+ 0x0038ce00,
+ 0x02ed0adc,
+ 0x00ed08dc,
+ 0xdc0438ce,
+ 0xdc02ed0e,
+ 0xbd00ed0c,
+ 0xdf388614,
+ 0x0cdf380e,
+ 0x380adf38,
+ 0x383108df,
+ 0xde3906df,
+ 0x9f343c06,
+ 0x3c08de06,
+ 0xde3c0ade,
+ 0x0ede3c0c,
+ 0xe706de3c,
+ 0x06de1801,
+ 0xdd08ec18,
+ 0x06ec180a,
+ 0x38ce08dd,
+ 0x01e61808,
+ 0x38ce00e7,
+ 0xed0adc00,
+ 0xed08dc02,
+ 0xc514bd00,
+ 0xdd83ffcc,
+ 0xde0edc02,
+ 0x00ce180c,
+ 0x183c8d08,
+ 0xde1804df,
+ 0x00ea1802,
+ 0x0cdf0edd,
+ 0xdf180918,
+ 0x1800de00,
+ 0xde1802df,
+ 0x7fff8c04,
+ 0x0cded722,
+ 0xdf183818,
+ 0x1838180e,
+ 0x38180cdf,
+ 0x180adf18,
+ 0x08df1838,
+ 0x18381831,
+ 0x183906df,
+ 0x1fc44f8f,
+ 0x09278f18,
+ 0x49598f05,
+ 0x2609188f,
+ 0x064f39f7,
+ 0x10008c39,
+ 0x008c0a2c,
+ 0x05042700,
+ 0x39fc2609,
+ 0x0e395f4f,
+ 0x00fc203e,
+ 0x00ffffc0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00007400,
+ 0x07070000,
+ 0x00010f0f,
+ 0x75000000,
+ 0x00000000,
+ 0x0f0f0707,
+ 0x00000000,
+ 0x00007600,
+ 0x07070000,
+ 0x00000f0f,
+ 0x77000000,
+ 0x00000000,
+ 0x0f0f0707,
+ 0x00000000,
+ 0x00000000,
+ 0x01000100,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+UINT32 DataBlock1[] = {
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41094109,
+ 0x41095c09,
+ 0x41094109,
+ 0xfb084109,
+ 0x41092009,
+ 0x00020002,
+ 0x00020002
+};
+
+SMU_FIRMWARE_BLOCK FmBlockArray[] = {
+ {
+ 0x200,
+ 0x51a,
+ &DataBlock0[0]
+ },
+ {
+ 0xffc0,
+ 0x10,
+ &DataBlock1[0]
+ }
+};
+
+SMU_FIRMWARE_HEADER Fm = {
+ {
+ 0x0, 0x0
+ },
+ 2,
+ &FmBlockArray[0]
+};
+#endif
+
diff --git a/src/vendorcode/amd/cimx/rd890/Makefile.inc b/src/vendorcode/amd/cimx/rd890/Makefile.inc
new file mode 100644
index 0000000000..8a05570f6d
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/Makefile.inc
@@ -0,0 +1,118 @@
+#*****************************************************************************
+#
+# Copyright (C) 2012 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of Advanced Micro Devices, Inc. nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#*****************************************************************************
+
+# CIMX Root directory
+CIMX_ROOT = $(src)/vendorcode/amd/cimx
+
+NB_CIMX_INC = -I$(src)/mainboard/$(MAINBOARDDIR)
+NB_CIMX_INC += -I$(src)/northbridge/amd/cimx/rd890
+NB_CIMX_INC += -I$(CIMX_ROOT)/rd890
+
+romstage-y += amdAcpiIvrs.c
+romstage-y += amdAcpiLib.c
+romstage-y += amdAcpiMadt.c
+romstage-y += amdDebugOutLib.c
+romstage-y += amdSbLib.c
+#romstage-y += nbDispatcher.c
+romstage-y += nbEventLog.c
+romstage-y += nbHtInit.c
+romstage-y += nbHtInterface.c
+romstage-y += nbInit.c
+romstage-y += nbInitializer.c
+romstage-y += nbInterface.c
+romstage-y += nbIoApic.c
+romstage-y += nbIommu.c
+romstage-y += nbLib.c
+romstage-y += nbMaskedMemoryInit.c
+romstage-y += nbMiscInit.c
+romstage-y += nbModuleInfo.c
+romstage-y += nbPcieAspm.c
+romstage-y += nbPcieCplBuffers.c
+romstage-y += nbPcieEarlyHwLib.c
+romstage-y += nbPcieHotplug.c
+romstage-y += nbPcieInitEarly.c
+romstage-y += nbPcieInitLate.c
+romstage-y += nbPcieLateHwLib.c
+romstage-y += nbPcieLib.c
+romstage-y += nbPcieLinkWidth.c
+romstage-y += nbPciePllControl.c
+romstage-y += nbPciePortRemap.c
+#romstage-y += nbPcieRecovery.c
+romstage-y += nbPcieSb.c
+romstage-y += nbPcieWorkarounds.c
+romstage-y += nbPowerOnReset.c
+#romstage-y += nbRecovery.c
+#romstage-y += nbRecoveryInitializer.c
+romstage-y += nbMaskedMemoryInit32.S
+
+ramstage-y += amdAcpiIvrs.c
+ramstage-y += amdAcpiLib.c
+ramstage-y += amdAcpiMadt.c
+ramstage-y += amdDebugOutLib.c
+ramstage-y += amdSbLib.c
+#ramstage-y += nbDispatcher.c
+ramstage-y += nbEventLog.c
+ramstage-y += nbHtInit.c
+ramstage-y += nbHtInterface.c
+ramstage-y += nbInit.c
+ramstage-y += nbInitializer.c
+ramstage-y += nbInterface.c
+ramstage-y += nbIoApic.c
+ramstage-y += nbIommu.c
+ramstage-y += nbLib.c
+ramstage-y += nbMaskedMemoryInit.c
+ramstage-y += nbMiscInit.c
+ramstage-y += nbModuleInfo.c
+ramstage-y += nbPcieAspm.c
+ramstage-y += nbPcieCplBuffers.c
+ramstage-y += nbPcieEarlyHwLib.c
+ramstage-y += nbPcieHotplug.c
+ramstage-y += nbPcieInitEarly.c
+ramstage-y += nbPcieInitLate.c
+ramstage-y += nbPcieLateHwLib.c
+ramstage-y += nbPcieLib.c
+ramstage-y += nbPcieLinkWidth.c
+ramstage-y += nbPciePllControl.c
+ramstage-y += nbPciePortRemap.c
+#ramstage-y += nbPcieRecovery.c
+ramstage-y += nbPcieSb.c
+ramstage-y += nbPcieWorkarounds.c
+ramstage-y += nbPowerOnReset.c
+#ramstage-y += nbRecovery.c
+#ramstage-y += nbRecoveryInitializer.c
+ramstage-y += nbMaskedMemoryInit32.S
+
+NB_CIMX_CFLAGS =
+export CIMX_ROOT
+export NB_CIMX_INC
+export NB_CIMX_CFLAGS
+CC := $(CC) $(NB_CIMX_CFLAGS) $(NB_CIMX_INC)
+
+#######################################################################
+
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c
new file mode 100644
index 0000000000..c710bf06fe
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c
@@ -0,0 +1,236 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdAcpiLib.h"
+#include "amdAcpiIvrs.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get first block entry in an IVRS (IOMMU) table
+ *
+ *
+ *
+ * @param[in] IoVirtualizationEntryType Type of IVHD or IVMD entry (IVHD = 0x10, IVMD = 0x20-0x22, any = 0xFF))
+ * @param[in] Pointer to IVRS ACPI table
+ *
+ */
+VOID*
+LibAmdGetFirstIvrsBlockEntry (
+ IN UINT8 IoVirtualizationEntryType,
+ IN VOID *IvrsPtr
+ )
+{
+ // Start at IVRS pointer + 48 (48 is always the size of IVRS header)
+ UINT8* BlockPtr;
+ // If our pointer is not to an IVRS, return error
+
+// if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != 'SRVI') return NULL;
+ if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != Int32FromChar ('S', 'R', 'V', 'I')) return NULL;
+ BlockPtr = (UINT8*)IvrsPtr + 48;
+ // Search each entry incrementing by it's size field in offset 2 until
+ // we reach the end of the IVRS
+ do {
+ if (*BlockPtr == IoVirtualizationEntryType) {
+ return BlockPtr;
+ }
+ BlockPtr += *((UINT16*) (BlockPtr + 2));
+ } while (BlockPtr < (UINT8*)IvrsPtr + ((DESCRIPTION_HEADER*)IvrsPtr)->Length);
+ return NULL;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get next block entry in an IVRS (IOMMU) table
+ *
+ *
+ *
+ * @param[in] IoVirtualizationEntryType Type of IVHD or IVMD entry (IVHD = 0x10, IVMD = 0x20-0x22, any = 0xFF))
+ * @param[in] CurrentStructurePtr Pointer to current IVHD or IVMD block in IVRS
+ * @param[in] IvrsPtr Pointer to IVRS table
+ *
+ */
+
+VOID*
+LibAmdGetNextIvrsBlockEntry (
+ IN UINT8 IoVirtualizationEntryType,
+ IN VOID* CurrentStructurePtr,
+ IN VOID* IvrsPtr
+ )
+{
+ // Start at the current device entry
+ // Start searching after the current entry
+ UINT8* BlockPtr;
+ // If our pointer is not to an IVRS, return error
+// if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != 'SRVI') return NULL;
+ if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != Int32FromChar ('S', 'R', 'V', 'I')) return NULL;
+
+ BlockPtr = (UINT8*)CurrentStructurePtr + *((UINT16*) ((UINT8*)CurrentStructurePtr + 2));
+
+ // Search each entry incrementing by it's size field in offset 2 until
+ // we reach the end of the IVRS
+ while (BlockPtr < ((UINT8*)IvrsPtr + ((DESCRIPTION_HEADER*)IvrsPtr)->Length)) {
+ if (*BlockPtr == IoVirtualizationEntryType) {
+ return BlockPtr;
+ }
+ BlockPtr += *((UINT16*) (BlockPtr + 2));
+ }
+ return NULL;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get pointer to first Device Entry of an IVHD
+ *
+ *
+ *
+ * @param[in] IoVirtualizationEntryType Type of IVHD device entry to search for. (0xFF returns next entry of any type)
+ * Typical values: 4 byte entries (0-63), 8 byte entries (64-127)
+ * @param[in] IvhdBlockPtr Pointer to current IVHD block
+ *
+ */
+VOID*
+LibAmdGetFirstDeviceEntry (
+ IN UINT8 DeviceEntryType,
+ IN VOID* IvhdBlockPtr
+ )
+{
+ // Start at IVHD pointer + 24 (24 is always the size of IVHD header)
+ // Not much we can do do validate an IVHD input, the only field we know for sure is the type
+ UINT8 *EntryPtr;
+ UINT16 IvhdSize;
+ EntryPtr = (UINT8*)IvhdBlockPtr + 24;
+ IvhdSize = *(UINT16*) ((UINT8*)IvhdBlockPtr + 2);
+ // Search each entry incrementing by it's type field until the end of the IVHD
+ // Types 0-63 are 4 byte size, 64-127 are 8 byte size
+ do {
+ if (*EntryPtr == DeviceEntryType) {
+ return EntryPtr;
+ }
+ if (*EntryPtr < 64) {
+ EntryPtr += 4;
+ } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) {
+ EntryPtr += 8;
+ } else {
+ ASSERT (TRUE);
+ return NULL;
+ }
+ } while (EntryPtr < ((UINT8*)IvhdBlockPtr + IvhdSize));
+ return NULL;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get pointer to Next Device Entry of an IVHD
+ *
+ *
+ *
+ *
+ * @param[in] IoVirtualizationEntryType Type of IVHD entry. (0xFF returns next entry of any type)
+ * Typical values: 4 byte entries (0-63), 8 byte entries (64-127)
+ * @param[in] CurrentStructurePtr Pointer to current device entry in IVHD block
+ * @param[in] IvhdBlockPtr Pointer to current IVHD block
+ */
+VOID*
+LibAmdGetNextDeviceEntry (
+ IN UINT8 DeviceEntryType,
+ IN VOID* CurrentDeviceEntry,
+ IN VOID* IvhdBlockPtr
+ )
+{
+ UINT8 *EntryPtr;
+ UINT16 IvhdSize;
+ // Start at IVHD pointer + 24 (24 is always the size of IVHD header)
+ // Not much we can do do validate an IVHD input, the only field we know for sure is the type
+ EntryPtr = CurrentDeviceEntry;
+
+ if ((*EntryPtr != 0) && (*EntryPtr < 64)) {
+ EntryPtr += 4;
+ } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) {
+ EntryPtr += 8;
+ }
+ IvhdSize = *(UINT16*) ((UINT8*)IvhdBlockPtr + 2);
+ // Search each entry incrementing by it's type field until the end of the IVHD
+ // Types 0-63 are 4 byte size, 64-127 are 8 byte size
+ while (EntryPtr < ((UINT8*)IvhdBlockPtr + IvhdSize)) {
+ if (*EntryPtr == DeviceEntryType) {
+ return EntryPtr;
+ }
+ if (*EntryPtr < 64) {
+ EntryPtr += 4;
+ } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) {
+ EntryPtr += 8;
+ } else {
+ ASSERT (TRUE);
+ return NULL;
+ }
+ }
+ return NULL;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h
new file mode 100644
index 0000000000..4d62c17319
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h
@@ -0,0 +1,77 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _AMDACPIIVRS_H_
+#define _AMDACPIIVRS_H_
+
+//#ifndef ASSERT
+//#define ASSERT
+//#endif
+
+
+VOID*
+LibAmdGetFirstIvrsBlockEntry (
+ IN UINT8 IoVirtualizationEntryType,
+ IN VOID* IvrsPtr
+);
+
+VOID*
+LibAmdGetNextIvrsBlockEntry (
+ IN UINT8 IoVirtualizationEntryType,
+ IN VOID* CurrentStructurePtr,
+ IN VOID* IvrsPtr
+);
+
+VOID*
+LibAmdGetFirstDeviceEntry (
+ IN UINT8 DeviceEntryType,
+ IN VOID* IvhdBlockPtr
+);
+
+VOID*
+LibAmdGetNextDeviceEntry (
+ IN UINT8 DeviceEntryType,
+ IN VOID* CurrentDeviceEntry,
+ IN VOID* IvhdBlockPtr
+);
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c
new file mode 100644
index 0000000000..60b5ffe71b
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c
@@ -0,0 +1,186 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdAcpiLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get ACPI table.
+ *
+ *
+ *
+ * @param[in] Signature ACPI table signature
+ *
+ */
+
+AGESA_STATUS
+LibAmdGetAcpiTable (
+ IN UINT32 Signature,
+ IN VOID **TablePtr,
+ IN UINTN *TableHandle
+ )
+{
+ UINT32 i;
+ UINT32* RsdPtr;
+ UINT32* Rsdt;
+ DESCRIPTION_HEADER* CurrentTable;
+
+ RsdPtr = (UINT32*) (UINTN)0xe0000;
+ Rsdt = NULL;
+
+ do {
+// if (*RsdPtr == ' DSR' && *(RsdPtr + 1) == ' RTP') {
+ if ((*RsdPtr == Int32FromChar (' ', 'D', 'S', 'R')) && (*(RsdPtr+1) == Int32FromChar (' ', 'R', 'T', 'P'))) {
+ Rsdt = (UINT32*) (UINTN) (((RSDP*)RsdPtr)->RsdtAddress);
+ break;
+ }
+ RsdPtr += 4;
+ } while (RsdPtr <= (UINT32*) ((UINTN)0xffff0));
+ if (Rsdt != NULL && LibAmdGetAcpiTableChecksum (Rsdt) == 0) {
+ for (i = 0; i < (((DESCRIPTION_HEADER*)Rsdt)->Length - sizeof (DESCRIPTION_HEADER)) / 4; i++) {
+ CurrentTable = (DESCRIPTION_HEADER*) (UINTN)*(UINT32*) ((UINT8*)Rsdt + sizeof (DESCRIPTION_HEADER) + i*4);
+ if (CurrentTable->Signature == Signature) {
+ *TablePtr = CurrentTable;
+ return AGESA_SUCCESS;
+ }
+ }
+ }
+ return AGESA_UNSUPPORTED;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set ACPI table.
+ *
+ *
+ *
+ * @param[in] Signature ACPI table signature
+ *
+ */
+
+AGESA_STATUS
+LibAmdSetAcpiTable (
+ IN VOID *TablePtr,
+ IN BOOLEAN Checksum,
+ IN UINTN *TableHandle
+ )
+{
+ if (Checksum) {
+ LibAmdUpdateAcpiTableChecksum (TablePtr);
+ }
+ return AGESA_SUCCESS;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get ACPI table checksum
+ *
+ *
+ *
+ * @param[in] Pointer to ACPI table
+ *
+ */
+
+UINT8
+LibAmdGetAcpiTableChecksum (
+ IN VOID *TablePtr
+ )
+{
+ UINT32 i;
+ UINT8 Checksum;
+
+ Checksum = 0;
+
+ for (i = 0; i < ((DESCRIPTION_HEADER*)TablePtr)->Length; i++) {
+ Checksum = Checksum + *(UINT8*) ((UINT8*)TablePtr + i);
+ }
+ return Checksum;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Update ACPI table checksum
+ *
+ *
+ *
+ * @param[in] Pointer to ACPI table
+ *
+ */
+
+VOID
+LibAmdUpdateAcpiTableChecksum (
+ IN VOID *TablePtr
+ )
+{
+ UINT8 Checksum;
+ Checksum = 0;
+ ((DESCRIPTION_HEADER*)TablePtr)->Checksum = 0;
+ Checksum = LibAmdGetAcpiTableChecksum (TablePtr);
+ ((DESCRIPTION_HEADER*)TablePtr)->Checksum = 0x100 - Checksum;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h
new file mode 100644
index 0000000000..46ad04faea
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h
@@ -0,0 +1,136 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _AMDACPILIB_H_
+#define _AMDACPILIB_H_
+
+#ifndef ASSERT
+ #define ASSERT
+#endif
+
+#pragma pack(push, 1)
+
+///Header for RSDP table
+typedef struct _RSDP {
+ UINT64 Signature; ///< signature
+ UINT8 Checksum; ///< 8 bit checksum
+ UINT8 OEMID[6]; ///< OEM identifier
+ UINT8 Revision; ///< revision
+ UINT32 RsdtAddress; ///< pointer to rsdt
+ UINT32 Length; ///< length of RSDP
+ UINT64 XsdtAddress; ///< pointer to xsdt
+ UINT8 ExtendedChecksum; ///< checksum of xsdt
+ UINT8 Reserved[3]; ///< reserved
+} RSDP;
+
+///Header for general ACPI table
+typedef struct _DESCRIPTION_HEADER {
+ UINT32 Signature; ///< signature
+ UINT32 Length; ///< length
+ UINT8 Revision; ///< revision
+ UINT8 Checksum; ///< 8 bit checksum
+ UINT8 OEMID[6]; ///< OEM identifier
+ UINT8 OEMTableID[8]; ///< OEM table identifier
+ UINT32 OEMRevision; ///< OEM revision
+ UINT32 CreatorID; ///< table creator identifier
+ UINT32 CreatorRevision; ///< table revision
+} DESCRIPTION_HEADER;
+
+///IO APIC struct in MADT table
+typedef struct {
+ UINT8 Type; ///< type
+ UINT8 Length; ///< length
+ UINT8 ApicId; ///< Apic Id
+ UINT8 Reserved; ///< reserved
+ UINT32 IoApicBase; ///< IO APIC base address
+ UINT32 GlobalInterruptBase; ///< Global Interrupt Base
+} MADT_IO_APIC_STRUCT;
+
+///Local APIC struct in MADT table
+typedef struct {
+ UINT8 Type; ///< type
+ UINT8 Length; ///< length
+ UINT8 AcpiProcessorId; ///< ACPI Processor ID
+ UINT8 ApicId; ///< Apic Id
+ UINT32 Flags; ///< Flags
+} MADT_LOCAL_APIC_STRUCT;
+
+///Local SAPIC struct in MADT table
+typedef struct {
+ UINT8 Type; ///< type
+ UINT8 Length; ///< length
+ UINT8 ApicId; ///< Apic Id
+ UINT8 Reserved; ///< reserved
+ UINT32 GlobalInterruptBase; ///< Global Interrupt Base
+ UINT64 IoApicBase; ///< IO SAPIC base address
+} MADT_IO_SAPIC_STRUCT;
+
+#pragma pack(pop)
+
+AGESA_STATUS
+LibAmdSetAcpiTable (
+ IN VOID *TablePtr,
+ IN BOOLEAN Checksum,
+ IN UINTN *TableHandle
+ );
+
+AGESA_STATUS
+LibAmdGetAcpiTable (
+ IN UINT32 Signature,
+ IN VOID **TablePtr,
+ IN UINTN *TableHandle
+ );
+
+
+VOID
+LibAmdUpdateAcpiTableChecksum (
+ IN VOID* TablePtr
+);
+
+UINT8
+LibAmdGetAcpiTableChecksum (
+ IN VOID* TablePtr
+);
+
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c
new file mode 100644
index 0000000000..daf2c1feb3
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c
@@ -0,0 +1,148 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdAcpiLib.h"
+#include "amdAcpiMadt.h"
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get first block entry in an IVRS (IOMMU) table
+ *
+ *
+ *
+ * @param[in] StructureType Type of structure entry to find (APIC = 1, 0xFF = next structure)
+ * @param[in] MadtPtr Pointer to MADT ACPI table
+ *
+ */
+
+VOID*
+LibAmdGetFirstMadtStructure (
+ IN UINT8 StructureType,
+ IN VOID *MadtPtr
+ )
+{
+ // Start at MADT pointer + 48 (48 is always the size of IVRS header)
+ UINT8* BlockPtr;
+
+ // If our pointer is not to an IVRS, return error
+// if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != 'CIPA') {
+ if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != Int32FromChar ('C', 'I', 'P', 'A')) {
+ return NULL;
+ }
+ BlockPtr = (UINT8*)MadtPtr + 44;
+
+ // Search each entry incrementing by it's size field in offset 2 until
+ // we reach the end of the IVRS
+ do {
+ if (*BlockPtr == StructureType) {
+ return BlockPtr;
+ }
+ BlockPtr += *(BlockPtr + 1);
+ } while (BlockPtr < (UINT8*)MadtPtr + ((DESCRIPTION_HEADER*)MadtPtr)->Length);
+ return NULL;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get next block entry in an IVRS (IOMMU) table
+ *
+ *
+ *
+ * @param[in] StructureType Type of structure entry to find (APIC = 1, ..., 0xFF = next structure)
+ * @param[in] CurrentStructurePtr Pointer to current structure in IVRS
+ * @param[in] MadtPtr Pointer to MADT ACPI table
+ *
+ */
+
+VOID*
+LibAmdGetNextMadtStructure (
+ IN UINT8 StructureType,
+ IN VOID *CurrentStructurePtr,
+ IN VOID *MadtPtr
+ )
+{
+ UINT8 *BlockPtr;
+ BlockPtr = (UINT8*)CurrentStructurePtr + (*(UINT8*) ((UINT8*)CurrentStructurePtr + 1));
+
+ // If our pointer is not to an IVRS, return error
+// if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != 'CIPA') {
+ if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != Int32FromChar ('C', 'I', 'P', 'A')) {
+ return NULL;
+ }
+
+ // Search each entry incrementing by it's size field in offset 2 until
+ // we reach the end of the IVRS
+ while (BlockPtr < ((UINT8*)MadtPtr + ((DESCRIPTION_HEADER*)MadtPtr)->Length)) {
+ if (*BlockPtr == StructureType) {
+ return BlockPtr;
+ }
+ BlockPtr += *(BlockPtr + 1);
+ }
+ return NULL;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h
new file mode 100644
index 0000000000..9f0aa73b5a
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h
@@ -0,0 +1,66 @@
+/**
+ * @file
+ *
+ * ACPI common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _AMDACPIMADT_H_
+#define _AMDACPIMADT_H_
+
+//#ifndef ASSERT
+//#define ASSERT
+//#endif
+
+
+
+VOID*
+LibAmdGetFirstMadtStructure (
+ IN UINT8 StructureType,
+ IN VOID* MadtPtr
+);
+
+VOID*
+LibAmdGetNextMadtStructure (
+ IN UINT8 StructureType,
+ IN VOID* CurrentStructurePtr,
+ IN VOID* MadtPtr
+);
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c
new file mode 100644
index 0000000000..f40852b7e5
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c
@@ -0,0 +1,436 @@
+/**
+ * @file
+ *
+ * Debug out functions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "amdDebugOutLib.h"
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+#define COM_BASE_ADDRESS 0x3f8
+#define DIVISOR 115200
+#define LF 0x0a
+#define CR 0x0d
+
+typedef CHAR8 *va_list;
+#ifndef _INTSIZEOF
+#define _INTSIZEOF(n)( (sizeof(n) + sizeof(UINTN) - 1) & ~(sizeof(UINTN) - 1) )
+#endif
+#ifndef va_start
+#define va_start(ap, v) ( ap = (va_list)&(v) + _INTSIZEOF(v) )
+#endif
+#ifndef va_arg
+#define va_arg(ap, t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
+#endif
+#ifndef va_end
+#define va_end(ap) ( ap = (va_list)0 )
+#endif
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+typedef struct {
+ UINT8 Index;
+ CHAR8 Buffer[256];
+} StringBuffer;
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+VOID
+SendByteToBuffer (
+ IN OUT StringBuffer *Buffer,
+ IN CHAR8 Data
+ );
+
+VOID
+SendStringToBuffer (
+ OUT StringBuffer *Buffer,
+ IN CHAR8 *pstr
+ );
+
+VOID
+SendBufferToDebugOut (
+ IN CHAR8* Buffer
+ );
+
+VOID
+ItoA (
+ IN UINT32 Value,
+ IN UINTN Radix,
+ OUT CHAR8 *pstr
+ );
+
+VOID
+SendBufferToHdtOut (
+ IN CHAR8* Buffer
+ );
+
+VOID
+SendBufferToSerialOut (
+ IN CHAR8* Buffer
+ );
+
+VOID
+InitDebugOut (VOID);
+
+VOID
+InitSerialOut (VOID);
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Send format string to debug out
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+
+VOID
+LibAmdTraceDebug (
+ IN UINT32 Level,
+ IN CHAR8 *Format,
+ IN ...
+ )
+{
+ CHAR8 TemBuffer[16];
+ UINT8 Index;
+ StringBuffer Buffer;
+ va_list ArgList;
+ if (Level == 0) {
+ return;
+ }
+ Buffer.Index = 0;
+ Index = 1;
+ va_start (ArgList, Format);
+ while (Index != 0) {
+ if (*Format == 0) break;
+ if (*Format == '%') {
+ INT32 Radix;
+ Radix = 0;
+ if (*(Format + 1) == 'd' || *(Format + 1) == 'D') {
+ Radix = 10;
+ }
+ if (*(Format + 1) == 'x' || *(Format + 1) == 'X' ) {
+ Radix = 16;
+ }
+ if (Radix != 0) {
+ ItoA (va_arg (ArgList, INT32), Radix, TemBuffer);
+ SendStringToBuffer (&Buffer, TemBuffer);
+ Format += 2;
+ continue;
+ }
+ }
+ SendByteToBuffer (&Buffer, *Format);
+ if (*(Format) == 0x0a) SendByteToBuffer (&Buffer, 0x0d);
+ Format++;
+ }
+ SendBufferToDebugOut (&Buffer.Buffer[0]);
+ va_end (ArgList);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write string to message buffer
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+
+VOID
+SendStringToBuffer (
+ OUT StringBuffer *Buffer,
+ IN CHAR8 *pstr
+ )
+{
+ while (*pstr != 0) {
+ SendByteToBuffer (Buffer, *pstr);
+ pstr++;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write byte to message buffer
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+
+VOID
+SendByteToBuffer (
+ IN OUT StringBuffer *Buffer,
+ IN CHAR8 Data
+ )
+{
+ if (Buffer->Index < 255) {
+ Buffer->Buffer[Buffer->Index] = Data;
+ Buffer->Buffer[++Buffer->Index] = 0;
+ } else {
+ SendBufferToDebugOut (Buffer->Buffer);
+ Buffer->Index = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Integer To String
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+
+VOID
+ItoA (
+ IN UINT32 Value,
+ IN UINTN Radix,
+ OUT CHAR8 *pstr
+ )
+{
+ CHAR8 *tsptr;
+ CHAR8 *rsptr;
+ CHAR8 ch1;
+ CHAR8 ch2;
+ UINTN Reminder;
+
+ tsptr = pstr;
+ rsptr = pstr;
+//Create String
+ do {
+ Reminder = Value % Radix;
+ Value = Value / Radix;
+ if (Reminder < 0xa) {
+ *tsptr = (UINT8)Reminder + '0';
+ } else {
+ *tsptr = (UINT8)Reminder - 0xa + 'a';
+ }
+ tsptr++;
+ } while (Value != 0);
+//Reverse String
+ *tsptr = 0;
+ tsptr--;
+ while (tsptr > rsptr) {
+ ch1 = *tsptr;
+ ch2 = *rsptr;
+ *rsptr = ch1;
+ *tsptr = ch2;
+ tsptr--;
+ rsptr++;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init debug Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+VOID
+InitDebugOut (
+ VOID
+ )
+{
+#ifdef SERIAL_OUT_SUPPORT
+ InitSerialOut ();
+#endif
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Serial Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+VOID
+InitSerialOut (
+ VOID
+ )
+{
+ UINT8 Data;
+ UINT16 Divisor;
+
+ Data = 0x87;
+ LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x3, &Data, NULL);
+ Divisor = 115200 / DIVISOR;
+ Data = (UINT8) (Divisor & 0xFF);
+ LibAmdIoWrite (AccessWidth8 , COM_BASE_ADDRESS + 0x00, &Data, NULL);
+ Data = (UINT8) (Divisor >> 8);
+ LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x01, &Data, NULL);
+ Data = 0x07;
+ LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x3, &Data, NULL);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init HDT Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Send Buffer to debug Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+VOID
+SendBufferToDebugOut (
+ IN CHAR8* Buffer
+ )
+{
+#ifdef HDT_OUT_SUPPORT
+ SendBufferToHdtOut (Buffer);
+#endif
+
+#ifdef SERIAL_OUT_SUPPORT
+ SendBufferToSerialOut (Buffer);
+#endif
+}
+
+#ifdef HDT_OUT_SUPPORT
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Send Buffer to debug Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+VOID
+SendBufferToHdtOut (
+ IN CHAR8* Buffer
+ )
+{
+ UINT32 Dr0Reg;
+ UINT32 Dr7Reg;
+ UINT32 Cr4Reg;
+ UINT64 MsrCurrentValue;
+ UINT64 MsrNewValue;
+
+ // Save the CPU debug registers for restoration at the end of the routine
+ LibAmdMsrRead (0xC001100A, &MsrCurrentValue, NULL);
+ LibAmdReadCpuReg (DR0_REG, &Dr0Reg);
+ LibAmdReadCpuReg (DR7_REG, &Dr7Reg);
+ LibAmdReadCpuReg (CR4_REG, &Cr4Reg);
+
+ //Modify the registers for HDT out
+ LibAmdWriteCpuReg (DR0_REG, 0x8F0);
+ LibAmdWriteCpuReg (DR7_REG, 0x20402);
+ LibAmdWriteCpuReg (CR4_REG, Cr4Reg | 0x8);
+ MsrNewValue = MsrCurrentValue | BIT0;
+ LibAmdMsrWrite (0xC001100A, &MsrNewValue, NULL);
+
+ //HDT out
+ LibAmdIoWrite (AccessWidth32, 0x8F0, &Buffer, NULL);
+
+ // Restore the CPU debug registers
+ LibAmdWriteCpuReg (CR4_REG, Cr4Reg);
+ LibAmdWriteCpuReg (DR7_REG, Dr7Reg);
+ LibAmdWriteCpuReg (DR0_REG, Dr0Reg);
+ LibAmdMsrWrite (0xC001100A, &MsrCurrentValue, NULL);
+}
+#endif
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Send Buffer to debug Output
+ *
+ *
+ *
+ * @param[in] pConfig
+ *
+ */
+VOID
+SendBufferToSerialOut (
+ IN CHAR8* Buffer
+ )
+{
+ UINT8 Status;
+ UINT32 Count;
+
+ Count = 10000;
+ while (*Buffer != 0) {
+ do {
+ LibAmdIoRead (AccessWidth8, COM_BASE_ADDRESS + 0x05, &Status, NULL);
+ if (Status == 0xff) return;
+ // Loop port is ready
+ } while ((Status & 0x20) == 0 && (--Count) != 0);
+ LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x00, Buffer, NULL);
+ Buffer++;
+ }
+}
diff --git a/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h
new file mode 100644
index 0000000000..3458b80b11
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h
@@ -0,0 +1,54 @@
+/**
+ * @file
+ *
+ * Debug out functions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _AMDDEBUGOUTLIB_H_
+#define _AMDDEBUGOUTLIB_H_
+
+VOID
+LibAmdTraceDebug (
+ IN UINT32 Level,
+ IN CHAR8 *Format,
+ IN ...
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/amdSbLib.c b/src/vendorcode/amd/cimx/rd890/amdSbLib.c
new file mode 100644
index 0000000000..22b7fb17df
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdSbLib.c
@@ -0,0 +1,216 @@
+/**
+ * @file
+ *
+ * SB common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "amdlib.h"
+#include "amdSbLib.h"
+
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Stall
+ *
+ *
+ *
+ * @param[in] uSec
+ *
+ */
+
+VOID
+LibAmdSbStall (
+ IN UINT32 uSec,
+ IN VOID *ConfigPtr
+ )
+{
+ UINT16 AcpiTimerBaseAddress;
+ UINT32 StartTime;
+ UINT32 ElapsedTime;
+ SB_INFO SbInfo;
+ SbInfo = LibAmdSbGetRevisionInfo (ConfigPtr);
+ if (SbInfo.Type == SB_UNKNOWN) {
+ AcpiTimerBaseAddress = 0;
+ } else {
+ LibAmdSbPmioRead ((SbInfo.Type == SB_SB700) ? 0x24 : 0x64, AccessWidth16, &AcpiTimerBaseAddress, ConfigPtr);
+ }
+ if (AcpiTimerBaseAddress == 0) {
+ uSec = uSec / 2;
+ while (uSec != 0) {
+ LibAmdIoRead (AccessWidth8, 0x80, &StartTime, (AMD_CONFIG_PARAMS *)ConfigPtr);
+ uSec--;
+ }
+ } else {
+ LibAmdIoRead (AccessWidth32, AcpiTimerBaseAddress, &StartTime, (AMD_CONFIG_PARAMS *)ConfigPtr);
+ do {
+ LibAmdIoRead (AccessWidth32, AcpiTimerBaseAddress, &ElapsedTime, (AMD_CONFIG_PARAMS *)ConfigPtr);
+ if (ElapsedTime < StartTime) {
+ ElapsedTime = ElapsedTime + (0xFFFFFFFF - StartTime);
+ } else {
+ ElapsedTime = ElapsedTime - StartTime;
+ }
+ } while ((ElapsedTime*28/100)<uSec); //28/100
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PMIO
+ *
+ *
+ *
+ * @param[in] uSec
+ *
+ */
+
+VOID
+LibAmdSbPmioRead (
+ IN UINT8 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN VOID *ConfigPtr
+ )
+{
+ UINT8 i;
+ if (Width > 0x80) {
+ Width -= 0x80;
+ }
+ for (i = 0; i <= Width; i++) {
+ LibAmdIoWrite (AccessWidth8, 0xCD6, &Address, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD6
+ Address++;
+ LibAmdIoRead (AccessWidth8,0xCD7, (UINT8 *)Value + i, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD7
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PMIO
+ *
+ *
+ *
+ * @param[in] uSec
+ *
+ */
+
+VOID
+LibAmdSbPmioWrite (
+ IN UINT8 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN VOID *ConfigPtr
+ )
+{
+ UINT8 i;
+ if (Width > 0x80) {
+ Width -= 0x80;
+ }
+ for (i = 0; i <= Width; i++) {
+ LibAmdIoWrite (AccessWidth8, 0xCD6, &Address, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD6
+ Address++;
+ LibAmdIoWrite (AccessWidth8,0xCD7, (UINT8 *)Value + i, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD7
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get SB Type
+ *
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+SB_INFO
+LibAmdSbGetRevisionInfo (
+ IN VOID *ConfigPtr
+ )
+{
+ UINT32 DeviceId;
+ UINT8 RevisionId;
+ SB_INFO SbInfo;
+ PCI_ADDR SbSmbusAddress;
+ SbSmbusAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0x00);
+ LibAmdPciRead (AccessWidth32, SbSmbusAddress, &DeviceId, (AMD_CONFIG_PARAMS *)ConfigPtr);
+ SbInfo.Revision = SB_REV_UNKNOWN;
+ switch (DeviceId) {
+ case 0x43851002:
+ SbSmbusAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0x08);
+ LibAmdPciRead (AccessWidth8, SbSmbusAddress, &RevisionId, (AMD_CONFIG_PARAMS *)ConfigPtr);
+ if (RevisionId >= 0x40) {
+ SbInfo.Type = SB_SB800;
+ } else {
+ SbInfo.Type = SB_SB700;
+ }
+ break;
+ default:
+ SbInfo.Type = SB_UNKNOWN;
+ }
+ return SbInfo;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/amdSbLib.h b/src/vendorcode/amd/cimx/rd890/amdSbLib.h
new file mode 100644
index 0000000000..b226dba646
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/amdSbLib.h
@@ -0,0 +1,85 @@
+/**
+ * @file
+ *
+ * SB common library
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: Common Library
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _AMDSBLIB_H_
+#define _AMDSBLIB_H_
+
+VOID
+LibAmdSbStall (
+ IN UINT32 uSec,
+ IN VOID *ConfigPtr
+ );
+
+VOID
+LibAmdSbPmioRead (
+ IN UINT8 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN VOID *ConfigPtr
+ );
+
+VOID
+LibAmdSbPmioWrite (
+ IN UINT8 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN VOID *ConfigPtr
+ );
+
+#define SB_SB800 0x02
+#define SB_SB700 0x01
+#define SB_UNKNOWN 0xFF
+#define SB_REV_UNKNOWN 0xFF
+
+/// Southbridge info
+typedef struct {
+ UINT8 Type; ///< SB Model (SB800/SB700/...)
+ UINT8 Revision; ///< SB Revision ID
+} SB_INFO;
+
+SB_INFO
+LibAmdSbGetRevisionInfo (
+ IN VOID *ConfigPtr
+ );
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbDef.h b/src/vendorcode/amd/cimx/rd890/nbDef.h
new file mode 100644
index 0000000000..8589adcfd2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbDef.h
@@ -0,0 +1,532 @@
+/**
+ * @file
+ *
+ *
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBDEF_H_
+#define _NBDEF_H_
+
+#pragma pack (push, 1)
+
+AGESA_STATUS
+AmdPowerOnResetInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbPowerOnResetInit (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdHtInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbHtInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdEarlyPostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbEarlyPostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdMidPostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbMidPostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdLatePostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbLatePostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdPcieEarlyInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+PcieEarlyInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+
+AGESA_STATUS
+AmdS3Init (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+AmdS3InitIommu (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbS3Init (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+AmdPcieLateInit (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+AmdPcieLateInitWa (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+AmdPcieValidatePortState (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+PcieLateInit (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+PcieLateInitWa (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+PcieValidatePortState (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+PcieLateInitPorts (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+
+AGESA_STATUS
+AmdPcieS3Init (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+BOOLEAN
+PcieLibCheckGen2Disabled (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibSetGen2Disabled (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+
+PCI_ADDR
+PcieLibGetPortPciAddress (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibSetLinkCompliance (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+PcieLibInitValidateInput (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibSetPcieMmioBase (
+ IN UINT16 PcieMmioBase,
+ IN UINT16 PcieMmioSize,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieCheckSelectedPorts (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+PCIE_LINK_STATUS
+PcieGetPortsLinkStatus (
+ IN UINT16 SelectedPortMask,
+ IN OUT PCIE_LINK_STATUS *PortLinkStatus,
+ IN UINT32 Pooling,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+UINT16
+PcieFindPortsWithLinkStatus (
+ IN PCIE_LINK_STATUS *PortLinkStatus,
+ IN PCIE_LINK_STATUS LinkStatus
+ );
+
+AGESA_STATUS
+PcieBrokenLaneWorkaround (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieGen2Workaround (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieMiscWorkaround (
+ IN PCIE_LINK_STATUS *PortsLinkStatus,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieCheckVco (
+ IN UINT16 SelectedPortMask,
+ IN PCIE_LINK_STATUS *PortsLinkStatus,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieLibPortTrainingControl (
+ IN PORT PortId,
+ IN PCIE_LINK_TRAINING Operation,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibSetCoreConfiguration (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibCommonCoreInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+LINK_INFO
+PcieLibGetPortLinkInfo (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibPowerOffPortLanes (
+ IN PORT PortId,
+ IN PCIE_LINK_WIDTH Width,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+BOOLEAN
+PcieLibIsPortReversed (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+);
+
+VOID
+PcieLibPowerOffPll (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieInitSelectedPorts (
+ IN UINT16 SelectedPortMask,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibSetLinkMode (
+ IN PORT PortId,
+ IN PCIE_LINK_MODE Operation,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PciePreTrainingInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieInitPorts (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieAfterTrainingInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibUnHidePorts (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibHidePorts (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieLibRequestPciReset (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieLibResetSlot (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieLibManageTxClock (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibManageLclkClock (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibEnablePllPowerOffInL1 (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+CORE
+PcieLibGetCoreId (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+UINT32
+PcieLibGetCoreAddress (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+AmdPcieInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+PcieLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+
+BOOLEAN
+PcieLibIsValidPortId (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+);
+
+BOOLEAN
+PcieLibIsValidCoreId (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+);
+
+VOID
+PcieLibPreTrainingInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibMiscLateCoreSetting (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+PcieLateValidateConfiguration (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieForcePortsVisibleOrDisable (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+/*
+VOID
+PcieReportCoreDisableStatus (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+*/
+
+AGESA_STATUS
+PcieLateInitCores (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieLateCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieLibStrapModeControl (
+ IN CORE CoreId,
+ IN PCIE_STRAP_MODE Operation,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibCoreAfterTrainingInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+PORT_STATIC_INFO*
+PcieLibGetStaticPortInfo (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+CORE_INFO*
+PcieLibGetCoreInfo (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+PORT
+PcieLibNativePortId (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieNbSbSetupVc (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieLibLateInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieLibValidatePortStateInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieInitiateSoftwareGen2 (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieRecoveryInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+PCI_CORE_RESET
+PcieLibCoreReset (
+ IN CORE CoreId,
+ IN PCI_CORE_RESET Operation,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+PORT_INFO*
+PcieLibGetPortInfo (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+PCIE_DEVICE_TYPE
+PcieGetDeviceType (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+UINT8
+PcieLibGetActiveCoreMap (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#pragma pack (pop)
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbDispatcher.c b/src/vendorcode/amd/cimx/rd890/nbDispatcher.c
new file mode 100644
index 0000000000..16e86a1aaa
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbDispatcher.c
@@ -0,0 +1,201 @@
+/**
+ * @file
+ *
+ * Function dispatcher.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+extern AMD_MODULE_HEADER mNbModuleID;
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+AGESA_STATUS
+CALLCONV
+AmdNbDispatcher (
+ IN OUT VOID*ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ IMAGE_ENTRY ImageEntry;
+ ImageEntry = NULL;
+ Status = AGESA_UNSUPPORTED;
+ CIMX_INIT_TRACE ((ConfigPtr));
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 Entry \n"));
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), " Funcid = %x Callout = %x\n", ((AMD_CONFIG_PARAMS*)ConfigPtr)->Func, ((AMD_CONFIG_PARAMS*)ConfigPtr)->CalloutPtr));
+
+#ifdef B1_IMAGE
+ // 1. Try to execute any B1 specific functions
+ switch (((AMD_CONFIG_PARAMS*)ConfigPtr)->Func) {
+ #ifdef B1_IMAGE
+ // B1 ONLY Functions
+ //
+ //
+ #endif
+ default:
+ break;
+ }
+#endif
+
+ // 2. If not B1 specific function but we are B1, see if we can find B2 instead
+#ifdef B1_IMAGE
+ if (Status == AGESA_UNSUPPORTED) {
+ UINTN ImageStart;
+ UINTN ImageEnd;
+ AMD_IMAGE_HEADER* AltImagePtr;
+ ImageStart = 0xFFF00000;
+ ImageEnd = 0xFFFFFFFF;
+ AltImagePtr = (AMD_IMAGE_HEADER*) (UINTN) ((AMD_CONFIG_PARAMS*)ConfigPtr)->AltImageBasePtr;
+
+ if ((UINTN)AltImagePtr != 0xFFFFFFFF) {
+ if (AltImagePtr != NULL) {
+ ImageStart = (UINT32) (UINTN)AltImagePtr;
+ ImageEnd = ImageStart + 4;
+ }
+ // Locate/test image base that matches this component
+ AltImagePtr = LibAmdLocateImage ((VOID*)ImageStart, (VOID*)ImageEnd, 4096, CIMX_NB_ID);
+ if (AltImagePtr != NULL) {
+ //Invoke alternative Image
+ ImageEntry = (IMAGE_ENTRY) (UINTN) ((UINT8*) AltImagePtr + AltImagePtr->EntryPointAddress);
+ Status = (*ImageEntry) (ConfigPtr);
+ }
+ }
+ }
+#endif
+ if (Status == AGESA_UNSUPPORTED) {
+ // 3. Try to execute any other functions
+ switch (((AMD_CONFIG_PARAMS*)ConfigPtr)->Func) {
+
+#if defined (B1_IMAGE) || defined (B2_IMAGE)
+// B1 & B2 Functions
+ case PH_AmdPowerOnResetInit:
+ Status = LibSystemApiCall (AmdPowerOnResetInit, ConfigPtr);
+ break;
+ case PH_AmdPcieEarlyInit:
+ Status = LibSystemApiCall (AmdPcieEarlyInit, ConfigPtr);
+ break;
+ case PH_AmdInitializer:
+ Status = LibSystemApiCall (AmdInitializer, ConfigPtr);
+ break;
+#endif
+#ifdef B2_IMAGE
+// B2 Functions
+ case PH_AmdNbHtInit :
+ Status = LibSystemApiCall (AmdHtInit, ConfigPtr);
+ break;
+ case PH_AmdEarlyPostInit :
+ LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr);
+ Status = LibSystemApiCall (AmdEarlyPostInit, ConfigPtr);
+ break;
+ case PH_AmdMidPostInit :
+ Status = LibSystemApiCall (AmdMidPostInit, ConfigPtr);
+ break;
+ case PH_AmdLatePostInit :
+ Status = LibSystemApiCall (AmdPcieLateInit, ConfigPtr);
+ Status = LibSystemApiCall (AmdLatePostInit, ConfigPtr);
+ Status = LibSystemApiCall (AmdPcieLateInitWa, ConfigPtr);
+ break;
+ case PH_AmdPcieValidatePortState :
+ Status = LibSystemApiCall (AmdPcieValidatePortState, ConfigPtr);
+ break;
+ case PH_AmdPcieLateInit :
+ Status = LibSystemApiCall (AmdPcieLateInit, ConfigPtr);
+ break;
+ case PH_AmdNbLateInit :
+ Status = LibSystemApiCall (AmdLatePostInit, ConfigPtr);
+ break;
+ case PH_AmdS3Init :
+ LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr);
+ Status = LibSystemApiCall (AmdS3InitIommu, ConfigPtr);
+ Status = LibSystemApiCall (AmdPcieS3Init, ConfigPtr);
+ Status = LibSystemApiCall (AmdS3Init, ConfigPtr);
+ Status = LibSystemApiCall (AmdPcieLateInitWa, ConfigPtr);
+ break;
+ case PH_AmdNbS3Init :
+ LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr);
+ Status = LibSystemApiCall (AmdS3Init, ConfigPtr);
+ break;
+ case PH_AmdPcieS3Init :
+ Status = LibSystemApiCall (AmdS3InitIommu, ConfigPtr);
+ Status = LibSystemApiCall (AmdPcieS3Init, ConfigPtr);
+ break;
+#endif
+#ifdef B3_IMAGE
+// B3 Functions
+#endif
+ default:
+ break;
+ }
+ }
+
+ // 4. Try next dispatcher if possible, and we have not already got status back
+ if ((mNbModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) {
+ MODULE_ENTRY ModuleEntry;
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 control goes to next Module \n"));
+ ModuleEntry = mNbModuleID.NextBlock->ModuleDispatcher;
+ Status = (*ModuleEntry) (ConfigPtr);
+ }
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 Exit\n"));
+ return Status;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbEventLog.c b/src/vendorcode/amd/cimx/rd890/nbEventLog.c
new file mode 100644
index 0000000000..4c228b0f7b
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbEventLog.c
@@ -0,0 +1,106 @@
+
+/**
+ * @file
+ *
+ *
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * This function logs NB events into a callback.
+ *
+ *
+ *
+ * @param[in] EventClass
+ * @param[in] EventInfo
+ * @param[in] DataParam1
+ * @param[in] DataParam2
+ * @param[in] DataParam3
+ * @param[in] DataParam4
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbEventLog (
+ IN UINTN EventClass,
+ IN UINT32 EventInfo,
+ IN UINT32 DataParam1,
+ IN UINT32 DataParam2,
+ IN UINT32 DataParam3,
+ IN UINT32 DataParam4,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_EVENT Event;
+ Event.EventClass = EventClass;
+ Event.EventInfo = EventInfo;
+ Event.DataParam1 = DataParam1;
+ Event.DataParam2 = DataParam2;
+ Event.DataParam3 = DataParam3;
+ Event.DataParam4 = DataParam4;
+ if (EventClass > ((API_WORKSPACE*)NbConfigPtr->ConfigPtr)->Status) {
+ ((API_WORKSPACE*)NbConfigPtr->ConfigPtr)->Status = EventClass;
+ }
+ LibNbCallBack (PHCB_AmdReportEvent, (UINTN)&Event, NbConfigPtr);
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbEventLog.h b/src/vendorcode/amd/cimx/rd890/nbEventLog.h
new file mode 100644
index 0000000000..cf313fa7f2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbEventLog.h
@@ -0,0 +1,95 @@
+
+/**
+ * @file
+ *
+ *
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBEVENTLOG_H_
+#define _NBEVENTLOG_H_
+
+#pragma pack(push, 1)
+
+/**
+ * Event
+ *
+ */
+typedef struct {
+ UINTN EventClass; /**< Event Class.
+ * @li <b>AGESA_WARNING</b>
+ * @li <b>AGESA_ERROR</b>
+ * @li <b>AGESA_FATAL</b>
+ */
+ UINT32 EventInfo; /**< Event Info.
+ * This parameter used as event identifier
+ */
+ UINT32 DataParam1; ///< Event specific data
+ UINT32 DataParam2; ///< Event specific data
+ UINT32 DataParam3; ///< Event specific data
+ UINT32 DataParam4; ///< Event specific data
+} AGESA_EVENT;
+
+
+#define PCIE_ERROR_HOTPLUG_INIT 0x20010100
+#define PCIE_ERROR_TRAINING_FAIL 0x20010200
+#define PCIE_ERROR_CORE_CONFIGURATION 0x20010300
+#define PCIE_ERROR_BROKEN_LINE 0x20010400
+#define PCIE_ERROR_GEN2_FAIL 0x20010500
+#define PCIE_ERROR_VCO_NEGOTIATON 0x20010600
+#define PCIE_ERROR_DEVICE_REMAP 0x20010700
+#define GENERAL_ERROR_BAD_CONFIGURATION 0x20000100
+#define GENERAL_ERROR_NB_NOT_PRESENT 0x20000200
+#define GENERAL_ERROR_LOCATE_ACPI_TABLE 0x20000300
+
+
+VOID
+LibNbEventLog (
+ IN UINTN EventClass,
+ IN UINT32 EventInfo,
+ IN UINT32 DataParam1,
+ IN UINT32 DataParam2,
+ IN UINT32 DataParam3,
+ IN UINT32 DataParam4,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+#pragma pack(pop)
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInit.c b/src/vendorcode/amd/cimx/rd890/nbHtInit.c
new file mode 100644
index 0000000000..687219a359
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbHtInit.c
@@ -0,0 +1,626 @@
+/**
+ * @file
+ *
+ * HT Initialization
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+#define LINK_BUFFERS_IFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0xF)
+#define LINK_BUFFERS_NFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0x11)
+#define SUBLINK_BUFFERS_IFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0xF)
+#define SUBLINK_BUFFERS_NFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0x11)
+
+typedef VOID DUMMY_CALL (VOID);
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+VOID
+NbInitRasParityMacro (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+UINT8 IBIASCodeTable[] = {
+//0.2G 0.5G 0.6G
+ 0x44, 0x00, 0x44, 0x00, 0xb6,
+//0.8G 1.0G 1.2G 1.4G 1.6G
+ 0x44, 0x96, 0xb6, 0x23, 0x44,
+//1.8G 2.0G 2.2G 2.4G 2.6G
+ 0x64, 0x96, 0xA6, 0xb6, 0xc6
+};
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Init at early post.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+HtLibEarlyInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT32 Value;
+ PCI_ADDR ClkPciAddress;
+ PCI_ADDR CpuPciAddress;
+ PCI_ADDR LinkPciAddress;
+ HT_CONFIG *pHtConfig;
+ UINT8 CpuHtSpeed;
+ UINT8 NbHtSpeed;
+ HT_INACTIVE_LANE_STATE InLnSt;
+ BOOLEAN IsIfcmEnabled;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibEarlyInit Enter\n"));
+ pHtConfig = GET_HT_CONFIG_PTR (pConfig);
+ Status = AGESA_SUCCESS;
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Device = 1;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, 0);
+ LinkPciAddress.AddressValue = MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, ((pConfig->NbHtPath.LinkID & 0xF0) > 0x10)?4:0, 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Node %d Link %d PciAddress %x\n", pConfig->NbHtPath.NodeID, pConfig->NbHtPath.LinkID, LinkPciAddress.AddressValue));
+ LibNbEnableClkConfig (pConfig);
+//Get Ht Speed Info
+ LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x89), AccessWidth8, &CpuHtSpeed, pConfig);
+ LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REGD1 , AccessWidth8, &NbHtSpeed, pConfig);
+ NbHtSpeed &= 0xf;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Ht speed Cpu %x Nb %x\n", CpuHtSpeed, NbHtSpeed));
+//Set IBIAS code
+ LibNbPciRMW (ClkPciAddress.AddressValue | NB_CLK_REGD8, AccessWidth16, (UINT32)~(0x3ff), ((UINT8*)FIX_PTR_ADDR (&IBIASCodeTable[0], NULL))[(pHtConfig->HtReferenceClock / 200)*CpuHtSpeed], pConfig);
+ if (CpuHtSpeed > HT_FREQUENCY_1000M) {
+ UINT8 T0Time;
+ UINT8 ForceFullT0;
+//Enable Protocol checker
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG1E, AccessWidth32, 0, 0x7FFFFFFC, pConfig);
+//Set NB Transmitter Deemphasis
+ if ((pHtConfig->NbTransmitterDeemphasis & 0x80) == 0) {
+ LibHtSetNbTransmitterDeemphasis (pHtConfig->NbTransmitterDeemphasis, pConfig);
+ }
+ LibNbPciRead (CpuPciAddress.AddressValue | 0x16C, AccessWidth32, &Value, pConfig);
+ T0Time = (UINT8) (Value & 0x3F);
+ ForceFullT0 = (UINT8) ((Value >> 13) & 0x7);
+//Enable LS State and set T0Time
+ //T0Time = 0x14; //2us
+ if (pHtConfig->LSx < HtLinkStateSkipInit) {
+ if (pHtConfig->LSx == HtLinkStateSameAsCpu) {
+ LibNbPciRead (
+ CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170),
+ AccessWidth32,
+ &Value,
+ pConfig
+ );
+ if ((Value & BIT8) != 0) {
+ pHtConfig->LSx = HtLinkStateLS2;
+ } else {
+ pHtConfig->LSx = HtLinkStateLS1;
+ }
+ } else {
+ if (pHtConfig->LSx >= HtLinkStateLS2) {
+ T0Time = 0x26; //12us
+ ForceFullT0 = 0x6;
+ } else {
+ T0Time = 0x14; //2us
+ ForceFullT0 = 0x0;
+ }
+ }
+ if (CpuHtSpeed == NbHtSpeed) {
+ LibHtEnableLxState (pHtConfig->LSx, pConfig);
+ }
+ }
+//Set up InLnSt
+ //Match CPU InLnSt except for HT3 LS1
+ LibNbPciRead (
+ CpuPciAddress.AddressValue | 0x16C,
+ AccessWidth32,
+ &Value,
+ pConfig
+ );
+ InLnSt = (Value >> 6) & 0x3;
+
+ // Do not enable HT3 LS1 with InLnSt == 0x1 (PHY_OFF) as per errata 9
+ if (pHtConfig->LSx == HtLinkStateLS1) {
+ if (InLnSt == InactiveLaneStateSameAsPhyOff) {
+ InLnSt = InactiveLaneStateCadCtrlDrivelToLogic0;
+ }
+ }
+ LibNbPciRMW (
+ pConfig->NbPciAddress.AddressValue | NB_PCI_REGA0,
+ AccessWidth8,
+ 0x00,
+ T0Time | (InLnSt << 6),
+ pConfig
+ );
+ LibNbPciRMW (
+ CpuPciAddress.AddressValue | 0x16C,
+ AccessWidth16,
+ (UINT32)(~((0x7 << 13) + 0x3f)),
+ T0Time | (ForceFullT0 << 13),
+ pConfig
+ );
+ // Disable command throtling
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | (NB_PCI_REGAC + 1), AccessWidth8, (UINT32)~BIT6, BIT6, pConfig);
+ LibNbPciRMW (CpuPciAddress.AddressValue | 0x168, AccessWidth16, (UINT32)~BIT10, BIT10, pConfig);
+ // Enables strict TM4 detection
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessWidth32, (UINT32)~BIT22, BIT22, pConfig);
+ } else {
+ //Set Link Tristate
+ if (pHtConfig->HtLinkTriState < HtLinkTriStateSkip) {
+ if (pHtConfig->HtLinkTriState == HtLinkTriStateSameAsCpu) {
+ LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x84), AccessWidth16, &Value, pConfig);
+ if ((Value & BIT13) != 0) {
+ pHtConfig->HtLinkTriState = HtLinkTriStateCadCtl;
+ LibNbPciRead (
+ CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170),
+ AccessWidth16,
+ &Value,
+ pConfig
+ );
+ if ((Value & BIT8) != 0) {
+ pHtConfig->HtLinkTriState = HtLinkTriStateCadCtlClk;
+ }
+ }
+ }
+ if (pHtConfig->HtLinkTriState >= HtLinkTriStateCadCtl) {
+ UINT16 TriStateValue;
+ TriStateValue = 0;
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGC8, AccessWidth16 , (UINT32)~BIT13, BIT13, pConfig);
+ LibNbPciRMW (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x84), AccessWidth16, (UINT32)~(BIT13), BIT13, pConfig);
+ if (pHtConfig->HtLinkTriState == HtLinkTriStateCadCtlClk) {
+ TriStateValue = BIT8;
+ }
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGAC, AccessWidth16, (UINT32)~BIT8, TriStateValue, pConfig);
+ if (LibNbGetCpuFamily () != 0x0) {
+ LibNbPciRMW (
+ CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170),
+ AccessWidth16,
+ (UINT32)~(BIT8),
+ TriStateValue,
+ pConfig
+ );
+ }
+ }
+ }
+ LibNbPciRMW (
+ pConfig->NbPciAddress.AddressValue | NB_PCI_REGA0,
+ AccessWidth8,
+ 0x3f,
+ InactiveLaneStateSameAsPhyOff << 6,
+ pConfig
+ );
+ }
+ //Enable 64bit address mode
+
+ if ((pHtConfig->HtExtendedAddressSupport & 0x80) == 0) {
+ LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, &Value, pConfig);
+ if (pHtConfig->HtExtendedAddressSupport == HtExtAddressingSameAsCpu) {
+ Value &= BIT7;
+ } else {
+ Value = (pHtConfig->HtExtendedAddressSupport == HtExtAddressingEnable)? BIT7 : 0;
+ }
+ LibNbPciRMW (((pConfig->NbPciAddress.AddressValue) | (NB_PCI_REGC8 + 1)), AccessWidth8, 0x7C, Value, pConfig);
+ LibNbPciRMW (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, 0x7F, Value, pConfig);
+ }
+
+ // Check if IFCM enabled in CPU
+ LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, &Value, pConfig);
+ IsIfcmEnabled = (Value & BIT4) ? TRUE:FALSE;
+ if (IsIfcmEnabled) {
+ // Enable Isoc in chipset
+ LibNbPciRMW (((pConfig->NbPciAddress.AddressValue) | (NB_PCI_REGC8 + 1)), AccessWidth8, 0xFC, BIT4, pConfig);
+ }
+
+ if (pHtConfig->LinkBufferOptimization == ON) {
+ BOOLEAN IsConnectedToSublink;
+ IsConnectedToSublink = (pConfig->NbHtPath.LinkID & 0xF0) > 0 ? TRUE:FALSE;
+ if (IsConnectedToSublink) {
+ Value = IsIfcmEnabled ? SUBLINK_BUFFERS_IFCM : SUBLINK_BUFFERS_NFCM;
+ } else {
+ Value = IsIfcmEnabled ? LINK_BUFFERS_IFCM : LINK_BUFFERS_NFCM;
+ }
+ LibNbPciRMW (
+ LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x90),
+ AccessWidth32,
+ 0x0,
+ Value,
+ pConfig
+ );
+ }
+ NbInitRasParityMacro (pConfig);
+ LibNbDisableClkConfig (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibEarlyInit Exit [0x%x]\n", Status));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set NB transmitter deemphasis level.
+ *
+ *
+ * @param[in] NbDeemphasisLevel NB Deemphasis level See HT_CONFIG::NbTransmitterDeemphasis
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+LibHtSetNbTransmitterDeemphasis (
+ IN UINT8 NbDeemphasisLevel,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGA7, AccessWidth8, (UINT32)~0x07, NbDeemphasisLevel + BIT7, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable LSx state
+ *
+ *
+ *
+ * @param[in] LSx LS State to enable. See HT_CONFIG::LSx
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+LibHtEnableLxState (
+ IN UINT8 LSx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ UINT32 NbLSx;
+ UINT32 CpuLSx;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Enable HT LS%d\n", LSx));
+ switch (LSx) {
+ case 0:
+ Value = LS0;
+ break;
+ case 1:
+ Value = LS1;
+ break;
+ case 2:
+ Value = LS2;
+ break;
+ case 3:
+ Value = LS3;
+ break;
+ default:
+ Value = 0;
+ CIMX_ASSERT (FALSE);
+ return;
+ }
+ NbLSx = (Value << 7);
+ CpuLSx = (LSx >= 2)?BIT8:0;
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGAC, AccessWidth16, (UINT32)~(BIT7 + BIT8), NbLSx, pConfig);
+ LibNbPciRMW (
+ MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170),
+ AccessWidth32,
+ (UINT32)~BIT8,
+ CpuLSx,
+ pConfig
+ );
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB validate HY Input parameters
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+HtLibInitValidateInput (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ HT_CONFIG *pHtConfig;
+ NB_INFO NbInfo;
+
+ Status = AGESA_SUCCESS;
+ pHtConfig = GET_HT_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ if (pHtConfig == NULL || NbInfo.Type == NB_UNKNOWN) {
+ return AGESA_FATAL;
+ }
+ if (pHtConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) {
+ Status = HtLibInitializer (pConfig);
+ }
+ return Status;
+}
+
+UINT8 SmuWaBasePeriod[] = {
+ 0x1F, //HT 200Mhz
+ 0x00,
+ 0x1F, //HT 400Mhz
+ 0x00,
+ 0x17, //HT 600Mhz
+ 0x1F, //HT 800Mhz
+ 0x27, //HT 1000Mhz
+ 0x2E, //HT 1200Mhz
+ 0x36, //HT 1400Mhz
+ 0x3E, //HT 1600Mhz
+ 0x46, //HT 1800Mhz
+ 0x4E, //HT 2000Mhz
+ 0x55, //HT 2200Mhz
+ 0x5D, //HT 2400Mhz
+ 0x65 //HT 2600Mhz
+};
+
+UINT8 SmuWaBaseDelay[] = {
+ 0x3, //HT 200Mhz
+ 0x0,
+ 0x3, //HT 400Mhz
+ 0x0,
+ 0x2, //HT 600Mhz
+ 0x3, //HT 800Mhz
+ 0x3, //HT 1000Mhz
+ 0x4, //HT 1200Mhz
+ 0x5, //HT 1400Mhz
+ 0x6, //HT 1600Mhz
+ 0x7, //HT 1800Mhz
+ 0x7, //HT 2000Mhz
+ 0x8, //HT 2200Mhz
+ 0x9, //HT 2400Mhz
+ 0xA //HT 2600Mhz
+};
+
+UINT8 SmuWaPeriod10us[] = {
+ 120,
+ 100,
+ 90,
+ 80
+};
+
+UINT8 SmuWaDelay1us[] = {
+ 0x0, //HT 200Mhz
+ 0x0,
+ 0x0, //HT 400Mhz
+ 0x0,
+ 0x0, //HT 600Mhz
+ 0x0, //HT 800Mhz
+ 0x0, //HT 1000Mhz
+ 0x0, //HT 1200Mhz
+ 0x2, //HT 1400Mhz
+ 0x2, //HT 1600Mhz
+ 0x2, //HT 1800Mhz
+ 0x3, //HT 2000Mhz
+ 0x3, //HT 2200Mhz
+ 0x4, //HT 2400Mhz
+ 0x4 //HT 2600Mhz
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get SMU wa data
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ * @retval SMU wa data
+ */
+
+UINT32
+LibHtGetSmuWaData (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 NorthbridgeId;
+ UINT8 NorthbridgeIndex;
+ UINT8 NbHtSpeed;
+ UINT16 SmuWaPeriod;
+ UINT16 SmuWaDelay;
+ AMD_NB_CONFIG_BLOCK *ConfigPtr;
+ NorthbridgeIndex = 0;
+ ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig);
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId];
+ if (LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) {
+ if (pConfig == NbConfigPtr) {
+ LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REGD1 , AccessWidth8, &NbHtSpeed, pConfig);
+ NbHtSpeed &= 0xf;
+ SmuWaPeriod = SmuWaPeriod10us [NorthbridgeIndex] * SmuWaBasePeriod [NbHtSpeed];
+ SmuWaDelay = SmuWaDelay1us [NbHtSpeed] * SmuWaBaseDelay [NbHtSpeed];
+ return ((SmuWaPeriod & 0xFF) << 8) | ((SmuWaPeriod & 0xFF00) >> 8) | ((SmuWaDelay & 0xFF) << 24) | ((SmuWaDelay & 0xFF00) << 8);
+ }
+ NorthbridgeIndex++;
+ }
+ }
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init RAS macro
+ *
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+VOID
+NbInitRasParityMacro (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR CpuPciAddress;
+ UINT32 SaveBase;
+ UINT32 SaveLimit;
+ UINT32 Value;
+ UINT32 Base;
+ UINT32 Limit;
+ UINT32 Index;
+ UINT64 SaveTom;
+ UINT64 Value64;
+ DUMMY_CALL *RetAddr;
+ UINT8 Node;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0);
+//Set TOM
+ LibAmdMsrRead (0xC001001a, &SaveTom, (AMD_CONFIG_PARAMS *)NbConfigPtr);
+ Value64 = 0x40000000;
+ LibAmdMsrWrite (0xC001001a, &Value64, (AMD_CONFIG_PARAMS *)NbConfigPtr);
+//Set mmio
+ LibNbPciRead (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &SaveBase, NbConfigPtr);
+ LibNbPciRead (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &SaveLimit, NbConfigPtr);
+ Limit = ((0x50000000 - 1) >> 8) & (~ 0xFF);
+ Limit |= NbConfigPtr->NbHtPath.NodeID | (HT_PATH_LINK_ID (NbConfigPtr->NbHtPath) << 4) | (HT_PATH_SUBLINK_ID (NbConfigPtr->NbHtPath) << 6);
+ Base = ((0x40000000 >> 8) & (~ 0xFF)) | 0x3;
+ for (Node = 0; Node < 8; Node++) {
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18 + Node, 1, 0);
+ if (LibNbIsDevicePresent (CpuPciAddress, NbConfigPtr)) {
+ LibNbPciWrite (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &Limit, NbConfigPtr);
+ LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &Base, NbConfigPtr);
+ } else {
+ break;
+ }
+ }
+//set Scan
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT27, BIT27, NbConfigPtr);
+ RetAddr = (DUMMY_CALL* ) (UINTN) 0x40000000;
+ *((UINT8*) (UINTN) RetAddr) = 0xC3;
+ for (Index = 0; Index < 64; Index++) {
+ RetAddr ();
+ RetAddr = (DUMMY_CALL*) (UINTN) ((UINT8*) (UINTN) RetAddr + 64);
+ }
+//Reset scan
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT27, 0x0, NbConfigPtr);
+ Value = 0;
+// Restore MMIO Map
+ for (Node = 0; Node < 8; Node++) {
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18 + Node, 1, 0);
+ if (LibNbIsDevicePresent (CpuPciAddress, NbConfigPtr)) {
+ LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &Value, NbConfigPtr);
+ LibNbPciWrite (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &SaveLimit, NbConfigPtr);
+ LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &SaveBase, NbConfigPtr);
+ } else {
+ break;
+ }
+ }
+// Restore TOM
+ LibAmdMsrWrite (0xC001001a, &SaveTom, (AMD_CONFIG_PARAMS *)NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for all NB.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdHtInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (HtLibInitializer, ConfigPtr);
+ return Status;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * HT config structure initializer
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+HtLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ HT_CONFIG *pHtConfig;
+
+ pHtConfig = GET_HT_CONFIG_PTR (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibInitializer Enter\n"));
+ if (pHtConfig == NULL) {
+ return AGESA_WARNING;
+ }
+ if (pHtConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) {
+ return AGESA_SUCCESS;
+ }
+ LibAmdMemFill (pHtConfig, 0, sizeof (HT_CONFIG), (AMD_CONFIG_PARAMS *)&(pHtConfig->sHeader));
+ pHtConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER;
+ pHtConfig->HtExtendedAddressSupport = HtExtAddressingSameAsCpu;
+ pHtConfig->HtLinkTriState = HtLinkTriStateSameAsCpu;
+ pHtConfig->HtReferenceClock = 200;
+// Select LS State
+ pHtConfig->LSx = HtLinkStateSameAsCpu;
+ pHtConfig->LinkBufferOptimization = OFF;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibInitializer Exit\n"));
+ return AGESA_SUCCESS;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInit.h b/src/vendorcode/amd/cimx/rd890/nbHtInit.h
new file mode 100644
index 0000000000..1f8c23d181
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbHtInit.h
@@ -0,0 +1,126 @@
+/**
+ * @file
+ *
+ * HT definitions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+#ifndef _NBHTINIT_H_
+#define _NBHTINIT_H_
+
+///HT link inactive lane
+typedef enum {
+ InactiveLaneStateCadCtrlDrivelToLogic0 = 0, ///< No clock
+ InactiveLaneStateSameAsPhyOff, ///< Same as PHY OFF
+ InactiveLaneStateSameAsOperational, ///< Same as operational
+ InactiveLaneStateSameAsDisconnected, ///< Same as disconnected
+} HT_INACTIVE_LANE_STATE;
+
+AGESA_STATUS
+HtLibEarlyInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+HtLibInitValidateInput (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+LibHtSetNbTransmitterDeemphasis (
+ IN UINT8 NbDeemphasisLevel,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+LibHtEnableLxState (
+ IN UINT8 LSx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+AmdHtInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+HtLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+UINT32
+LibHtGetSmuWaData (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#define LS1 0
+#define LS0 1
+#define LS2 2
+#define LS3 3
+
+/// HT link state
+typedef enum {
+ HtLinkStateLS0 = 0, ///< LS0
+ HtLinkStateLS1, ///< LS1
+ HtLinkStateLS2, ///< LS2
+ HtLinkStateLS3, ///< LS3
+ HtLinkStateSameAsCpu, ///< Same as set on CPU
+ HtLinkStateSkipInit = 0x80 ///< Skip initialization
+} HT_LS_STATE;
+
+/// HT Link Tri-state
+typedef enum {
+ HtLinkTriStateCadCtl = 1, ///< control/data
+ HtLinkTriStateCadCtlClk, ///< CAD clk
+ HtLinkTriStateSameAsCpu, ///< Same as set on CPU
+ HtLinkTriStateSkip = 0x80 ///< Skip initialization
+} HT_LINK_TRISTATE;
+
+/// HT Link Tri-state
+typedef enum {
+ HtExtAddressingDisable = 0, ///< Disable ext addressing
+ HtExtAddressingEnable, ///< Enable Ext addressing
+ HtExtAddressingSameAsCpu, ///< Set Ext addressing as on CPU
+ HtExtAddressingSkip = 0x80 ///< Skip initialization
+} HT_EXT_ADDRESSING;
+
+#define HT_PATH_LINK_ID(htPath) (htPath.LinkID & 0xf)
+#define HT_PATH_SUBLINK_ID(htPath) (((htPath.LinkID & 0xf0) == 0) ? 0 : (((htPath.LinkID & 0xf0) >> 4) - 1))
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInterface.c b/src/vendorcode/amd/cimx/rd890/nbHtInterface.c
new file mode 100644
index 0000000000..ecb5e0df57
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbHtInterface.c
@@ -0,0 +1,125 @@
+/**
+ * @file
+ *
+ * HT Init interfaces
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Early system wide HT init
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+AGESA_STATUS
+AmdHtInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NBHT_TRACE), "[NBHT]AmdHtInit Enter\n"));
+ Status = LibNbApiCall (NbHtInit, ConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NBHT_TRACE), "[NBHT]AmdHtInit Exit [0x%x]\n", Status));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Early Nb HT init.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+AGESA_STATUS
+NbHtInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBHT_TRACE), "[NBHT]NbHtInit Enter\n"));
+ Status = HtLibInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0 , 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ Status = HtLibEarlyInit (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBHT_TRACE), "[NBHT]NbHtInit Exit [0x%x]\n", Status));
+ return Status;
+}
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbInit.c b/src/vendorcode/amd/cimx/rd890/nbInit.c
new file mode 100644
index 0000000000..8a5c5dba96
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbInit.c
@@ -0,0 +1,417 @@
+/**
+ * @file
+ *
+ * NB Initialization.
+ *
+ * Init IOAPIC/IOMMU/Misc NB features.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Early post validate input parameters
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbLibEarlyPostInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ NB_CONFIG *pNbConfig;
+ NB_INFO NbInfo;
+
+ Status = AGESA_SUCCESS;
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ if (NbInfo.Type == NB_UNKNOWN) {
+ return AGESA_FATAL;
+ }
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) {
+ Status = NbLibInitializer (pConfig);
+ }
+ if (pNbConfig->SysMemoryTomBelow4G == 0) {
+ Status = AGESA_FATAL;
+ }
+ //pNbConfig->sHeader.InitializerID = PH_AmdEarlyPostInit;
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Mid/Late post validate input parameters
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbLibPostInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ NB_CONFIG *pNbConfig;
+ NB_INFO NbInfo;
+
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ Status = AGESA_SUCCESS;
+ if (NbInfo.Type == NB_UNKNOWN) {
+ return AGESA_FATAL;
+ }
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) {
+ Status = AGESA_FATAL;
+ }
+ //pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ //if (pNbConfig->sHeader.InitializerID != PH_AmdEarlyPostInit) {
+ // return AGESA_FATAL;
+ //}
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Prepare NB to boot to OS.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbLibPrepareToOS (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, 0xffffffff, BIT7, pConfig);
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set Multiple NB support
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+NbMultiNbIocInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (GET_BLOCK_CONFIG_PTR (pConfig)->NumberOfNorthbridges > 0) {
+ if (pConfig->NbPciAddress.AddressValue == 0) {
+ //Primary NB
+ Value = BIT3 + (HT_INTERRUPT_ENCODING_OFFSET << 4);
+ } else {
+ //Secondary NB
+ Value = BIT2 + (HT_INTERRUPT_ENCODING_OFFSET << 4);
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~((0x7f << 2) + BIT28) , Value, pConfig);
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~(BIT9 + BIT10 + BIT28), pNbConfig->P2PMode << 9, pConfig);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set NB SSID/SVID.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+NbLibSetSSID (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (pNbConfig->SSID == 0xffffffff) {
+ LibNbPciRead (pConfig->NbPciAddress.AddressValue, AccessWidth32, &pNbConfig->SSID, pConfig);
+ }
+ if (pNbConfig->SSID != 0) {
+ LibNbPciWrite (pConfig->NbPciAddress.AddressValue | NB_PCI_REG50, AccessS3SaveWidth32, &pNbConfig->SSID, pConfig);
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Setup UnitId clamping
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+NbLibSetupClumping (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT16 ClumpingCapability;
+ UINT16 Value;
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ Value = 0;
+ if (LibNbGetCpuFamily () == CPU_FAMILY_NPT) {
+ return;
+ }
+ LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REG58, AccessS3SaveWidth16, &ClumpingCapability, pConfig);
+ if ((ClumpingCapability & BIT3) != 0 &&
+ (pNbConfig->UnitIdClumping & DEV3_CLUMPING) != 0 &&
+ !LibNbIsDevicePresent (PcieLibGetPortPciAddress (3, pConfig), pConfig)) {
+ Value |= BIT3;
+ }
+ if ((ClumpingCapability & BIT12) != 0 &&
+ (pNbConfig->UnitIdClumping & DEV12_CLUMPING) != 0 &&
+ !LibNbIsDevicePresent (PcieLibGetPortPciAddress (12, pConfig), pConfig)) {
+ Value |= BIT12;
+ }
+ if (Value != 0) {
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG5C, AccessS3SaveWidth16, 0xffff, Value, pConfig);
+ LibNbPciRMW (MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x110), AccessS3SaveWidth16, 0xffff, Value, pConfig);
+ }
+}
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set top of memory in NB.
+ * NB will not pass to CPU any upstream DMA request to address above TOM and TOM2
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbLibSetTopOfMemory (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ NB_CONFIG *pNbConfig;
+ UINT32 RD890_TOM2;
+ UINT32 RD890_TOM3;
+
+ RD890_TOM2 = 0;
+ RD890_TOM3 = 0;
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (pNbConfig->SysMemoryTomBelow4G != 0) {
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG90, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomBelow4G) << 20, pConfig);
+ }
+ if (pNbConfig->SysMemoryTomAbove4G != 0) {
+ if ((pNbConfig->SysMemoryTomAbove4G - 1) <= 0xfffff) {
+ RD890_TOM2 = pNbConfig->SysMemoryTomAbove4G;
+ } else {
+ RD890_TOM2 = (UINT32) (0xFD00000000 >> 20);
+ RD890_TOM3 = pNbConfig->SysMemoryTomAbove4G;
+ }
+ }
+ if (RD890_TOM2 != 0) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG31, AccessS3SaveWidth32, 0, (RD890_TOM2 >> 12), pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG30, AccessS3SaveWidth32, 0, (RD890_TOM2 << 20) | 1, pConfig);
+ }
+ if (RD890_TOM3 != 0) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4E, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomAbove4G >> 2) | BIT31, pConfig);
+ }
+ return AGESA_SUCCESS;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Loget COre APic ID and dtore to scratch
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+NbLibGetCore0ApicId (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT64 Value;
+ UINT32 Apic20;
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ LibAmdMsrRead (0x0000001B, &Value, (AMD_CONFIG_PARAMS *)pConfig);
+ LibNbMemRead ((Value & 0xfffffffff000) + 0x20, AccessWidth32, &Apic20, pConfig);
+ pNbConfig->Reserved = (UINT16) (Apic20 >> 24);
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Direct NMI message to Core 0
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+NbLibSetNmiRouting (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ NB_MISC_REG12,
+ AccessS3SaveWidth32,
+ 0x00ffffff,
+ (UINT32)pNbConfig->Reserved << 24,
+ pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for all NB.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdNbInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (NbLibInitializer, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB config structure initializer
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+NbLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT64 Value64;
+ NB_CONFIG *pNbConfig;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ if (pNbConfig == NULL) {
+ return AGESA_WARNING;
+ }
+ if (pNbConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) {
+ return AGESA_SUCCESS;
+ }
+ LibAmdMemFill (pNbConfig, 0, sizeof (NB_CONFIG), (AMD_CONFIG_PARAMS *)&(pNbConfig->sHeader));
+ pNbConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER;
+ // Get TOM and TOM2
+ LibAmdMsrRead (0xC001001a, &Value64, (AMD_CONFIG_PARAMS *)pConfig);
+ pNbConfig->SysMemoryTomBelow4G = (UINT16) (Value64 >> 20);
+ LibAmdMsrRead (0xC0010010, &Value64, (AMD_CONFIG_PARAMS *)pConfig);
+ if ((Value64 & BIT21) != 0) {
+ LibAmdMsrRead (0xC001001d, &Value64, (AMD_CONFIG_PARAMS *)pConfig);
+ pNbConfig->SysMemoryTomAbove4G = (UINT32) (Value64 >> 20);
+ }
+ pNbConfig->P2PMode = 1;
+ pNbConfig->UnitIdClumping = 3;
+ return AGESA_SUCCESS;
+}
+
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbInit.h b/src/vendorcode/amd/cimx/rd890/nbInit.h
new file mode 100644
index 0000000000..36a83f8b9b
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbInit.h
@@ -0,0 +1,107 @@
+/**
+ * @file
+ *
+ * NB definitions
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBINIT_H_
+#define _NBINIT_H_
+
+
+VOID
+NbLibSetSSID (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+NbLibSetupClumping (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibSetTopOfMemory (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibEarlyPostInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibPostInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibPrepareToOS (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+NbMultiNbIocInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+AmdNbInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+#ifndef HT_INTERRUPT_ENCODING_OFFSET
+ #define HT_INTERRUPT_ENCODING_OFFSET 0x2
+#endif
+
+VOID
+NbLibSetNmiRouting (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbLibGetCore0ApicId (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbInitializer.c b/src/vendorcode/amd/cimx/rd890/nbInitializer.c
new file mode 100644
index 0000000000..ab4a0041a8
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbInitializer.c
@@ -0,0 +1,133 @@
+/**
+ * @file
+ *
+ * NB Post Init interfaces
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+AGESA_STATUS
+AmdInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for all NB.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (NbInitializer, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB structure initializer.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbInitializer Enter\n"));
+ Status = MiscInitializer (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ return Status;
+ }
+ Status = HtLibInitializer (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ return Status;
+ }
+ Status = PcieLibInitializer (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ return Status;
+ }
+ Status = NbLibInitializer (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbInitializer Exit\n"));
+ return Status;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbInitializer.h b/src/vendorcode/amd/cimx/rd890/nbInitializer.h
new file mode 100644
index 0000000000..0ae6d16b40
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbInitializer.h
@@ -0,0 +1,57 @@
+/**
+ * @file
+ *
+ * NB Post Init interfaces
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+#ifndef _NBINITIALIZER_H_
+#define _NBINITIALIZER_H_
+
+
+AGESA_STATUS
+AmdInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbInterface.c b/src/vendorcode/amd/cimx/rd890/nbInterface.c
new file mode 100644
index 0000000000..7d41b26053
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbInterface.c
@@ -0,0 +1,312 @@
+/**
+ * @file
+ *
+ * NB Post Init interfaces
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Init all NB at early POST.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdEarlyPostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (NbEarlyPostInit, ConfigPtr);
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Init at early post.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbEarlyPostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbEarlyPostInit Enter\n"));
+
+ Status = NbLibEarlyPostInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ NbLibSetTopOfMemory (NbConfigPtr);
+ NbLibSetupClumping (NbConfigPtr);
+ NbMultiNbIocInit (NbConfigPtr);
+#ifndef EPREADY_WORKAROUND_DISABLED
+ PcieEpReadyWorkaround (NbConfigPtr);
+#endif
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbEarlyPostInit Exit [ %x]\n", Status));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Init all NB at mid POST.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdMidPostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (NbMidPostInit, ConfigPtr);
+#ifndef IOMMU_SUPPORT_DISABLE
+ NbIommuInit (ConfigPtr);
+#endif
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Init at mid POST.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbMidPostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMidPostInit Enter\n"));
+ Status = NbLibPostInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ NbLibSetIOAPIC (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMidPostInit Exit [ %x]\n", Status));
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Init all NB at late POST.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdLatePostInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (NbLatePostInit, ConfigPtr);
+#ifndef IOMMU_SUPPORT_DISABLE
+ NbIommuAcpiFixup (ConfigPtr);
+#endif
+ return Status;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Init at late post.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbLatePostInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbLatePostInit Enter\n"));
+ Status = NbLibPostInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ NbLibGetCore0ApicId (NbConfigPtr);
+ NbLibSetNmiRouting (NbConfigPtr);
+ NbLibSetSSID (NbConfigPtr);
+ Status = NbLibPrepareToOS (NbConfigPtr);
+ LibNbSetDefaultIndexes (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbLatePostInit Exit [ %x]\n", Status));
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Init all NB at S3 Resume.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdS3InitIommu (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+
+#ifndef IOMMU_SUPPORT_DISABLE
+ NbIommuInitS3 (ConfigPtr);
+#endif
+
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Init all NB at S3 Resume.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdS3Init (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (NbS3Init, ConfigPtr);
+
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Init at S3
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbS3Init (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbS3Init Enter\n"));
+ Status = NbLibPostInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ Status = NbLibSetTopOfMemory (NbConfigPtr);
+ NbLibSetupClumping (NbConfigPtr);
+ NbMultiNbIocInit (NbConfigPtr);
+ NbLibSetSSID (NbConfigPtr);
+ NbLibSetIOAPIC (NbConfigPtr);
+ NbLibSetNmiRouting (NbConfigPtr);
+ Status = NbLibPrepareToOS (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbS3Init Exit [%x]\n", Status));
+ return Status;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbIoApic.c b/src/vendorcode/amd/cimx/rd890/nbIoApic.c
new file mode 100644
index 0000000000..045883def8
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbIoApic.c
@@ -0,0 +1,194 @@
+/**
+ * @file
+ *
+ * NB IOAPIC Initialization.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*! \var APIC_DEVICE_INFO gDefaultApicDeviceInfoTable[]
+ * \brief Default IO APIC interrupt mapping
+ * \details
+ * @li Interrupt Info for HT referenced as gDefaultApicDeviceInfoTable[0]
+ * @li Interrupt Info for IOMMU referenced as gDefaultApicDeviceInfoTable[1]
+ * @li Interrupt Info for device 2 referenced as gDefaultApicDeviceInfoTable[2]
+ * @li Interrupt Info for device 3 referenced as gDefaultApicDeviceInfoTable[3]
+ * @li ...
+ * @li Interrupt Info for device 13 can be referenced as gDefaultApicDeviceInfoTable[13]
+ */
+CONST APIC_DEVICE_INFO gDefaultApicDeviceInfoTable[] = {
+// Group Swizzling Port Int Pin
+ {0, 0, 31}, //HT
+ {0, 0, 31}, //IOMMU
+ {0, ABCD, 28}, //Dev2 Grp0 [Int - 0..3]
+ {1, ABCD, 28}, //Dev3 Grp1 [Int - 4..7]
+ {5, ABCD, 28}, //Dev4 Grp5 [Int - 20..23]
+ {5, CDAB, 28}, //Dev5 Grp5 [Int - 20..23]
+ {6, BCDA, 29}, //Dev6 Grp6 [Int - 24..27]
+ {6, CDAB, 29}, //Dev7 Grp6 [Int - 24..27]
+ {0, 0, 0 }, // Reserved
+ {6, ABCD, 29}, //Dev9 Grp6 [Int - 24..27]
+ {5, BCDA, 30}, //Dev10 Grp5 [Int - 20..23]
+ {2, ABCD, 30}, //Dev11 Grp2 [Int - 8..11]
+ {3, ABCD, 30}, //Dev12 Grp3 [Int - 12..15]
+ {4, ABCD, 30} //Dev13 Grp4 [Int - 16..19]
+};
+
+CONST APIC_REGISTER_INFO gApicRegisterInfoTable[] = {
+ {0, NB_IOAPICCFG_REG03, 0, NB_IOAPICCFG_REG06}, //Dev2
+ {8, NB_IOAPICCFG_REG03, 8, NB_IOAPICCFG_REG06}, //Dev3
+ {16, NB_IOAPICCFG_REG03, 16, NB_IOAPICCFG_REG06}, //Dev4
+ {24, NB_IOAPICCFG_REG03, 24, NB_IOAPICCFG_REG06}, //Dev5
+ {0, NB_IOAPICCFG_REG04, 0, NB_IOAPICCFG_REG07}, //Dev6
+ {8, NB_IOAPICCFG_REG04, 8, NB_IOAPICCFG_REG07}, //Dev7
+ {0, 0, 0, 0 }, //Dev8
+ {16, NB_IOAPICCFG_REG04, 24 ,NB_IOAPICCFG_REG07}, //Dev9
+ {24, NB_IOAPICCFG_REG04, 0 ,NB_IOAPICCFG_REG08}, //Dev10
+ {0, NB_IOAPICCFG_REG05, 8 ,NB_IOAPICCFG_REG08}, //Dev11
+ {8, NB_IOAPICCFG_REG05, 16 ,NB_IOAPICCFG_REG08}, //Dev12
+ {16, NB_IOAPICCFG_REG05, 24 ,NB_IOAPICCFG_REG08}, //Dev13
+};
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Configure IO APIC
+ * Enable IO APIC base address decoding. Enable default forwarding interrupt to SB
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+NbLibSetIOAPIC (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ NB_CONFIG *pNbConfig;
+ PORT PortId;
+ APIC_DEVICE_INFO ApicDeviceInfoTable[sizeof (gDefaultApicDeviceInfoTable) / sizeof (APIC_DEVICE_INFO)];
+ APIC_REGISTER_INFO *pApicRegisterInfoTable;
+
+ pNbConfig = GET_NB_CONFIG_PTR (pConfig);
+ pApicRegisterInfoTable = (APIC_REGISTER_INFO*)FIX_PTR_ADDR (&gApicRegisterInfoTable[0], NULL);
+ if (pNbConfig->IoApicBaseAddress != 0 ) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NB]NbLibSetIOAPIC\n"));
+ //Copy default routing to local memory buffer
+ LibAmdMemCopy (&ApicDeviceInfoTable, (APIC_DEVICE_INFO*)FIX_PTR_ADDR (&gDefaultApicDeviceInfoTable[0], NULL), sizeof (ApicDeviceInfoTable), (AMD_CONFIG_PARAMS *)&(pNbConfig->sHeader));
+ //Callback to platform BIOS to update
+ LibNbCallBack (PHCB_AmdUpdateApicInterruptMapping, (UINTN)&ApicDeviceInfoTable, pConfig);
+ //Setup base address
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " Apic Base %x\n", (UINT32)pNbConfig->IoApicBaseAddress & 0xffffff00));
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG01, AccessS3SaveWidth32, (UINT32) (0xff), (UINT32)pNbConfig->IoApicBaseAddress & 0xffffff00, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG02, AccessS3SaveWidth32, 0x0, ((UINT32*)&pNbConfig->IoApicBaseAddress)[1] , pConfig);
+ //Setup interrupt mapping
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PCI_ADDR Port;
+ APIC_REGISTER_INFO RegisterInfo;
+ APIC_DEVICE_INFO PortInfo;
+ PORT NativePortId;
+ if (PortId == 8 || !PcieLibIsValidPortId (PortId, pConfig)) {
+ continue;
+ }
+ NativePortId = PcieLibNativePortId (PortId, pConfig);
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ RegisterInfo = pApicRegisterInfoTable[NativePortId - MIN_PORT_ID];
+ PortInfo = ApicDeviceInfoTable[Port.Address.Device];
+ //Setup routing for EP
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX,
+ RegisterInfo.EpRoutingRegister,
+ AccessS3SaveWidth32,
+ 0xFFFFFFFF,
+ (PortInfo.Group | (PortInfo.Swizzle << 4)) << RegisterInfo.EpRoutingOffset,
+ pConfig
+ );
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " EP Routing Dev[%d] NativePortId[%d] PortId[%d] Group - %d Swizzle - %d\n", Port.Address.Device, NativePortId, PortId, PortInfo.Group, PortInfo.Swizzle));
+ //Setup routing for RC
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX,
+ RegisterInfo.RcRoutingRegister,
+ AccessS3SaveWidth32,
+ 0xFFFFFFFF,
+ (PortInfo.Pin) << RegisterInfo.RcRoutingOffset,
+ pConfig
+ );
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " RC Routing Dev[%d] NativeDev[%d] Pin - %d \n", Port.Address.Device, NativePortId, PortInfo.Pin));
+
+ }
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX,
+ NB_IOAPICCFG_REG09,
+ AccessS3SaveWidth32,
+ 0x0,
+ ApicDeviceInfoTable[0].Pin | (ApicDeviceInfoTable[1].Pin << 8),
+ pConfig
+ );
+ //Enable IO API MMIO decoding and configure features
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG00, AccessS3SaveWidth32, 0x0 , 0x1f , pConfig);
+ }
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbIoApic.h b/src/vendorcode/amd/cimx/rd890/nbIoApic.h
new file mode 100644
index 0000000000..f2ba8944d2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbIoApic.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * NB IOAPIC Initialization.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+#ifndef _NBIOAPIC_H_
+#define _NBIOAPIC_H_
+
+
+VOID
+NbLibSetIOAPIC (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbIommu.c b/src/vendorcode/amd/cimx/rd890/nbIommu.c
new file mode 100644
index 0000000000..705b1a82fd
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbIommu.c
@@ -0,0 +1,1737 @@
+/**
+ * @file
+ *
+ * Routines for IOMMU.
+ *
+ * Implement the IOMMU init and ACPI feature.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+#include "amdSbLib.h"
+
+#define Int32FromChar(a,b,c,d) ((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24)
+
+/*----------------------------------------------------------------------------------------
+ * R D 8 9 0 / S D A T A
+ *----------------------------------------------------------------------------------------
+ */
+
+// IOMMU Initialization
+
+INDIRECT_REG_ENTRY
+CONST
+STATIC
+IommuL1Table[] = {
+ // 01. 0x0C [30:28]=7 L1VirtOrderQueues Increase maximum number virtual queues
+ // for all devices
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_0C, 0x8FFFFFFF, 0x70000000 },
+ // 02. 0x07 [11] L1DEBUG_1 Multiple error logs possible
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5},
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5},
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5},
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5},
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5},
+ // 02. 0x06 [0] L1DEBUG_0 Phantom function disable
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_06, (UINT32)~BIT0, 0 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_06, (UINT32)~BIT0, 0 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_06, (UINT32)~BIT0, 0 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_06, (UINT32)~BIT0, 0 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_06, (UINT32)~BIT0, 0 },
+ { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_06, (UINT32)~BIT0, 0 }
+};
+
+INDIRECT_REG_ENTRY
+CONST
+STATIC
+IommuL2Table[] = {
+ // 01. 0x0C [29]=1 IFifoClientPriority Set attribute to VC1 L1 client high priority
+ { L2CFG_SEL_WR_EN | L2REG_0C, 0xD0000000, 0x20000000 },
+ // 02. 0x10 [9:8]=2 DTCInvalidationSel DTC cache invalidation sequential precise
+ { L2CFG_SEL_WR_EN | L2REG_10, 0xFFFFFC00, 0x00000200 },
+ // 03. 0x14 [9:8]=2 ITCInvalidationSel ... cache invalidation sequential precise
+ { L2CFG_SEL_WR_EN | L2REG_14, 0xFFFFFC00, 0x00000200 },
+ // 04. 0x18 [9:8]=2 IPTCAInvalidationSel ... cache invalidation sequential precise
+ { L2CFG_SEL_WR_EN | L2REG_18, 0xFFFFFC00, 0x00000200 },
+ // 05. 0x1C [9:8]=2 IPTCBInvalidationSel ... cache invalidation sequential precise
+ { L2CFG_SEL_WR_EN | L2REG_1C, 0xFFFFFC00, 0x00000200 },
+ // 06. 0x50 [9:8]=2 PDCInvalidationSel ... cache invalidation sequential precise
+ { L2CFG_SEL_WR_EN | L2REG_50, 0xFFFFFC00, 0x00000200 },
+ // 07. 0x10 [4]=1 DTCParityEn DTC cache parity protection
+ { L2CFG_SEL_WR_EN | L2REG_10, (UINT32)~BIT4, BIT4 },
+ // 08. 0x14 [4]=1 ITCParityEn ... cache parity protection
+ { L2CFG_SEL_WR_EN | L2REG_14, (UINT32)~BIT4, BIT4 },
+ // 09. 0x18 [4]=1 PTCAParityEn ... cache parity protection
+ { L2CFG_SEL_WR_EN | L2REG_18, (UINT32)~BIT4, BIT4 },
+ // 10. 0x1C [4]=1 PTCBParityEn ... cache parity protection
+ { L2CFG_SEL_WR_EN | L2REG_1C, (UINT32)~BIT4, BIT4 },
+ // 11. 0x50 [4]=1 PDCParityEn ... cache parity protection
+ { L2CFG_SEL_WR_EN | L2REG_50, (UINT32)~BIT4, BIT4 },
+ // 12. 0x80 [0]=1 ERRRuleLock0 Lock fault detection rule sets
+ // 0x30 [0]=1 ERRRuleLock1
+ { L2CFG_SEL_WR_EN | L2REG_80, (UINT32)~BIT0, BIT0 },
+ { L2CFG_SEL_WR_EN | L2REG_30, (UINT32)~BIT0, BIT0 },
+ // 13. 0x56 [2]=0 L2_CP_CONTROL Disable CP flush on invalidation
+ // 0x56 [1]=1 L2_CP_CONTROL Enable CP flush on wait
+ { L2CFG_SEL_WR_EN | L2REG_56, 0xFFFFFFF9, BIT1 },
+ // A21
+ { L2CFG_SEL_WR_EN | L2REG_06, 0xFFFFFFFF, BIT6 + BIT7 + BIT5 + BIT8 },
+ { L2CFG_SEL_WR_EN | L2REG_47, 0xFFFFFFFF, BIT1 + BIT3 + BIT0 + BIT4 + BIT5 },
+ { L2CFG_SEL_WR_EN | L2REG_07, 0xFFFFFFFF, BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT8 + BIT6},
+
+};
+
+// IOMMU ACPI Initialization
+
+IOMMU_IVRS_HEADER
+STATIC
+RD890S_DfltHeader = {
+// 'SRVI',
+ Int32FromChar ('S', 'R', 'V', 'I'),
+ 48,
+ 1,
+ 0,
+ {'A', 'M', 'D', ' ', ' ', 0},
+ {'R', 'D', '8', '9', '0', 'S', 0, 0},
+ {'1', ' ', ' ', 0},
+ {'A','M','D',' '},
+ {'1', ' ', ' ', 0},
+ 0,
+ 0
+};
+
+IOMMU_EXCLUSIONTABLE
+STATIC
+RD890S_DfltExclusion = {
+ sizeof (UINTN) + sizeof (IOMMU_EXCLUSIONRANGE) * 0,
+ {{0, 0}}
+};
+
+IOMMU_DEVICELIST
+STATIC
+RD890S_DfltDevices = {
+ (sizeof (UINT16) + sizeof (UINT16) * 12),
+ {
+ DEVICEID_NB, // Type 2 entry, Device 0, Func 0 <-- NB all functions
+ DEVICEID_GPP1_0, // Type 2 entry, Device 2, Func 0 <-- GPP1 port 0
+ DEVICEID_GPP1_1, // Type 2 entry, Device 3, Func 0 <-- GPP1 port 1
+ DEVICEID_GPP3A_0, // Type 2 entry, Device 4, Func 0 <-- GPP3a port 0
+ DEVICEID_GPP3A_1, // Type 2 entry, Device 5, Func 0 <-- GPP3a port 1
+ DEVICEID_GPP3A_2, // Type 2 entry, Device 6, Func 0 <-- GPP3a port 2
+ DEVICEID_GPP3A_3, // Type 2 entry, Device 7, Func 0 <-- GPP3a port 3
+ DEVICEID_GPP3A_4, // Type 2 entry, Device 9, Func 0 <-- GPP3a port 4
+ DEVICEID_GPP3A_5, // Type 2 entry, Device A, Func 0 <-- GPP3a port 5
+ DEVICEID_GPP2_0, // Type 2 entry, Device B, Func 0 <-- GPP2 port 0
+ DEVICEID_GPP2_1, // Type 2 entry, Device C, Func 0 <-- GPP2 port 1
+ DEVICEID_GPP3B_0, // Type 2 entry, Device D, Func 0 <-- GPP3b port 0
+ }
+};
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+*/
+
+// IOMMU Library
+
+BOOLEAN
+NbIommuEnabled (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+BOOLEAN
+IommuCheckEnable (
+ IN PCI_ADDR IommuPciAddress,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+BOOLEAN
+IommuCheckHp (
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+BOOLEAN
+IommuCheckPhantom (
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+UINT32
+IommuGetL1 (
+ IN UINT16 DeviceId
+ );
+
+UINT8
+IommuGetLog2 (
+ IN UINT32 Value
+ );
+
+VOID
+IommuRecordBusDevFuncInfo (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+IommuInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuInitL2CacheControl (
+ IN IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+);
+
+VOID
+IommuPlaceHeader (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuPlaceIvhdAndScanDevices (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuPlaceIvmdAndExclusions (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuIvhdNorthbridgeDevices (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuIvhdSouthbridgeDevices (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuIvhdApicsAndHpets (
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuCreateDeviceEntry (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN UINT16 DeviceId,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+IommuCreate4ByteEntry (
+ IN UINT8 Type,
+ IN UINT8 Data,
+ IN UINT16 Word1,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr
+ );
+
+VOID
+IommuCreate8ByteEntry (
+ IN UINT8 Type,
+ IN UINT8 Data,
+ IN UINT16 Word1,
+ IN UINT8 Byte4,
+ IN UINT16 Word5,
+ IN UINT8 Byte7,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr
+ );
+
+VOID
+IommuFinalizeIvrs (
+ IN OUT VOID *BufferPtr,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+// IOMMU ACPI Final
+
+UINT64
+IommuGetApicBaseAddress (
+ IN VOID *DevicePtr,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+UINT8
+IommuGetApicId (
+ IN UINT64 BaseAddress,
+ IN VOID *MadtPtr,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+NbIommuHwInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbIommuHwTopologyInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+IommuTopologyInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if IOMMU enable on platform
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+BOOLEAN
+NbIommuEnabled (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ BOOLEAN Result;
+ Result = FALSE;
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ if (ConfigPtr->Northbridges[NorthbridgeId].pNbConfig->IommuBaseAddress != 0) {
+ Result = TRUE;
+ break;
+ }
+ }
+ return Result;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu Initialization for all NB in system.
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+AGESA_STATUS
+NbIommuInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AGESA_SUCCESS;
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInit Enter\n"));
+
+ if (NbIommuEnabled (ConfigPtr)) {
+ NbIommuHwInit (ConfigPtr);
+ NbIommuAcpiInit (ConfigPtr);
+ NbIommuHwTopologyInit (ConfigPtr);
+ } else {
+ Status = AGESA_UNSUPPORTED;
+ }
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInit Exit [Status = 0x%x]\n", Status));
+ return Status;
+}
+
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu Initialization for all NB in system.
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+AGESA_STATUS
+NbIommuInitS3 (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AGESA_SUCCESS;
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInitS3 Enter\n"));
+
+ if (NbIommuEnabled (ConfigPtr)) {
+ NbIommuHwInit (ConfigPtr);
+ NbIommuHwTopologyInit (ConfigPtr);
+ } else {
+ Status = AGESA_UNSUPPORTED;
+ }
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInitS3 Exit [Status = 0x%x]\n", Status));
+ return Status;
+}
+
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu HW Initialization for all NB in system.
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+AGESA_STATUS
+NbIommuHwInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ AMD_NB_CONFIG *pConfig;
+
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ pConfig = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ IommuInit (pConfig);
+ }
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu HW Initialization for all NB in system.
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+AGESA_STATUS
+NbIommuHwTopologyInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ AMD_NB_CONFIG *pConfig;
+
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ pConfig = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ IommuTopologyInit (pConfig);
+ }
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu Initialization for all NB in system.
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table created
+ * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found
+ * @retval AGESA_ERROR IOMMU initialization failed.
+ *
+ */
+AGESA_STATUS
+NbIommuAcpiInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ AGESA_STATUS Status;
+ AMD_NB_CONFIG *pConfig;
+ NB_BUFFER_PARAMS Ivrs;
+ UINTN IvrsHandle;
+
+ Status = AGESA_SUCCESS;
+ Ivrs.BufferLength = 0;
+ Ivrs.BufferHandle = IVRS_HANDLE;
+ Ivrs.BufferPtr = NULL;
+ pConfig = &ConfigPtr->Northbridges[0];
+ ConfigPtr->CurrentNorthbridge = 0;
+ IvrsHandle = 0;
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit Enter\n"));
+
+ // Get a buffer for IVRS
+ Ivrs.BufferLength = IVRS_BUFFER_SIZE;
+ Status = LibNbCallBack (PHCB_AmdAllocateBuffer, (UINTN)&Ivrs, &ConfigPtr->Northbridges[0]);
+ if (Status != AGESA_SUCCESS || Ivrs.BufferPtr == NULL) {
+ // Table creation failed
+ return AGESA_ERROR;
+ }
+
+ // Clear buffer before using
+ LibAmdMemFill (Ivrs.BufferPtr, 0, Ivrs.BufferLength, (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+
+ // PLACE OUR ACPI IVRS TABLE
+ // 1. Create IVRS header
+ // 2. For each northbridge place IVHD
+ // 3. For northbridge 0 only, place IVMD exclusion entries
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ pConfig = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ if (NorthbridgeId == 0) {
+ IommuPlaceHeader (Ivrs.BufferPtr, pConfig);
+ }
+ IommuPlaceIvhdAndScanDevices (Ivrs.BufferPtr, pConfig);
+ IommuPlaceIvmdAndExclusions (Ivrs.BufferPtr, pConfig);
+ }
+ IommuFinalizeIvrs (Ivrs.BufferPtr, pConfig);
+
+ LibAmdSetAcpiTable (Ivrs.BufferPtr, TRUE, &IvrsHandle);
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit [IVRS TableAddress = 0x%x]\n", (UINT32)(Ivrs.BufferPtr)));
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit Exit [Status = 0x%x]\n", Status));
+
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Iommu IVRS fixup for APICS
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ * @retval AGESA_SUCCESS IOMMU initialized and table patched, or no patching required
+ * @retval AGESA_ERROR IOMMU enabled but no previously generated IVRC table found.
+ *
+ */
+AGESA_STATUS
+NbIommuAcpiFixup (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ UINT8 ApicId;
+ UINT64 ApicBaseAddress;
+ UINT8 NorthbridgeId;
+ BOOLEAN IommuFound;
+ VOID *DevicePtr;
+ VOID *IvhdPtr;
+ VOID *IvrsPtr;
+ VOID *MadtPtr;
+ AMD_NB_CONFIG *pConfig;
+ PCI_ADDR IommuPciAddress;
+ UINTN IvrsHandle;
+
+
+ pConfig = &ConfigPtr->Northbridges[0];
+ IommuFound = FALSE;
+ ApicId = 0xFF;
+ ApicBaseAddress = 0;
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup Enter\n"));
+
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ pConfig = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+ if (IommuCheckEnable (IommuPciAddress, pConfig)) {
+ IommuFound = TRUE;
+ }
+ }
+
+ // Any Iommus enabled? If no, we don't need to patch anything
+ if (!IommuFound) {
+ return AGESA_SUCCESS;
+ }
+
+ // Check for an IVRS
+ // Check IVRS for a type 10 block (IVHD)
+ // Check for an MADT
+ // If these conditions fail, abort
+
+// Status = LibAmdGetAcpiTable ('SRVI', &IvrsPtr, &IvrsHandle);
+ Status = LibAmdGetAcpiTable (Int32FromChar ('S', 'R', 'V', 'I'), &IvrsPtr, &IvrsHandle);
+ if (Status != AGESA_SUCCESS) {
+// REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, 'SRVI', 0, 0, 0, pConfig);
+ REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, Int32FromChar ('S', 'R', 'V', 'I'), 0, 0, 0, pConfig);
+ return AGESA_ERROR;
+ }
+
+// Status = LibAmdGetAcpiTable ('CIPA', &MadtPtr, NULL);
+ Status = LibAmdGetAcpiTable (Int32FromChar ('C', 'I', 'P', 'A'), &MadtPtr, NULL);
+ if (Status != AGESA_SUCCESS) {
+// REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, 'CIPA', 0, 0, 0, pConfig);
+ REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, Int32FromChar ('C', 'I', 'P', 'A'), 0, 0, 0, pConfig);
+ return AGESA_ERROR;
+ }
+
+ IvhdPtr = LibAmdGetFirstIvrsBlockEntry (TYPE_IVHD, IvrsPtr);
+ if (IvhdPtr == NULL) {
+ return AGESA_ERROR;
+ }
+
+ // An IVRS can contain one or more IVHD entries (one per IOMMU)
+ // Each IVHD entry can contain one or more APIC entries
+
+ while (IvhdPtr != NULL) {
+ DevicePtr = LibAmdGetFirstDeviceEntry (DE_SPECIAL, IvhdPtr);
+ do {
+ // Be sure to only fix APIC entries
+ if (*(UINT8*) ((UINT8*)DevicePtr + DE_SPECIAL_VARIETY) == VARIETY_IOAPIC) {
+ ApicBaseAddress = IommuGetApicBaseAddress (DevicePtr, pConfig);
+ ApicId = IommuGetApicId (ApicBaseAddress, MadtPtr, pConfig);
+ *(UINT8*)((UINT8*)DevicePtr + DE_SPECIAL_ID) = ApicId;
+ }
+ DevicePtr = LibAmdGetNextDeviceEntry (DE_SPECIAL, DevicePtr, IvhdPtr);
+ } while (DevicePtr != NULL);
+
+ IvhdPtr = LibAmdGetNextIvrsBlockEntry (TYPE_IVHD, IvhdPtr, IvrsPtr);
+ }
+
+ LibAmdSetAcpiTable (IvrsPtr, TRUE, &IvrsHandle);
+
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup [IVRS TableAddress = 0x%x]\n", (UINT32)IvrsPtr));
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup [APIC TableAddress = 0x%x]\n", (UINT32)MadtPtr));
+ CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup Exit\n"));
+
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------
+ * P R I V A T E
+ *----------------------------------------------------------------------------------------
+ */
+UINT32 IommuMmioInitTable[] = {
+ 0x8, 0x0,
+ 0xC, 0x08000000,
+ 0x10, 0x0,
+ 0x14, 0x08000000,
+ 0x2000, 0x0,
+ 0x2008, 0x0
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Nb Iommu Initialization.
+ *
+ * @param[in] pConfig Northbridge configuration pointer
+ * @retval AGESA_SUCCESS IOMMU enable and initialized succesfully.
+ * @retval AGESA_UNSUPPORTED IOMMU not initialized.
+ */
+AGESA_STATUS
+IommuInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 CapBase;
+ PCI_ADDR IommuPciAddress;
+ UINTN i;
+
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+
+ // If the base address = 0, don't enable IOMMU
+ if (pConfig->pNbConfig->IommuBaseAddress == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ // NBMISCIND:0x75 IOC_FEATURE_CNTL_10_0[10]=1
+ // 0=disable
+ // 1=enable
+
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~(BIT28), BIT0, pConfig);
+
+ // Get Capabilities pointer 32h (points to 40h) - capability ID 0x0F. Not found, we have no IOMMU.
+ CapBase = LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig);
+ if (CapBase == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+
+ // IOMMU_ADAPTER_ID_W - RW - 32 bits - nbconfigfunc2:0x68
+ // SUBSYSTEM_VENDOR_ID_W 15:0 0x0 Sets the subsystem vendor ID register header
+ // SUBSYSTEM_ID_W 31:16 0x0 Sets the subsystem ID register in the configuration header
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NBIOMMU]Iommu Device Found [PCI Address = 0x%x]\n", IommuPciAddress.AddressValue));
+ if (pConfig->pNbConfig->SSID == PCI_INVALID) {
+ LibNbPciRead (IommuPciAddress.AddressValue, AccessWidth32, &pConfig->pNbConfig->SSID, pConfig);
+ }
+ if (pConfig->pNbConfig->SSID) {
+ LibNbPciWrite (IommuPciAddress.AddressValue | 0x68, AccessS3SaveWidth32, &pConfig->pNbConfig->SSID, pConfig);
+ }
+
+ // Get Capabilities pointer 32h (points to 40h) - capability ID 0x0F
+ // Set Cap_Offset+04h [31:14] Base Address Low [31:14]
+ // Set Cap_Offset+08h [31:0] Base Address High [64:32]
+ // Set Cap_Offset+04h [0] Enable
+ LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 8)), AccessS3SaveWidth32, 0x0, ((UINT32*)&pConfig->pNbConfig->IommuBaseAddress)[1], pConfig);
+ LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 4)), AccessS3SaveWidth32, 0x0, ((UINT32*)&pConfig->pNbConfig->IommuBaseAddress)[0], pConfig);
+
+ // Enable zeroing of address for zero-byte reads when IOMMU enabled
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG01, AccessS3SaveWidth32, (UINT32)~(BIT8 | BIT9), BIT8, pConfig);
+
+ // 8.3.1 L1 Initialization
+ LibNbIndirectTableInit (IommuPciAddress.AddressValue | L1CFG_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR(&IommuL1Table[0],NULL),
+ (sizeof (IommuL1Table) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+
+ // 8.3.3.1 L2 Common Initialization
+ LibNbIndirectTableInit (IommuPciAddress.AddressValue | L2CFG_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR(&IommuL2Table[0], NULL),
+ (sizeof (IommuL2Table) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+ //Configure PDC cache to 12-way set associative cache for A21
+ if (LibNbGetRevisionInfo (pConfig).Revision > NB_REV_A11) {
+ LibNbPciIndexRMW (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | L2REG_52, AccessS3SaveWidth32, 0x0, 0xF0000002 , pConfig);
+ }
+ // Start and lock the Iommu settings
+ LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 4)), AccessS3SaveWidth32, 0xFFFFFFFF, (UINT32)BIT0, pConfig);
+
+ //Reset IOMMU MMIO registers on system reset
+ for (i = 0; i < (sizeof (IommuMmioInitTable) / sizeof (UINT32)); i = i + 2) {
+ LibNbMemRMW (pConfig->pNbConfig->IommuBaseAddress + IommuMmioInitTable[i], AccessS3SaveWidth32, 0x0, IommuMmioInitTable[i + 1], pConfig);
+ }
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Iommu Initialization of topology specific data.
+ *
+ * @param[in] pConfig Northbridge configuration pointer
+ * @retval AGESA_SUCCESS IOMMU enable and initialized succesfully.
+ * @retval AGESA_UNSUPPORTED IOMMU not initialized.
+ */
+AGESA_STATUS
+IommuTopologyInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ // Set L2 Caches Hash Control based on maximum bus, device, function
+ IommuInitL2CacheControl ((IOMMU_PCI_TOPOLOGY*) &pConfig->pNbConfig->IommuTpologyInfo, pConfig);
+ return AGESA_SUCCESS;
+}
+
+L2_HASH_CONTROL HashControls[] = {
+ {
+ L2_DTC_CONTROL
+ },
+ {
+ L2_ITC_CONTROL
+ },
+ {
+ L2_PTC_A_CONTROL
+ },
+ {
+ L2_PTC_B_CONTROL
+ },
+ {
+ L2_PDC_CONTROL
+ }
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set L2 Cache Hash Control based on maximum Bus, Dev, Function found
+ *
+ * @param[in] PciPtr Array of bus, device, function
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+IommuInitL2CacheControl (
+ IN IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ PCI_ADDR IommuPciAddress;
+ UINTN i;
+ UINT8 FuncBitsUsed;
+ UINT8 DevBitsUsed;
+ UINT8 BusBitsUsed;
+
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " L2Cache Init Max Bus = 0x%x Max Device = 0x%x Mux Func = 0x%x\n", PciPtr->MaxBus, PciPtr->MaxDevice, PciPtr->MaxFunction));
+
+ FuncBitsUsed = CIMX_MAX (IommuGetLog2 (PciPtr->MaxFunction + 1), 3);
+ DevBitsUsed = IommuGetLog2 (PciPtr->MaxDevice + 1);
+ BusBitsUsed = IommuGetLog2 (PciPtr->MaxBus + 1);
+
+ for (i = 0; i < (sizeof (HashControls) / sizeof (L2_HASH_CONTROL)); i++) {
+ UINT8 NBits;
+ UINT8 NFuncBits;
+ UINT8 NDevBits;
+ UINT8 NBusBits;
+ LibNbPciIndexRead (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | HashControls[i].HashControl, AccessWidth32, &Value, pConfig);
+ NBits = (UINT8) (Value >> 28) - IommuGetLog2 ((Value >> 16) & 0xff);
+ NFuncBits = CIMX_MIN (NBits, 0x3);
+ NBits = NBits - NFuncBits;
+ NDevBits = CIMX_MIN ( NBits, DevBitsUsed + FuncBitsUsed - NFuncBits);
+ NBusBits = NBits - NDevBits;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " NBusBits = %d, NDevBits = %d, NFuncBits = %d \n", NBusBits, NDevBits, NFuncBits));
+ LibNbPciIndexRMW (
+ IommuPciAddress.AddressValue | L2CFG_INDEX,
+ L2CFG_SEL_WR_EN | (HashControls[i].HashControl + 1),
+ AccessS3SaveWidth32,
+ 0xFFFFFE00,
+ (NFuncBits | (NDevBits << 2) | (NBusBits << 5)) & 0x1FF,
+ pConfig
+ );
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check to see if current PCI Address is an IOMMU
+ *
+ * @param[in] IommuPciAddress PCI Address to check
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ * @retval TRUE if Iommu is enabled and found
+ */
+BOOLEAN
+IommuCheckEnable (
+ IN PCI_ADDR IommuPciAddress,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 CapBase;
+
+ if (pConfig->pNbConfig->IommuBaseAddress == 0x0) {
+ return FALSE;
+ }
+ CapBase = LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig);
+ if (CapBase == 0) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check an RD890 PCIE bridge to see if hot plug is enabled
+ *
+ * @param[in] DeviceId Device Id to check
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ * @retval TRUE if current device supports hotplug
+ */
+BOOLEAN
+IommuCheckHp (
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 PciData;
+ PCI_ADDR PciAddress;
+
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0);
+
+ LibNbPciRead (PciAddress.AddressValue | NB_PCIP_REG6C, AccessWidth32, &PciData, pConfig);
+
+ // Check for hot plug by reading PCIE_SLOT_CAP pcieConfigDev[13:2]:0x6C [6] HOTPLUG_CAPABLE
+ PciData &= BIT6;
+ if (PciData != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check a PCIE device to see if it supports phantom functions
+ *
+ * @param[in] DeviceId Device Id to check
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ * @retval TRUE if current device supports phantom functions
+ */
+BOOLEAN
+IommuCheckPhantom (
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 PciData;
+ UINT8 PcieCapBase;
+ PCI_ADDR PciAddress;
+
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0);
+
+ // Check for phantom functions by reading PCIE Device Capabilities register (base + 4) [4:3] 0 = not supported
+ PcieCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIE_CAPID, pConfig);
+ if (PcieCapBase != 0) {
+ LibNbPciRead (((PciAddress.AddressValue) | (PcieCapBase + 4)), AccessWidth32, &PciData, pConfig);
+ PciData &= PCIE_PHANTOMMASK;
+ if (PciData != 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check to see if current PCI Address is a multi-port PCIE core
+ *
+ * @param[in] DeviceId 16-bit device id to check
+ * @retval L1 configuration select
+ */
+UINT32
+IommuGetL1 (
+ IN UINT16 DeviceId
+ )
+{
+ // This function translates an RD890 multi-port pci core to the offset of the L1 entry
+ // corresponding to it. An unknown device returns as invalid
+ switch (DeviceId) {
+ case DEVICEID_GPP1_0 :
+ return L1CFG_SEL_GPP1;
+ case DEVICEID_GPP1_1 :
+ return L1CFG_SEL_GPP1;
+ case DEVICEID_GPP2_0 :
+ return L1CFG_SEL_GPP2;
+ case DEVICEID_GPP2_1 :
+ return L1CFG_SEL_GPP2;
+ case DEVICEID_GPP3A_0 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3A_1 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3A_2 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3A_3 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3A_4 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3A_5 :
+ return L1CFG_SEL_GPP3A;
+ case DEVICEID_GPP3B_0 :
+ return L1CFG_SEL_GPP3B;
+ default:
+ return PCI_INVALID;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD Device Entries
+ *
+ * @param[in] Value Value to find the logarithm of
+ * @retval Logarithm of input Value
+ */
+UINT8
+IommuGetLog2 (
+ IN UINT32 Value
+ )
+{
+ UINT8 Result;
+
+ Result = 0;
+
+ // This code will round a 32bit value to the next highest power of 2
+ Value--;
+ Value |= Value >> 1;
+ Value |= Value >> 2;
+ Value |= Value >> 4;
+ Value |= Value >> 8;
+ Value |= Value >> 16;
+ Value++;
+
+ // Calculate the logarithm
+ while (Value >>= 1) {
+ Result++;
+ }
+
+ return Result;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVRS Header for IOMMU ACPI table
+ *
+ * @param[in, out] BufferPtr Pointer to buffer to return IVRS.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+IommuPlaceHeader (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ IOMMU_IVRS_HEADER *HeaderPtr;
+ HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr;
+ LibAmdMemCopy (HeaderPtr, &RD890S_DfltHeader, sizeof (IOMMU_IVRS_HEADER), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVMD (memory device) Create all IVMD entries for a single exclusion table
+ *
+ * @param[in, out] BufferPtr Pointer to text buffer to return IVRS
+ * @param[in] pConfig Northbridge configuration pointer
+ */
+VOID
+IommuPlaceIvmdAndExclusions (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 EntryCount;
+ UINT8 CurrentExclusion;
+ AGESA_STATUS Status;
+ IOMMU_EXCLUSIONTABLE *pExclusion;
+ IOMMU_IVRS_HEADER *HeaderPtr;
+ IOMMU_IVMD_ENTRY *IvmdPtr;
+
+ pExclusion = &RD890S_DfltExclusion;
+ HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr;
+ IvmdPtr = (IOMMU_IVMD_ENTRY *)BufferPtr;
+
+ Status = LibNbCallBack (PHCB_AmdGetExclusionTable, (UINTN)&pExclusion, pConfig);
+ if (Status == AGESA_SUCCESS) {
+ EntryCount = (UINT8) ((pExclusion->TableLength - sizeof (UINTN)) / sizeof (IOMMU_EXCLUSIONRANGE));
+ for (CurrentExclusion = 0; CurrentExclusion < EntryCount; CurrentExclusion++) {
+ IvmdPtr = (IOMMU_IVMD_ENTRY*) ((UINT8*)HeaderPtr + HeaderPtr->Length);
+ IvmdPtr->Type = TYPE_IVMD_ALL; // 20h = All peripherals
+ IvmdPtr->Flags = 0x7; // Exclusion range
+ IvmdPtr->Length = 32; // 32 byte structure
+ IvmdPtr->DeviceId = 0; // Reserved for type 20h
+ IvmdPtr->AuxData = 0; // Reserved for type 20h
+ IvmdPtr->Reserved = 0;
+ IvmdPtr->BlockStartAddress = pExclusion->ExclusionRange[CurrentExclusion].Start;
+ IvmdPtr->BlockLength = pExclusion->ExclusionRange[CurrentExclusion].Length;
+ HeaderPtr->Length += 32; // Update size of IVRS
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD (hardware device) Entry for IOMMU ACPI table
+ *
+ * @param[in, out] BufferPtr Pointer to text buffer to return IVRS
+ * @param[in] pConfig Northbridge configuration pointer
+ */
+VOID
+IommuPlaceIvhdAndScanDevices (
+ IN OUT VOID *BufferPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ IOMMU_PCI_TOPOLOGY PciFlags;
+ IOMMU_IVRS_HEADER *HeaderPtr;
+ IOMMU_IVHD_ENTRY *IvhdPtr;
+ PCI_ADDR IommuPciAddress;
+
+ HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr;
+ IvhdPtr = (IOMMU_IVHD_ENTRY *)BufferPtr;
+ //PciFlags.PhantomFunction = FALSE;
+ PciFlags.MaxBus = 0;
+ PciFlags.MaxDevice = 0;
+ PciFlags.MaxFunction = 0;
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+
+ IvhdPtr = (IOMMU_IVHD_ENTRY*) ((UINT8*)HeaderPtr + HeaderPtr->Length);
+ IvhdPtr->Type = TYPE_IVHD; // Hardware block
+ IvhdPtr->Flags = FLAGS_COHERENT | FLAGS_IOTLBSUP | FLAGS_ISOC | FLAGS_RESPASSPW | FLAGS_PASSPW;
+ IvhdPtr->Length = 24; // Length = 24 with no devices
+ IvhdPtr->DeviceId = (UINT16)((IommuPciAddress.AddressValue >> 12) & 0xFFFF); // Change 32 bit ID into 16 bit
+ IvhdPtr->CapabilityOffset = (UINT16) (LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig));
+ IvhdPtr->BaseAddress = pConfig->pNbConfig->IommuBaseAddress;
+ IvhdPtr->PciSegment = 0;
+ LibNbPciRead (IommuPciAddress.AddressValue | (IvhdPtr->CapabilityOffset + 0x10), AccessWidth32, &Value, pConfig);
+ IvhdPtr->IommuInfo = (UINT16)(Value & 0x1f); //Set MSInum.
+ IvhdPtr->IommuInfo |= ((0x13) << 8); //set UnitID
+ IvhdPtr->Reserved = 0;
+
+ IommuIvhdNorthbridgeDevices (&PciFlags, IvhdPtr, pConfig);
+ if (IommuPciAddress.Address.Bus == 0) {
+ IommuIvhdSouthbridgeDevices (&PciFlags, IvhdPtr, pConfig);
+ }
+ IommuIvhdApicsAndHpets (IvhdPtr, pConfig);
+ pConfig->pNbConfig->IommuTpologyInfo = *((UINT32*) &PciFlags);
+ HeaderPtr->Length += IvhdPtr->Length;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD Device Entries
+ *
+ * @param[in, out] PciPtr Pci topology flags
+ * @param[in, out] IvhdPtr Pointer to IVHD where entry is appended
+ * @param[in] pConfig NB config block
+ */
+VOID
+IommuIvhdNorthbridgeDevices (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT16 CurrentDevice;
+ UINT16 DeviceId;
+ UINT8 EntryCount;
+ IOMMU_DEVICELIST *pDevices;
+ PCI_ADDR NbPciAddress;
+ PCI_ADDR IommuPciAddress;
+
+ pDevices = &RD890S_DfltDevices;
+ NbPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress = pConfig->NbPciAddress;
+
+ IommuPciAddress.Address.Function = NB_IOMMU;
+ EntryCount = (UINT8) ((pDevices->TableLength - sizeof (UINT16)) / sizeof (UINT16));
+
+ // Run RD890S device table, fixed for current bus
+ for (CurrentDevice = 0; CurrentDevice < EntryCount; CurrentDevice++) {
+ DeviceId = (UINT16) (NbPciAddress.Address.Bus << 8) | pDevices->Device[CurrentDevice];
+ IommuCreateDeviceEntry (PciPtr, DeviceId, IvhdPtr, pConfig);
+
+ // CHECK HOTPLUG OR PHANTOM FUNCTION SUPPORT
+ // For each device, reset PhantomEnable, but set it as a one-shot. If any device under the northbridge PCIE bridge
+ // device has phantom function support enabled, set the L1. Additionally, check the bridge for hotplug, and set the
+ // L1 if so.
+
+ //PciPtr->PhantomFunction = FALSE;
+ //if (PciPtr->PhantomFunction || IommuCheckHp (DeviceId, pConfig)) {
+ // if (IommuGetL1 (DeviceId) != PCI_INVALID && LibNbGetRevisionInfo (pConfig).Revision != NB_REV_A11) {
+ // // Determine from deviceID which L1
+ // LibNbPciIndexRMW (IommuPciAddress.AddressValue | L1CFG_INDEX, L1CFG_SEL_WR_EN | IommuGetL1 (DeviceId), AccessS3SaveWidth32, (UINT32)~BIT0, BIT0, pConfig);
+ // }
+ //}
+ //PciPtr->PhantomFunction = FALSE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD Device Entries
+ *
+ * @param[in, out] PciPtr PCI topology flags
+ * @param[in, out] IvhdPtr Pointer to IVHD where entry is appended
+ * @param[in] pConfig NB config structute
+ */
+VOID
+IommuIvhdSouthbridgeDevices (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT16 DeviceId;
+ PCI_ADDR IommuPciAddress;
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+
+ // Assume Device 0x10 Function 0 - Device 0x17 Function 7 belong to the SB
+ //PciPtr->PhantomFunction = FALSE;
+ for (DeviceId = (0x10 << 3); (DeviceId < (0x18 << 3)); DeviceId++) {
+ IommuCreateDeviceEntry (PciPtr, DeviceId, IvhdPtr, pConfig);
+ //if (PciPtr->PhantomFunction) {
+ // // Enable SB phantom enable
+ // LibNbPciIndexRMW (IommuPciAddress.AddressValue | L1CFG_INDEX, L1CFG_SEL_WR_EN | L1CFG_SEL_SB, AccessS3SaveWidth32, (UINT32)~BIT0, BIT0, pConfig);
+ //}
+ //PciPtr->PhantomFunction = FALSE;
+ }
+
+#if defined (IVHD_APIC_SUPPORT) || defined (IVHD_HPET_SUPPORT)
+ DeviceId = (SB_DEV << 3); // Bus 0 Dev 14 Func 0
+#endif
+
+#ifdef IVHD_APIC_SUPPORT
+ // Southbridge IOAPIC
+ IommuCreate8ByteEntry (DE_SPECIAL, DATA_ALLINTS, 0, 0xFF, DeviceId, VARIETY_IOAPIC, IvhdPtr);
+#endif
+
+#ifdef IVHD_HPET_SUPPORT
+ // Southbridge HPET
+ IommuCreate8ByteEntry (DE_SPECIAL, DATA_ALLINTS, 0, 0, DeviceId, VARIETY_HPET, IvhdPtr);
+#endif
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD Device Entries
+ *
+ * @param[in, out] IvhdPtr Pointer to buffer to return IVRS.
+ * @param[in] pConfig NB config structute
+ */
+VOID
+IommuIvhdApicsAndHpets (
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+#ifdef IVHD_APIC_SUPPORT
+ PCI_ADDR PciAddress;
+ UINT16 DeviceId;
+ UINT32 PciData;
+
+ PciAddress = pConfig->NbPciAddress;
+
+ // Northbridge IOAPIC
+ DeviceId = (UINT16)((PciAddress.Address.Bus << 8)) | 1; // Bus X Dev 0 Func 0
+ LibNbPciRead (PciAddress.AddressValue | 0x4C, AccessWidth32, &PciData, pConfig);
+ if (PciData & (UINT32)BIT1) {
+ IommuCreate8ByteEntry (DE_SPECIAL, DATA_NOINTS, 0, 0xFF, DeviceId, VARIETY_IOAPIC, IvhdPtr);
+ }
+#endif
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD device entry (type 2 for single function or 3/4 for multifunction) at end of IVHD entry
+ *
+ * @param[in, out] PciPtr Pci topology flags
+ * @param[in] DeviceId DeviceID of entry to potentially create
+ * @param[in, out] IvhdPtr Pointer to IVHD
+ * @param[in] pConfig NB config structute
+ */
+VOID
+IommuCreateDeviceEntry (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN UINT16 DeviceId,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ // 8 BYTE DEVICE ENTRY:
+ // [0] Type (0x2 = Device, 0x3 = Device Range Start, 0x4 = Device Range End
+ // [1] DeviceID LSB (Device/Function)
+ // [2] DeviceID MSB (Bus)
+ // [3] Data (0 = No legacy interrupts)
+
+ // DEVICEID
+ // A 16 bit bus/device/function DeviceId consists of:
+ // [15:8] Bus
+ // [7:3] Device
+ // [2:0] Function
+
+ PCI_ADDR PciAddress;
+ UINT32 PciData;
+ UINT8 DeviceCount;
+ UINT8 FunctionCount;
+ UINT8 PcieCapBase;
+ UINT8 PcixCapBase;
+
+ BOOLEAN LegacyBridge;
+ BOOLEAN MultiFunction;
+ BOOLEAN SubFunction;
+ BOOLEAN DiscreteEntry;
+ UINT8 HighFunction;
+ UINT32 ClassCode;
+ UINT16 ExtendedCapabilityPtr;
+ SB_INFO SbInfo;
+ UINT8 SataEnableRegValue;
+ BOOLEAN SrIovDevice;
+
+ PcieCapBase = 0;
+ PcixCapBase = 0;
+ LegacyBridge = FALSE;
+ MultiFunction = FALSE;
+ SubFunction = FALSE;
+ DiscreteEntry = FALSE;
+ HighFunction = 0;
+ SataEnableRegValue = 0;
+ SrIovDevice = FALSE;
+
+ //For SB700, get combined mode status
+ SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig));
+ if (SbInfo.Type == SB_SB700) {
+ LibNbPciRead (MAKE_SBDFO (0, 0, 0x14, 0, SATA_ENABLE_REG), AccessWidth8, &SataEnableRegValue , pConfig);
+ }
+
+
+ // If the device to check does not exist, exit
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0);
+ if (!LibNbIsDevicePresent (PciAddress, pConfig)) {
+ return;
+ };
+ LibNbPciRead (PciAddress.AddressValue | PCI_CLASS, AccessWidth32, &ClassCode, pConfig);
+ ClassCode = (ClassCode >> 16) & 0xFFFF; // Keep class code and sub-class only
+
+ // THREE STAGES TO THIS FUNCTION
+ // 1. Check for multifunction or special devices
+ // 2. Place device entry for the current device ID
+ // 3. If a bridge, decide if we need to traverse further
+
+ // STEP 1 - CHECK FUNCTIONS ON THIS DEVICE
+ // To make decisions, we will need several pieces of information about this device not found with current SBDFO
+ // 1. Multifunction device - To determine if a device entry, or device range entry is needed - check function 0 only
+ // 2. DisableRange - We will create single entries a device containing a PCI or PCIE bridge
+ // 3. How many functions on this device?
+
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0);
+ LibNbPciRead (PciAddress.AddressValue | PCI_HEADER, AccessWidth32, &PciData, pConfig);
+ if ((PciData & PCI_MULTIFUNCTION) != 0) {
+ MultiFunction = TRUE;
+ } else {
+ DiscreteEntry = TRUE;
+ }
+ if ((DeviceId & 0x7) != 0 && MultiFunction) {
+ SubFunction = TRUE;
+ }
+
+ if (MultiFunction) {
+ for (FunctionCount = 0; FunctionCount < 8; FunctionCount++) {
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, FunctionCount, 0);
+ LibNbPciRead (PciAddress.AddressValue | PCI_HEADER, AccessWidth32, &PciData, pConfig);
+ if (PciData != PCI_INVALID) {
+ HighFunction = FunctionCount;
+ }
+ LibNbPciRead (PciAddress.AddressValue | PCI_CLASS, AccessWidth32, &PciData, pConfig);
+ if (((PciData >> 16) & 0xFFFF) == PCI_BRIDGE_CLASS) {
+ DiscreteEntry = TRUE;
+ }
+ }
+ }
+
+ // For SR IOV devices set for all functions to be available
+ if (MultiFunction && (!DiscreteEntry) && (!SubFunction)) {
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0);
+ ExtendedCapabilityPtr = LibNbFindPcieExtendedCapability (PciAddress.AddressValue, 0x10, pConfig);
+ if (ExtendedCapabilityPtr != 0) {
+ SrIovDevice = TRUE;
+ }
+ }
+ // STEP 2 - PLACE DEVICE ENTRY
+ // We have already decided whether we should use discrete type2 entries, or ranged type3/4 entries
+ // Place each device entry at the end of the current IVHD
+ // In each case, increment the maximum bus/device/function for L2 cache control done after the IVHD is created
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NBIOMMU]Placing Entry for Device [0x%x]\n", DeviceId));
+
+ //if (IommuCheckPhantom (DeviceId, pConfig)) {
+ // PciPtr->PhantomFunction = TRUE;
+ //}
+
+ if (!MultiFunction || DiscreteEntry) {
+ //For Device 0x14, function 0, Set DATA_ALLINTS
+ if (DeviceId == (SB_DEV << 3)) {
+ IommuCreate4ByteEntry (DE_SELECT, DATA_ALLINTS, DeviceId, IvhdPtr);
+ } else if (DeviceId == DEVICEID_IDE) {
+ // For IDE device 0x14, function 1, first check if in combined mode
+ if (SataEnableRegValue & SATA_COMBINED_MODE) {
+ // Create Alias entry in combined mode
+ IommuCreate8ByteEntry (DE_ALIASSELECT, DATA_NOINTS, DEVICEID_IDE, 0, DEVICEID_SATA, 00, IvhdPtr);
+ } else {
+ //Create select entry if not in the combined mode
+ IommuCreate4ByteEntry (DE_SELECT, 0, DeviceId, IvhdPtr);
+ }
+ } else {
+ // For all other single function devices other than device 0x14, functions 0 or 1, create select entry
+ IommuCreate4ByteEntry (DE_SELECT, 0, DeviceId, IvhdPtr);
+ }
+
+ // Record the largest bus, device, function which will be used as a mask by the Iommu L2 cache
+ // Record if phantom device present for current device. Only set it if present, do not clear.
+// if (IommuCheckPhantom (DeviceId, pConfig)) {
+// PciPtr->PhantomFunction = TRUE;
+// }
+ IommuRecordBusDevFuncInfo (PciPtr, DeviceId, pConfig);
+ }
+
+ if (MultiFunction && (!DiscreteEntry) && (!SubFunction)) {
+
+ // This is a multifunction device without a bridge, so create a type 3 and 4 device entry
+ IommuCreate4ByteEntry (DE_START, 0, DeviceId, IvhdPtr);
+ if (SrIovDevice) {
+ IommuCreate4ByteEntry (DE_END, 0, (DeviceId | 0x00FF), IvhdPtr);
+ } else {
+ IommuCreate4ByteEntry (DE_END, 0, DeviceId + HighFunction, IvhdPtr);
+ }
+
+ // Record the largest bus, device, function which will be used as a mask by the Iommu L2 cache
+ // Record if phantom device present for current device. Only set it if present, do not clear.
+// if (IommuCheckPhantom (DeviceId, pConfig)) {
+// PciPtr->PhantomFunction = TRUE;
+// }
+ IommuRecordBusDevFuncInfo (PciPtr, DeviceId + HighFunction, pConfig);
+ }
+
+ if (ClassCode == PCI_BRIDGE_CLASS) {
+ UINTN Type;
+ UINT32 BusData;
+ // STEP 3 - BRIDGE DEVICE
+ // These are treated a little differently. We already created the entry for the bridge itself...
+ // For a PCIe bridge, continue down the bridge device creating more entries until we find an endpoint
+ // For a PCI bridge, define the entire sub-bus range as belonging to this source id
+ // For a PCIX bridge, figure out which mode it is operating in
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0);
+ LibNbPciRead (PciAddress.AddressValue | PCI_BUS, AccessWidth32, &BusData, pConfig);
+ PcieCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIE_CAPID, pConfig);
+ PcixCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIX_CAPID, pConfig);
+
+ Type = 0;
+ if (PcieCapBase != 0) {
+ Type = 1;
+ LibNbPciRead (PciAddress.AddressValue | PcieCapBase, AccessWidth32, &PciData, pConfig);
+ PciData = (PciData >> 16) & PCIE_PORTMASK; // [7:4] are Device/Port type, 01
+ if (PciData == PCIE_PCIE2PCIX) {
+ Type = 2;
+ }
+ }
+ if (PcixCapBase != 0) {
+ Type = 2;
+ }
+
+ //For Hot plug capable devices, create 'Start of range' and 'End of range' IVRS'.
+ // This will override Type 1 and Type 2.
+ if (IommuCheckHp (DeviceId, pConfig)) {
+ Type = 3;
+ }
+
+ switch (Type) {
+ case 0:
+ //PCI
+ IommuRecordBusDevFuncInfo (PciPtr, DeviceId, pConfig);
+ IommuCreate8ByteEntry (DE_ALIASSTART, DATA_NOINTS, (UINT16) (BusData & 0xFF00), 0, DeviceId, 0, IvhdPtr);
+ IommuCreate4ByteEntry (DE_END, 0, (UINT16) (((BusData & 0xFF0000) >> 8) + 0xFF), IvhdPtr);
+ break;
+ case 1:
+ //Pcie (non hot plug)
+ for (DeviceCount = 0; DeviceCount <= 0x1f; DeviceCount++) {
+ for (FunctionCount = 0; FunctionCount <= 0x7; FunctionCount++) {
+ IommuCreateDeviceEntry (PciPtr, ((UINT16) (BusData & 0xFF00)) | (DeviceCount << 3) | FunctionCount, IvhdPtr, pConfig);
+ }
+ }
+ break;
+ case 2:
+ //PCIx
+ IommuRecordBusDevFuncInfo (PciPtr, (UINT16) (BusData & 0xFF00), pConfig);
+ IommuCreate8ByteEntry (DE_ALIASSTART, DATA_NOINTS, (UINT16) ((BusData & 0xFF00) | ( 1 << 3)), 0, (UINT16) (BusData & 0xFF00), 0, IvhdPtr);
+ IommuCreate4ByteEntry (DE_END, 0, (UINT16) (((BusData & 0xFF0000) >> 8) + 0xFF), IvhdPtr);
+ break;
+ case 3:
+ //For Hot plug ports, set all devices and functions behind the secondary bus.
+ IommuCreate4ByteEntry (DE_START, 0, (UINT16) (BusData & 0xFF00), IvhdPtr); // Secondary bus, Device 0, Function 0
+ IommuCreate4ByteEntry (DE_END, 0, (UINT16) ((BusData & 0xFF00) | (0x1F << 3) | 7), IvhdPtr); // Secondary bus, Device 1f, Function 7
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Place IVHD device entry (type 2 for single function or 3/4 for multifunction) at end of IVHD entry
+ *
+ * @param[in, out] PciPtr Pci topology flags
+ * @param[in] DeviceId DeviceID
+ * @param[in] pConfig NB config structute
+ */
+VOID
+IommuRecordBusDevFuncInfo (
+ IN OUT IOMMU_PCI_TOPOLOGY *PciPtr,
+ IN UINT16 DeviceId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT16 ExtendedCapabilityPtr;
+ PCI_ADDR Device;
+ Device.AddressValue = MAKE_SBDFO (0, DeviceId >> 8, (DeviceId >> 3) & 0x1f, DeviceId & 0x7, 0);
+#ifdef EXCLUDE_SB_DEVICE_FROM_L2_HASH
+ if ((UINT8)Device.Address.Bus == 0) {
+ AMD_NB_CONFIG_BLOCK *ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig);
+ if (ConfigPtr->PlatformType == ServerPlatform) {
+ return;
+ }
+ }
+#endif
+ Device.AddressValue = MAKE_SBDFO (0, DeviceId >> 8, (DeviceId >> 3) & 0x1f, DeviceId & 0x7, 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " Device Data For L2 Hash Bus = 0x%x Device = 0x%x Func = 0x%x\n", Device.Address.Bus, Device.Address.Device, Device.Address.Function));
+ ExtendedCapabilityPtr = LibNbFindPcieExtendedCapability (Device.AddressValue, 0x10, pConfig);
+ if (ExtendedCapabilityPtr != 0) {
+ UINT16 TotalVF;
+ LibNbPciRead (Device.AddressValue | (ExtendedCapabilityPtr + 0xE), AccessWidth16, &TotalVF, pConfig);
+ PciPtr->MaxFunction = CIMX_MAX (PciPtr->MaxFunction, TotalVF);
+ }
+ PciPtr->MaxBus = CIMX_MAX (PciPtr->MaxBus, (UINT8)Device.Address.Bus);
+ PciPtr->MaxDevice = CIMX_MAX (PciPtr->MaxDevice, (UINT8)Device.Address.Device);
+ PciPtr->MaxFunction = CIMX_MAX (PciPtr->MaxFunction, (UINT16) (UINT8)Device.Address.Function);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Append data entry to IVRS
+ *
+ * @param[in] Type IVRC entry type
+ * @param[in] Data IVRC entry data
+ * @param[in] Word1 IVRC entry data
+ * @param[in, out] IvhdPtr Current IVHD pointer
+ *
+ */
+VOID
+IommuCreate4ByteEntry (
+ IN UINT8 Type,
+ IN UINT8 Data,
+ IN UINT16 Word1,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr
+ )
+{
+ UINT32 Buffer;
+ UINT16 AlignedDeviceEntryIndex;
+ UINT16 DeviceEntryIndex;
+
+ Buffer = Type + (Word1 << 8) + (Data << 24);
+ DeviceEntryIndex = (IvhdPtr->Length - 24) / sizeof (UINT32);
+ AlignedDeviceEntryIndex = DeviceEntryIndex;
+
+#ifdef IVHD_MIN_8BYTE_ALIGNMENT
+ AlignedDeviceEntryIndex = (DeviceEntryIndex + 1) & 0xfffe;
+#endif
+
+ IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex] = Buffer;
+ IvhdPtr->Length += (4 + (AlignedDeviceEntryIndex - DeviceEntryIndex) * 4);
+ CIMX_TRACE ((TRACE_DATA (NULL, CIMX_NB_TRACE), "[NBIOMMU]Added entry - [0x%x]\n", Buffer));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Append data entry to IVRS
+ *
+ * @param[in] Type IVRC entry type
+ * @param[in] Data IVRC entry data
+ * @param[in] Word1 IVRC entry data
+ * @param[in] Byte4 IVRC entry data
+ * @param[in] Word5 IVRC entry data
+ * @param[in] Byte7 IVRC entry data
+ * @param[in, out] IvhdPtr Current IVHD pointer
+ *
+ */
+VOID
+IommuCreate8ByteEntry (
+ IN UINT8 Type,
+ IN UINT8 Data,
+ IN UINT16 Word1,
+ IN UINT8 Byte4,
+ IN UINT16 Word5,
+ IN UINT8 Byte7,
+ IN OUT IOMMU_IVHD_ENTRY *IvhdPtr
+ )
+{
+ UINT16 AlignedDeviceEntryIndex;
+ UINT16 DeviceEntryIndex;
+ UINT64 Buffer;
+
+ Buffer = Type + (Word1 << 8) + ((UINT32)Data << 24);
+ ((UINT32*)&Buffer)[1] = Byte4 + (Word5 << 8) + (Byte7 << 24);
+ DeviceEntryIndex = (IvhdPtr->Length - 24) / sizeof (UINT32);
+ AlignedDeviceEntryIndex = DeviceEntryIndex;
+
+#if defined (IVHD_MIN_8BYTE_ALIGNMENT) || defined (IVHD_SIZE_ALIGNMENT)
+ AlignedDeviceEntryIndex = (DeviceEntryIndex + 1) & 0xfffe;
+#endif
+ IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex] = ((UINT32*)&Buffer)[0];
+ IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex + 1] = ((UINT32*)&Buffer)[1];
+ IvhdPtr->Length += (8 + (AlignedDeviceEntryIndex - DeviceEntryIndex) * 4);
+ CIMX_TRACE ((TRACE_DATA (NULL, CIMX_NB_TRACE), "[NBIOMMU]Added entry - [0x%llx]\n", Buffer));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set checksum, IvInfo, finish IVRS table
+ *
+ * @param[in, out] BufferPtr Pointer to text buffer to return IVRS.
+ * @param[in, out] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+IommuFinalizeIvrs (
+ IN OUT VOID *BufferPtr,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ IOMMU_IVRS_HEADER *HeaderPtr;
+ PCI_ADDR IommuPciAddress;
+ UINT32 PciData;
+
+ HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr;
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+
+ // Find common IvInfo (largest shared) 0x50
+ // [22] = ATS Translation Reserved
+ // [21:15] = VA Size
+ // [14:8] = PA Size
+
+ LibNbPciRead (IommuPciAddress.AddressValue | RD890S_CAP_MISC, AccessWidth32, &PciData, pConfig);
+ PciData &= (IVINFO_ATSMASK | IVINFO_VAMASK | IVINFO_PAMASK);
+ HeaderPtr->IvInfo = PciData;
+
+ //LibAmdUpdateAcpiTableChecksum (HeaderPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Nb Iommu Fixup of IVRS APIC entries
+ *
+ * @param[in] DevicePtr Pointer to current device entry
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+UINT64
+IommuGetApicBaseAddress (
+ IN VOID *DevicePtr,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR PciAddress;
+ UINT16 DeviceId;
+ UINT32 Data;
+
+ // If no pointer provided, return no base address
+ if (DevicePtr == NULL) {
+ return 0;
+ }
+
+ // Special entry can be IOAPIC or other(HPET). We only care about the IOAPIC.
+ if (*(UINT8*) ((UINT8*)DevicePtr + DE_SPECIAL_VARIETY) != VARIETY_IOAPIC) {
+ return 0;
+ }
+
+ DeviceId = *(UINT16*) ((UINT8*)DevicePtr + DE_DEVICEID);
+ PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0);
+
+ // An APIC entry will only be created for AMD northbridge or southbridges, so
+ // we can assume PCI dev/func = 0, 0 will be a northbridge IOAPIC device
+ // and any other will be a southbridge IOAPIC device. If the device was not
+ // already enabled and known to be an AMD device, no entry would have been created.
+
+ if ((PciAddress.Address.Device == NB_PCI_DEV) && (PciAddress.Address.Function == NB_HOST)) {
+
+ // We have an AMD NB, check function 0
+ Data = 1;
+ PciAddress.Address.Function = 0;
+ LibNbPciWrite (PciAddress.AddressValue | 0xF8, AccessS3SaveWidth32, &Data, pConfig);
+ LibNbPciRead (PciAddress.AddressValue | 0xFC, AccessWidth32, &Data, pConfig);
+ } else {
+ SB_INFO SbInfo;
+ SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig));
+ if (SbInfo.Type == SB_SB700) {
+ PciAddress.Address.Function = 0;
+ LibNbPciRead (PciAddress.AddressValue | 0x74, AccessWidth32, &Data, pConfig);
+ } else {
+ LibAmdSbPmioRead ( 0x34, AccessWidth32, &Data, pConfig);
+ }
+ }
+ return ((UINT64) (Data & 0xFFFFFF00));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Nb Iommu Fixup of IVRS APIC entries
+ *
+ * @param[in] BaseAddress Base address to match
+ * @param[in] MadtPtr Pointer to current device entry
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+UINT8
+IommuGetApicId (
+ IN UINT64 BaseAddress,
+ IN VOID *MadtPtr,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ VOID *EntryPtr;
+
+ EntryPtr = LibAmdGetFirstMadtStructure (MADT_APIC_TYPE, MadtPtr);
+
+ do {
+ // If our base address for a known device matches this MADT, get the APIC ID
+ if (*(UINT32*) ((UINT8*)EntryPtr + MADT_APIC_BASE) == (UINT32)BaseAddress) {
+ return *(UINT8*) ((UINT8*)EntryPtr + MADT_APIC_ID);
+ }
+ EntryPtr = LibAmdGetNextMadtStructure (MADT_APIC_TYPE, EntryPtr, MadtPtr);
+ } while (EntryPtr != NULL);
+ return 0xFF;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Disconnect unused PCIe core from IOMMU block.
+ *
+ * @param[in] CoreId Pcie Core Id
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+NbIommuDisconnectPcieCore (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR IommuPciAddress;
+ UINT32 Value;
+ IommuPciAddress = pConfig->NbPciAddress;
+ IommuPciAddress.Address.Function = NB_IOMMU;
+ Value = 1 << ((0x4310 >> (CoreId * 4)) & 0xf);
+ LibNbPciIndexRMW (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | L2REG_46, AccessS3SaveWidth32, 0xFFFFFFFF, Value , pConfig);
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbIommu.h b/src/vendorcode/amd/cimx/rd890/nbIommu.h
new file mode 100644
index 0000000000..7fc2c5c908
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbIommu.h
@@ -0,0 +1,326 @@
+/**
+ * @file
+ *
+ * Routines for IOMMU.
+ *
+ * Implement the IOMMU init and ACPI feature.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+// Identifying an IOMMU:
+// RD890S - IOMMU present
+// all other (including RD890) - IOMMU not present
+// Class = System Base Peripheral (08h)
+// Subclass = IOMMU (06h)
+// Programming Interface Code = 0h
+// Must reside on top/root complex PCI hierarchy
+// There is always a NB device at bus 0 device 0 function 0 (fcn 2 for IOMMU) - device ID 0x5A23
+
+// Inputs:
+// From OEM: Get exclusion table
+// From OEM: Get text buffer
+
+// Outputs:
+// To OEM: Complete IVRS table for linking
+
+#ifndef _NBIOMMU_H_
+#define _NBIOMMU_H_
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+AGESA_STATUS
+NbIommuInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbIommuInitS3 (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbIommuAcpiInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbIommuAcpiFixup (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+VOID
+NbIommuDisconnectPcieCore (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+// IOMMU Architectural
+#define IVRS_BUFFER_SIZE 0x2000 // Default 8KB allocated to table
+//#define IVHD_MIN_8BYTE_ALIGNMENT // Align IVHD entries on 8 byte boundary
+#define IVHD_SIZE_ALIGNMENT // Align IVHD entries on MOD entry-size boundary
+#define IVHD_HPET_SUPPORT // Create HPET entries
+#define IVHD_APIC_SUPPORT // Create IOAPIC entries
+
+// IOMMU Northbridge
+#define RD890S_CAP_MISC 0x50 // RD890/S Capabilities Misc Info
+#define NB_PCI_DEV 0 // PCI NB device number
+#define NB_HOST 0 // Function 0 = NB HOST
+#define NB_IOMMU 2 // Function 2 = IOMMU
+#define SB_DEV 0x14 // PCI SB device number
+#define SB_SMBUS 3 // Function 3 = SMBUS
+#define SB_SATA 0x11 // SB SATA
+#define SATA_ENABLE_REG 0xAD // Dev. 0x14, Func 0, Reg 0xAD for SATA combined mode
+#define SATA_COMBINED_MODE BIT3 // Bit 3 of SB_ENABLE_REG., 1 = Combined mode
+
+#define IOMMU_CAP_HEADER_OFFSET 0x00
+#define IOMMU_BASE_LOW_OFFSET 0x04
+#define IOMMU_BASE_HIGH_OFFSET 0x08
+#define IOMMU_RANGE_OFFSET 0x0C
+#define IOMMU_MISC_OFFSET 0x10
+
+#define DEVICEID_NB ((0 << 8) + (NB_PCI_DEV << 3) + NB_HOST)
+#define DEVICEID_IOMMU ((0 << 8) + (NB_PCI_DEV << 3) + NB_IOMMU)
+#define DEVICEID_GPP1_0 ((0 << 8) + (0x2 << 3) + 0)
+#define DEVICEID_GPP1_1 ((0 << 8) + (0x3 << 3) + 0)
+#define DEVICEID_GPP2_0 ((0 << 8) + (0xB << 3) + 0)
+#define DEVICEID_GPP2_1 ((0 << 8) + (0xC << 3) + 0)
+#define DEVICEID_GPP3A_0 ((0 << 8) + (0x4 << 3) + 0)
+#define DEVICEID_GPP3A_1 ((0 << 8) + (0x5 << 3) + 0)
+#define DEVICEID_GPP3A_2 ((0 << 8) + (0x6 << 3) + 0)
+#define DEVICEID_GPP3A_3 ((0 << 8) + (0x7 << 3) + 0)
+#define DEVICEID_GPP3A_4 ((0 << 8) + (0x9 << 3) + 0)
+#define DEVICEID_GPP3A_5 ((0 << 8) + (0xA << 3) + 0)
+#define DEVICEID_GPP3B_0 ((0 << 8) + (0xD << 3) + 0)
+
+#define DEVICEID_SATA ((0 << 8) + (0x11 << 3) + 0)
+#define DEVICEID_IDE ((0 << 8) + (0x14 << 3) + 1)
+
+#define L1CFG_INDEX 0xF8
+// There is an L1 for each device (6), which is selected by [19:16] of L1CFG_INDEX
+// e.g. (LibNbPciIndexRead (Address | L1CFGIND, L1_REG_0C | L1_CFG_SEL, AccessWidth32, &Value, pConfig)
+#define L1CFG_SEL_WR_EN 0x80000000
+#define L1CFG_SEL_GPP1 0x00000000
+#define L1CFG_SEL_GPP2 0x00010000
+#define L1CFG_SEL_SB 0x00020000
+#define L1CFG_SEL_GPP3A 0x00030000
+#define L1CFG_SEL_GPP3B 0x00040000
+#define L1CFG_SEL_VC1 0x00050000
+#define L1REG_06 0x6
+#define L1REG_0C 0xC
+#define L1REG_0D 0xD
+#define L1REG_07 0x7
+#define L1CFG_DATA 0xFC
+
+#define L2CFG_INDEX 0xF0
+// e.g. (LibNbPciIndexRead (Address | L2CFGIND, L2_REG_0C, AccessWidth16, &Value, pConfig)
+#define L2CFG_SEL_WR_EN 0x100
+#define L2REG_06 0x6
+#define L2REG_07 0x7
+#define L2REG_0C 0xC
+#define L2REG_10 0x10
+#define L2REG_11 0x11
+#define L2REG_14 0x14
+#define L2REG_15 0x15
+#define L2REG_18 0x18
+#define L2REG_19 0x19
+#define L2REG_1C 0x1C
+#define L2REG_1D 0x1D
+#define L2REG_46 0x46
+#define L2REG_47 0x47
+#define L2REG_50 0x50
+#define L2REG_51 0x51
+#define L2REG_52 0x52
+#define L2REG_56 0x56
+#define L2REG_30 0x30
+#define L2REG_80 0x80
+#define L2CFG_DATA 0xF4
+
+// PCI/PCIe Architectural
+#define PCIE_CAPID 0x10
+#define PCIE_PORTMASK 0xF0 // Device cap reg 2
+#define PCIE_PCIE2PCIX 0x70 // Device cap reg 2
+#define PCIE_PHANTOMMASK 0x18 // Device cap reg 4
+#define PCIX_CAPID 0x07
+#define IOMMU_CAPID 0x0F
+
+#define PCI_DVID 0x00
+#define PCI_INVALID 0xFFFFFFFF
+#define PCI_CLASS 0x08
+#define PCI_HEADER 0x0C
+#define PCI_MULTIFUNCTION 0x00800000
+#define PCI_BUS 0x18
+#define PCI_SUBMASK 0xFF0000
+#define PCI_SECMASK 0xFF00
+#define PCI_PRIMASK 0xFF
+#define PCI_BRIDGE_CLASS 0x0604
+
+// IVRS Table Access
+#define TYPE_IVHD 0x10
+#define IVINFO_ATSMASK 0x00400000 // [22] = ATS
+#define IVINFO_VAMASK 0x003F8000 // [21:15] = Virtual Address Size
+#define IVINFO_PAMASK 0x00007F00 // [14:8] = Physical Address Size
+#define FLAGS_COHERENT BIT5
+#define FLAGS_IOTLBSUP BIT4
+#define FLAGS_ISOC BIT3
+#define FLAGS_RESPASSPW BIT2
+#define FLAGS_PASSPW BIT1
+
+#define TYPE_IVMD_ALL 0x20
+#define TYPE_IVMD_SELECT 0x21
+#define TYPE_IVMD_RANGE 0x22
+
+#define DE_PAD4 1
+#define DE_BYTE0 0
+#define DE_BYTE1 1
+#define DE_BYTE2 2
+#define DE_BYTE3 3
+#define DE_SELECT 2
+#define DATA_NOINTS 0
+#define DATA_LINT_EINT_INIT BIT7 + BIT6 + BIT1 + BIT0
+#define DATA_ALLINTS 0xD7
+#define DE_START 3
+#define DE_END 4
+#define DE_PAD8 64
+#define DE_BYTE4 4
+#define DE_BYTE5 5
+#define DE_BYTE6 6
+#define DE_BYTE7 7
+#define DE_ALIASSELECT 66
+#define DE_ALIASSTART 67
+#define DE_SPECIAL 72
+#define VARIETY_IOAPIC 0x1
+#define VARIETY_HPET 0x2
+#define DE_SPECIAL_VARIETY 7
+#define DE_DEVICEID 5
+#define DE_SPECIAL_ID 4
+
+// MADT Table Access
+#define MADT_APIC_TYPE 0x1
+#define MADT_APIC_ID 0x2
+#define MADT_APIC_BASE 0x4
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+#pragma pack (push, 1)
+
+/// IVRS header
+typedef struct {
+ UINT32 Signature; ///< see IOMMU specification for details
+ UINT32 Length; ///< see IOMMU specification for details
+ UINT8 Revision; ///< see IOMMU specification for details
+ UINT8 Checksum; ///< see IOMMU specification for details
+ CHAR8 OemId[6]; ///< see IOMMU specification for details
+ CHAR8 OemTableId[8]; ///< see IOMMU specification for details
+ CHAR8 OemRevision[4]; ///< see IOMMU specification for details
+ CHAR8 CreatorId[4]; ///< see IOMMU specification for details
+ CHAR8 CreatorRevision[4]; ///< see IOMMU specification for details
+ UINT32 IvInfo; ///< see IOMMU specification for details
+ UINT64 Reserved; ///< see IOMMU specification for details
+} IOMMU_IVRS_HEADER;
+
+/// DeviceID
+typedef struct {
+ UINT16 TableLength; ///< length of table
+ UINT16 Device[]; ///< DeviceID
+} IOMMU_DEVICELIST;
+
+/// PCI Topology Based Settings
+typedef struct {
+// BOOLEAN PhantomFunction; ///< phantom functions present
+ UINT8 MaxBus; ///< max bus accumulator
+ UINT8 MaxDevice; ///< max device accumulator
+ UINT16 MaxFunction; ///< max function accumulator
+} IOMMU_PCI_TOPOLOGY;
+
+/// IVHD for each hardware definition (i.e. # of northbridges)
+typedef struct {
+ UINT8 Type; ///< see IOMMU specification for details
+ UINT8 Flags; ///< see IOMMU specification for details
+ UINT16 Length; ///< see IOMMU specification for details
+ UINT16 DeviceId; ///< see IOMMU specification for details
+ UINT16 CapabilityOffset; ///< see IOMMU specification for details
+ UINT64 BaseAddress; ///< see IOMMU specification for details
+ UINT16 PciSegment; ///< see IOMMU specification for details
+ UINT16 IommuInfo; ///< see IOMMU specification for details
+ UINT32 Reserved; ///< see IOMMU specification for details
+ UINT32 DeviceEntry[]; ///< see IOMMU specification for details
+} IOMMU_IVHD_ENTRY;
+
+/// IVMD for each memory range
+typedef struct {
+ UINT8 Type; ///< see IOMMU specification for details
+ UINT8 Flags; ///< see IOMMU specification for details
+ UINT16 Length; ///< see IOMMU specification for details
+ UINT16 DeviceId; ///< see IOMMU specification for details
+ UINT16 AuxData; ///< see IOMMU specification for details
+ UINT64 Reserved; ///< see IOMMU specification for details
+ UINT64 BlockStartAddress; ///< see IOMMU specification for details
+ UINT64 BlockLength; ///< see IOMMU specification for details
+} IOMMU_IVMD_ENTRY;
+
+//#define IVRS_HANDLE 'SRVI'
+#define IVRS_HANDLE Int32FromChar ('S', 'R', 'V', 'I')
+
+#define L2_DTC_CONTROL 0x10
+#define L2_ITC_CONTROL 0x14
+#define L2_PTC_A_CONTROL 0x18
+#define L2_PTC_B_CONTROL 0x1C
+#define L2_PDC_CONTROL 0x50
+
+#define EXCLUDE_SB_DEVICE_FROM_L2_HASH
+
+/// L2 cache init
+typedef struct {
+ UINT8 HashControl; ///<Control regsiter block address
+} L2_HASH_CONTROL;
+
+#pragma pack (pop)
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.c b/src/vendorcode/amd/cimx/rd890/nbLib.c
new file mode 100644
index 0000000000..5862768bb0
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbLib.c
@@ -0,0 +1,1138 @@
+/**
+ * @file
+ *
+ * NB library functions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get silicon type and revision info.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr configuration structure pointer.
+ * @retval NB_INFO Northbrige Info Structure.
+ */
+/*----------------------------------------------------------------------------------------*/
+NB_INFO
+LibNbGetRevisionInfo (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ NB_INFO RevisionInfo;
+ UINT16 DeviceId;
+ UINT8 RevisionId;
+ UINT32 PrivateId;
+ LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x8, AccessWidth8, &RevisionId, NbConfigPtr);
+ RevisionInfo.Revision = RevisionId;
+ LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x2, AccessWidth16, &DeviceId, NbConfigPtr);
+ switch (DeviceId) {
+ case 0x5956:
+ RevisionInfo.Type = NB_RD890TV;
+ break;
+ case 0x5957:
+ RevisionInfo.Type = NB_RX780;
+ break;
+ case 0x5958:
+ RevisionInfo.Type = NB_RD780;
+ break;
+ case 0x5A10:
+ RevisionInfo.Type = NB_SR5690;
+ break;
+ case 0x5A11:
+ RevisionInfo.Type = NB_RD890;
+ break;
+ case 0x5A12:
+ RevisionInfo.Type = NB_SR5670;
+ break;
+ case 0x5A13:
+ RevisionInfo.Type = NB_SR5650;
+ break;
+ case 0x5A14:
+ RevisionInfo.Type = NB_990FX;
+ LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG7D, AccessWidth32, &PrivateId, NbConfigPtr);
+ PrivateId = (PrivateId >> 21) & 0x0f;
+ if (PrivateId == 1) {
+ RevisionInfo.Type = NB_990FX;
+ }
+ if (PrivateId == 2) {
+ RevisionInfo.Type = NB_990X;
+ }
+ if (PrivateId == 3) {
+ RevisionInfo.Type = NB_970;
+ }
+ break;
+ default:
+ RevisionInfo.Type = NB_UNKNOWN;
+ CIMX_ASSERT (FALSE);
+ }
+ return RevisionInfo;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] CallBackId Callback ID.
+ * @param[in] Data Callback specific data.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibNbCallBack (
+ IN UINT32 CallBackId,
+ IN OUT UINTN Data,
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ CALLOUT_ENTRY CallBackPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr)->StandardHeader.CalloutPtr;
+
+ Status = AGESA_UNSUPPORTED;
+ if (CallBackPtr != NULL) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack CallBackId = 0x%x\n", CallBackId));
+ Status = (*CallBackPtr) (CallBackId, Data, GET_BLOCK_CONFIG_PTR (NbConfigPtr));
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack Return = 0x%x\n", Status));
+ }
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] SystemApi Pointer to System API
+ * @param[in] ConfigPtr Northbridge block configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibSystemApiCall (
+ IN SYSTEM_API SystemApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ API_WORKSPACE Workspace;
+ UINT8 NorthbridgeId;
+
+ LibAmdMemFill (&Workspace, 0, sizeof (API_WORKSPACE), (AMD_CONFIG_PARAMS *)&(ConfigPtr->StandardHeader));
+ Workspace.ConfigPtr = ConfigPtr;
+ Workspace.Status = AGESA_SUCCESS;
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ ConfigPtr->Northbridges[NorthbridgeId].ConfigPtr = &Workspace.ConfigPtr;
+ }
+ if (SystemApi != NULL) {
+ (*SystemApi)(ConfigPtr);
+ }
+ return Workspace.Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Call Back routine.
+ *
+ *
+ *
+ * @param[in] NbApi Pointer to NB API
+ * @param[in] ConfigPtr Northbridge block configuration structure pointer
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+LibNbApiCall (
+ IN NB_API NbApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ UINT8 NorthbridgeId;
+ AGESA_STATUS Status;
+
+ Status = AGESA_SUCCESS;
+ for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
+ AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId];
+ ConfigPtr->CurrentNorthbridge = NorthbridgeId;
+ if (!LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) {
+ REPORT_EVENT (AGESA_WARNING, GENERAL_ERROR_NB_NOT_PRESENT, 0 , 0, 0, 0, NbConfigPtr);
+ continue;
+ }
+ if (NbApi != NULL) {
+ Status = (*NbApi) (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ break;
+ }
+ }
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write PCI register.
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Value Pointer to new register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciWrite (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR DeviceAddress;
+ DeviceAddress.AddressValue = Address;
+ LibAmdPciWrite (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PCI register
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbPciRead (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR DeviceAddress;
+ DeviceAddress.AddressValue = Address;
+ LibAmdPciRead (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write PCI register
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Width Access width.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbPciRMW (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbPciRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbPciWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexRead (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 IndexOffset;
+ IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
+ LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
+ LibNbPciRead (Address + IndexOffset, Width, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Value Pointer to save register value.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexWrite (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 IndexOffset;
+ IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
+ LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
+ LibNbPciWrite (Address + IndexOffset , Width, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write PCI Index/Data Address space
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address.
+ * @param[in] Width Access width of Index/Data register.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbPciIndexRMW (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbPciIndexRead (Address, Index, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbPciIndexWrite (Address, Index, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Program table of indirect register.
+ *
+ *
+ *
+ * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
+ * @param[in] Index Index Address. Index address OR with INDIRECT_REG_ENTRY.Register
+ * @param[in] pTable Pointer to indirect register table.
+ * @param[in] Length Number of entry in indirect register table.
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbIndirectTableInit (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN INDIRECT_REG_ENTRY *pTable,
+ IN UINTN Length,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINTN i;
+ for (i = 0; i < Length; i++) {
+ LibNbPciIndexRMW (Address, Index | pTable[i].Register , AccessS3SaveWidth32, pTable[i].Mask, pTable[i].Data, NbConfigPtr);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCI capability pointer
+ *
+ *
+ *
+ *
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT8
+LibNbFindPciCapability (
+ IN UINT32 Address,
+ IN UINT8 CapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT8 CapabilityPtr;
+ UINT8 CurrentCapabilityId;
+ PCI_ADDR Device;
+ Device.AddressValue = Address;
+ CapabilityPtr = 0x34;
+ if (!LibNbIsDevicePresent (Device, NbConfigPtr)) {
+ return 0;
+ }
+ while (CapabilityPtr != 0) {
+ LibNbPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, NbConfigPtr);
+ if (CapabilityPtr) {
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, NbConfigPtr);
+ if (CurrentCapabilityId == CapabilityId) break;
+ CapabilityPtr++;
+ }
+ }
+ return CapabilityPtr;
+}
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCIe extended capability pointer
+ *
+ *
+ *
+ *
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT16
+LibNbFindPcieExtendedCapability (
+ IN UINT32 Address,
+ IN UINT16 ExtendedCapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT16 CapabilityPtr;
+ UINT32 ExtendedCapabilityIdBlock;
+ if (LibNbFindPciCapability (Address, 0x10, NbConfigPtr) != 0) {
+ CapabilityPtr = 0x100;
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
+ if (ExtendedCapabilityIdBlock != 0 && (UINT16)ExtendedCapabilityIdBlock != 0xffff) {
+ do {
+ if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) {
+ return CapabilityPtr;
+ }
+ CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff);
+ LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
+ } while (CapabilityPtr != 0);
+ }
+ }
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to save IO port value;
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbIoRead (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdIoRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to new IO port value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+VOID
+LibNbIoWrite (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdIoWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write IO space
+ *
+ *
+ *
+ * @param[in] Address IO Port address.
+ * @param[in] Width Access width
+ * @param[in] Mask AND Mask
+ * @param[in] Data OR Mask
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbIoRMW (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbIoRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbIoWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Value Pointer to save register value
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbCpuHTLinkPhyRead (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Data;
+ PCI_ADDR CpuPciAddress;
+ UINT8 LinkId;
+ LinkId = Link & 0xf;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
+ LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
+ do {
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
+ } while ((Data & BIT31) == 0);
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Value Pointer to new register value
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbCpuHTLinkPhyWrite (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Data;
+ PCI_ADDR CpuPciAddress;
+ UINT8 LinkId;
+ LinkId = Link & 0xf;
+ CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
+ LibNbPciWrite (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
+ LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | BIT30 | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
+ do {
+ LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
+ } while ((Data & BIT31) == 0);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write CPU HT link Phy register
+ *
+ *
+ *
+ * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
+ * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
+ * @param[in] Register Register address.
+ * @param[in] Mask AND Mask.
+ * @param[in] Data OR Mask.
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+LibNbCpuHTLinkPhyRMW (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbCpuHTLinkPhyRead (Node, Link, Register, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbCpuHTLinkPhyWrite (Node, Link, Register, &Value, NbConfigPtr);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable Clock Config space access.
+ * Enable access to Clock Config Space at 0:0:1 PCI address.
+ *
+ *
+ * @param[in] pConfig Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbEnableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, BIT0, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Disable Clock Config space access.
+ * Disable access to Clock Config Space at 0:0:1 PCI address.
+ *
+ *
+ * @param[in] pConfig Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbDisableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, 0x0 , pConfig);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if PCI Device Present
+ *
+ *
+ *
+ * @param[in] Device Device PCI address.
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ * @retval TRUE Device present.
+ * @retval FALSE Device not present.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+BOOLEAN
+LibNbIsDevicePresent (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 VendorId;
+ LibNbPciRead (Device.AddressValue, AccessWidth32, &VendorId, NbConfigPtr);
+ return (VendorId == 0xffffffff)?FALSE:TRUE;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if IOMMU enabled
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ * @retval TRUE IOMMU not enabled.
+ * @retval FALSE IOMMU not enabled.
+ */
+/*----------------------------------------------------------------------------------------*/
+BOOLEAN
+LibNbIsIommuEnabled (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR IommuAddress;
+ IommuAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
+ IommuAddress.Address.Function = 2;
+ if (LibNbIsDevicePresent (IommuAddress, NbConfigPtr)) {
+ UINT8 Value;
+ LibNbPciRead (IommuAddress.AddressValue | 0x44, AccessWidth8, &Value, NbConfigPtr);
+ if ((Value & BIT0) != 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Reverse bit in DWORD.
+ * Reverse bits in bitfield inside DWORD.
+ *
+ *
+ * @param[in] Data Value to reverse.
+ * @param[in] StartBit Start bit.
+ * @param[in] StopBit Stop bit.
+ * @retval Reversed Value.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+UINT32
+LibNbBitReverse (
+ IN UINT32 Data,
+ IN UINT8 StartBit,
+ IN UINT8 StopBit
+ )
+{
+
+ UINT32 Bitr;
+ UINT32 Bitl;
+ UINT32 Distance;
+
+ while (StartBit < StopBit) {
+ Bitr = Data & (1 << StartBit );
+ Bitl = Data & (1 << StopBit );
+ Distance = StopBit - StartBit;
+ Data = (Data & ((UINT32)~(Bitl | Bitr))) | (Bitr << Distance ) | (Bitl >> Distance);
+ StartBit++;
+ StopBit--;
+ }
+ return Data;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read CPU family
+ *
+ *
+ *
+ * @retval 0xXX00000 CPU family.
+ *
+ */
+UINT32
+LibNbGetCpuFamily (
+ VOID
+ )
+{
+ CPUID_DATA Cpuid;
+ CpuidRead (0x1, &Cpuid);
+ return Cpuid.EAX_Reg & 0xff00000;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Load Firmware block
+ *
+ *
+ *
+ * @param[in] Address Address to load firmware
+ * @param[in] Size Firmware block size
+ * @param[in] FirmwareBlockPtr Pointer to firmware block
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ */
+VOID
+LibNbLoadMcuFirmwareBlock (
+ IN UINT16 Address,
+ IN UINT16 Size,
+ IN UINT32 *FirmwareBlockPtr,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 i;
+ PCI_ADDR ClkPciAddress;
+ UINT32 Selector;
+
+ Selector = (Address >= 0x200)?0x0000000:0x10000;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbEnableClkConfig (NbConfigPtr);
+ for (i = 0; i < Size; i++) {
+ LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address + (i * 4)), AccessWidth32, &FirmwareBlockPtr[i], NbConfigPtr);
+ }
+ LibNbDisableClkConfig (NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read SMU firmware ram
+ *
+ *
+ *
+ * @param[in] Address Address to read
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ *
+ */
+UINT32
+LibNbReadMcuRam (
+ IN UINT16 Address,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ PCI_ADDR ClkPciAddress;
+ UINT32 Selector;
+
+ Selector = (Address >= 0x200) ? 0x0000000 : 0x10000;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbEnableClkConfig (NbConfigPtr);
+ LibNbPciIndexRead (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address), AccessWidth32, &Value, NbConfigPtr);
+ LibNbDisableClkConfig (NbConfigPtr);
+ return Value;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * MCU Control
+ *
+ *
+ *
+ * @param[in] Operation Set/Reset MCU controller
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+VOID
+LibNbMcuControl (
+ IN NB_MCU_MODE Operation,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR ClkPciAddress;
+ UINT32 Value;
+
+ Value = (Operation == AssertReset)?0x00000ee1:0x00000ee2;
+ ClkPciAddress = NbConfigPtr->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "LibNbMcuControl Operation [0x%x]\n", Operation));
+ LibNbEnableClkConfig (NbConfigPtr);
+ LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, 0x00030000, AccessWidth32, &Value, NbConfigPtr);
+ LibNbDisableClkConfig (NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read/Modify/Write memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Mask AND Mask
+ * @param[in] Data OR Mask
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemRMW (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ LibNbMemRead (Address, Width, &Value, NbConfigPtr);
+ Value = (Value & Mask) | Data;
+ LibNbMemWrite (Address, Width, &Value, NbConfigPtr);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Read memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to memory to store value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemRead (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdMemRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Write memory space
+ *
+ *
+ *
+ * @param[in] Address Memory address.
+ * @param[in] Width Access width
+ * @param[in] Value Pointer to memory to get value
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbMemWrite (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ LibAmdMemWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Bridge
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Bridge Address of PCI to PCI bridge to scan.
+ */
+
+SCAN_STATUS
+LibNbScanPciBridgeBuses (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Bridge
+ )
+{
+ SCAN_STATUS Status;
+ UINT8 CurrentBus;
+ UINT8 MinBus;
+ UINT8 MaxBus;
+ PCI_ADDR Device;
+
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanBus == NULL) {
+ return SCAN_FINISHED;
+ }
+ LibNbPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &MinBus, This->pConfig);
+ LibNbPciRead (Bridge.AddressValue | 0x1A, AccessWidth8, &MaxBus, This->pConfig);
+ if (MinBus == 0 || MaxBus == 0) {
+ return SCAN_FINISHED;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan bridge %d:%d:%d \n", Bridge.Address.Bus, Bridge.Address.Device, Bridge.Address.Function));
+ for (CurrentBus = MinBus; CurrentBus <= MaxBus; CurrentBus++) {
+ Device.AddressValue = MAKE_SBDFO (0, CurrentBus, 0, 0, 0);
+ Status = This->ScanBus (This, Device);
+ }
+ return SCAN_FINISHED;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Bus
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Device Pci address device to start bus scan from
+ */
+/*----------------------------------------------------------------------------------------*/
+SCAN_STATUS
+LibNbScanPciBus (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ )
+{
+ SCAN_STATUS Status;
+ UINT32 CurrentDevice;
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanDevice == NULL) {
+ return SCAN_FINISHED;
+ }
+ for (CurrentDevice = Device.Address.Device; CurrentDevice <= 0x1f; CurrentDevice++) {
+ Device.Address.Device = CurrentDevice;
+ if (LibNbIsDevicePresent (Device, This->pConfig)) {
+ Status = This->ScanDevice (This, Device);
+ if (Status == SCAN_STOP_BUS_ENUMERATION) {
+ return Status;
+ }
+
+ }
+ }
+ return SCAN_FINISHED;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan Pci Device
+ *
+ *
+ *
+ * @param[in] This Pointer to PCI topology scan protocol
+ * @param[in] Device Pci address device to scan
+ */
+/*----------------------------------------------------------------------------------------*/
+
+SCAN_STATUS
+LibNbScanPciDevice (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ )
+{
+ SCAN_STATUS Status;
+ UINT8 Header;
+ UINT32 CurrentFunction;
+ UINT32 MaxFunction;
+ CIMX_ASSERT (This != NULL);
+ if (This->ScanFunction == NULL) {
+ return SCAN_FINISHED;
+ }
+ LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Header, This->pConfig);
+ MaxFunction = (Header & 0x80)?7:0;
+ for (CurrentFunction = Device.Address.Function; CurrentFunction <= MaxFunction; CurrentFunction++) {
+ Device.Address.Function = CurrentFunction;
+ if (LibNbIsDevicePresent (Device, This->pConfig)) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan function %d:%d:%d \n", Device.Address.Bus, Device.Address.Device, Device.Address.Function));
+ Status = This->ScanFunction (This, Device);
+ if (Status == SCAN_STOP_DEVICE_ENUMERATION || Status == SCAN_STOP_BUS_ENUMERATION) {
+ return Status;
+ }
+ }
+ }
+ return SCAN_FINISHED;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set default Indexes
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration block pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+
+VOID
+LibNbSetDefaultIndexes (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR PciAddress;
+ PORT PortId;
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, SB_CORE, NbConfigPtr);
+ PciAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PciAddress.Address.Device = PortId;
+ LibNbPciRMW (PciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
+ }
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.h b/src/vendorcode/amd/cimx/rd890/nbLib.h
new file mode 100644
index 0000000000..af10946b9a
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbLib.h
@@ -0,0 +1,352 @@
+/**
+ * @file
+ *
+ * CNB Library function
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBLIB_H_
+#define _NBLIB_H_
+
+#pragma pack(push, 1)
+
+/// NB_MCU_MODE
+typedef enum {
+ AssertReset, ///< Assert reset
+ DeAssertReset ///< Deassert reset
+} NB_MCU_MODE;
+
+/// SMU Firmware revision
+typedef struct {
+ UINT16 MajorRev; ///< Major revision
+ UINT16 MinorRev; ///< Minor revision
+} SMU_FIRMWARE_REV;
+
+/// Firmware block
+typedef struct {
+ UINT16 Address; ///< Block Address
+ UINT16 Length; ///< Block length in DWORD
+ UINT32 *Data; ///< Pointer to data array
+} SMU_FIRMWARE_BLOCK;
+
+/// Firmware header
+typedef struct {
+ SMU_FIRMWARE_REV Revision; ///< Revision info
+ UINT16 NumberOfBlock; ///< Number of blocks
+ SMU_FIRMWARE_BLOCK *BlockArray; ///< Pointer to block definition array
+} SMU_FIRMWARE_HEADER;
+
+
+NB_INFO
+LibNbGetRevisionInfo (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+AGESA_STATUS
+LibNbCallBack (
+ IN UINT32 CallBackId,
+ IN OUT UINTN Data,
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciWrite (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciRead (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciRMW (
+ IN UINT32 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciIndexRead (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciIndexWrite (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbPciIndexRMW (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbIndirectTableInit (
+ IN UINT32 Address,
+ IN UINT32 Index,
+ IN INDIRECT_REG_ENTRY *pTable,
+ IN UINTN Length,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+UINT8
+LibNbFindPciCapability (
+ IN UINT32 Address,
+ IN UINT8 CapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbIoRMW (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbCpuHTLinkPhyRead (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ OUT UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbCpuHTLinkPhyWrite (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+);
+
+VOID
+LibNbCpuHTLinkPhyRMW (
+ IN UINT8 Node,
+ IN UINT8 Link,
+ IN UINT16 Register,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+);
+
+VOID
+LibNbEnableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+LibNbDisableClkConfig (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+BOOLEAN
+LibNbIsDevicePresent (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+UINT32
+LibNbBitReverse (
+ IN UINT32 Data,
+ IN UINT8 StartBit,
+ IN UINT8 StopBit
+ );
+
+UINT32
+LibNbGetCpuFamily (
+ VOID
+ );
+
+VOID
+LibNbIoWrite (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbIoRead (
+ IN UINT16 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbLoadMcuFirmwareBlock (
+ IN UINT16 Address,
+ IN UINT16 Size,
+ IN UINT32 *FirmwareBlockPtr,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+UINT32
+LibNbReadMcuRam (
+ IN UINT16 Address,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbMcuControl (
+ IN NB_MCU_MODE Operation,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+
+AGESA_STATUS
+LibSystemApiCall (
+ IN SYSTEM_API SystemApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+LibNbApiCall (
+ IN NB_API NbApi,
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+VOID
+LibNbMemRMW (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN UINT32 Mask,
+ IN UINT32 Data,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbMemRead (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ IN VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+LibNbMemWrite (
+ IN UINT64 Address,
+ IN ACCESS_WIDTH Width,
+ OUT VOID *Value,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+struct _PCI_SCAN_PROTOCOL;
+typedef struct _PCI_SCAN_PROTOCOL PCI_SCAN_PROTOCOL;
+typedef UINT32 SCAN_STATUS;
+
+typedef SCAN_STATUS (*SCAN_ENTRY) (PCI_SCAN_PROTOCOL *This, PCI_ADDR Device);
+
+#define SCAN_FINISHED 0x0
+#define SCAN_STOP_DEVICE_ENUMERATION 0x1
+#define SCAN_STOP_BUS_ENUMERATION 0x2
+
+
+/// PCI topology scan protocol
+struct _PCI_SCAN_PROTOCOL {
+ SCAN_ENTRY ScanBus; ///< Pointer to function to scan device on PCI bus.
+ SCAN_ENTRY ScanDevice; ///< Pointer to function to scan function on PCI device.
+ SCAN_ENTRY ScanFunction; ///< Pointer to scan PCI function.
+ AMD_NB_CONFIG *pConfig; ///< NB configuration info.
+};
+
+SCAN_STATUS
+LibNbScanPciBus (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ );
+
+SCAN_STATUS
+LibNbScanPciDevice (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Device
+ );
+
+SCAN_STATUS
+LibNbScanPciBridgeBuses (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Bridge
+ );
+
+VOID
+LibNbSetDefaultIndexes (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+UINT16
+LibNbFindPcieExtendedCapability (
+ IN UINT32 Address,
+ IN UINT16 ExtendedCapabilityId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+BOOLEAN
+LibNbIsIommuEnabled (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+#pragma pack(pop)
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c
new file mode 100644
index 0000000000..8394835d06
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c
@@ -0,0 +1,121 @@
+/**
+ * @file
+ *
+ * NB RAS
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+extern UINT16 NbInitMaskedMemoryLength;
+
+typedef VOID (*MASKED_MEMORY_INIT_PROC) (IN UINT32 PciAddress, IN UINT16 AlinkAddress);
+
+
+AGESA_STATUS
+AmdMaskedMemoryInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (NbMaskedMemoryInit, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Mask Memory
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+NbMaskedMemoryInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT8 ExecutionBuffer[300];
+ SCRATCH_1 Scratch;
+ UINT16 AlinkPort;
+
+ Status = AGESA_SUCCESS;
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ if (Scratch.MaskMemoryInit == OFF) {
+ return Status;
+ }
+ Scratch.MaskMemoryInit = OFF;
+ LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ CIMX_ASSERT (NbInitMaskedMemoryLength < 300);
+ LibAmdMemCopy ((VOID*)ExecutionBuffer, (VOID*) (UINTN)NbInitMaskedMemory, NbInitMaskedMemoryLength, (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig);
+ (*((MASKED_MEMORY_INIT_PROC)(UINTN)ExecutionBuffer))(pConfig->NbPciAddress.AddressValue, AlinkPort);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG87, AccessS3SaveWidth32, 0x0, 0xffffffff, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG88, AccessS3SaveWidth32, 0x0, 0xffffffff, pConfig);
+ return Status;
+}
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h
new file mode 100644
index 0000000000..c364fe2d75
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h
@@ -0,0 +1,63 @@
+/**
+ * @file
+ *
+ * NB RAS
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBMASKEDMEMORYINIT_H_
+#define _NBMASKEDMEMORYINIT_H_
+
+AGESA_STATUS
+AmdMaskedMemoryInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+NbMaskedMemoryInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+NbInitMaskedMemory (
+ IN UINT32 PciAddress,
+ IN UINT16 AlinkAddress
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S
new file mode 100644
index 0000000000..3c148aa85e
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/******************************************************************************
+* CIMX Northbridge
+*
+* Contains CIMX 32 bit library code
+*
+* Description: nbMaskedMemoryInit32.S - nb Masked Memory Init 32bit ASM code
+*
+******************************************************************************/
+
+.altmacro
+
+#include <cpu/x86/post_code.h>
+
+ .section ".text"
+ .code32
+ .globl NbInitMaskedMemory, NbInitMaskedMemoryLength
+
+/*
+* PciAddress = 8(%ebp)
+* AlinkAddress = 12(%ebp)
+*/
+.type NbInitMaskedMemory, @function
+
+NbInitMaskedMemory:
+ push %ebp
+ movl %esp, %ebp
+ pusha
+ cmp $0, 12(%ebp)
+ jz 0f
+ mov 12(%ebp), %dx
+ mov $0x80000004, %eax
+ out %eax, %dx
+ add $4, %dx
+ in %dx, %eax
+ btr $2, %eax
+ out %eax, %dx
+ 0:
+ mov 8(%ebp), %eax
+ shr $4, %eax
+ or $0x80000060, %eax
+ mov %eax, %ebx
+ mov $0x0cf8, %dx
+ out %eax, %dx
+ mov $0x0cfc, %dx
+ mov $(0x80 | 0x1B), %eax # NB_MISC_REG1B
+ out %eax, %dx
+ mov %ebx, %eax
+ mov $0x64, %al
+ mov $0x0cf8, %dx
+ out %eax, %dx
+ mov $0x0cfc, %dx
+ in %dx, %eax
+ and $(~(0x01ff << 21)), %eax
+ bts $15, %eax
+ xor %ecx, %ecx
+ out %eax, %dx
+StartInit:
+ and $(~(0xff << 22)), %eax
+ shl $22, %ecx
+ or %ecx, %eax
+ shr $22, %ecx
+ out %eax, %dx
+ bts $21, %eax
+ out %eax, %dx
+ btr $21, %eax
+ out %eax, %dx
+ cmp $0x0ff, %cl
+ je DoneInit
+ inc %ecx
+ jmp StartInit
+DoneInit:
+ btr $15, %eax
+ out %eax, %dx
+ cmp $0, 12(%ebp)
+ jz 1f
+ mov 12(%ebp), %dx
+ mov $0x80000004, %eax
+ out %eax, %dx
+ add $4, %dx
+ in %dx, %eax
+ bts $2, %eax
+ out %eax, %dx
+ 1:
+ popa
+ movl %ebp, %esp
+ pop %ebp
+ ret
+NbInitMaskedMemoryLength = ( . - NbInitMaskedMemory)
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbMiscInit.c b/src/vendorcode/amd/cimx/rd890/nbMiscInit.c
new file mode 100644
index 0000000000..ded6934cec
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbMiscInit.c
@@ -0,0 +1,123 @@
+/**
+ * @file
+ *
+ * NB Initialization.
+ *
+ * Init IOAPIC/IOMMU/Misc NB features.
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for all NB.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdMiscInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (MiscInitializer, ConfigPtr);
+ return Status;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB structure initializer.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+MiscInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AMD_NB_CONFIG_BLOCK *ConfigPtr;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMiscInitializer Enter\n"));
+ ConfigPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr);
+ if (ConfigPtr == NULL) {
+ return AGESA_FATAL;
+ }
+ if (ConfigPtr->PlatformType == DetectPlatform) {
+ NB_INFO NbInfo;
+ NbInfo = LibNbGetRevisionInfo (NbConfigPtr);
+ if (NbInfo.Type != NB_UNKNOWN && NbInfo.Type >= NB_SR5690 && NbInfo.Type <= NB_SR5650) {
+ ConfigPtr->PlatformType = ServerPlatform;
+ } else {
+ ConfigPtr->PlatformType = DesktopPlatform;
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMiscInitializer Exit\n"));
+ return AGESA_SUCCESS;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbMiscInit.h b/src/vendorcode/amd/cimx/rd890/nbMiscInit.h
new file mode 100644
index 0000000000..2537e787f2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbMiscInit.h
@@ -0,0 +1,57 @@
+/**
+ * @file
+ *
+ * NB definitions
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBMISCINIT_H_
+#define _NBMISCINIT_H_
+
+AGESA_STATUS
+AmdMiscInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+AGESA_STATUS
+MiscInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c b/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c
new file mode 100644
index 0000000000..175e3b369e
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c
@@ -0,0 +1,70 @@
+/**
+ * @file
+ *
+ * Function dispatcher.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+#define Int32FromChar(a,b,c,d) ((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24)
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+VOLATILE AMD_MODULE_HEADER mNbModuleID = {
+// 'DOM$',
+ Int32FromChar ('D', 'O', 'M', '$'),
+ CIMX_NB_ID,
+ CIMX_NB_REVISION,
+ AmdNbDispatcher,
+ NULL
+};
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcie.h b/src/vendorcode/amd/cimx/rd890/nbPcie.h
new file mode 100644
index 0000000000..50120582d9
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcie.h
@@ -0,0 +1,352 @@
+/**
+ * @file
+ *
+ * PCIE definitions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIE_H_
+#define _NBPCIE_H_
+
+#pragma pack(push, 1)
+
+/// PCIe Link Aspm mode
+typedef enum {
+ PcieLinkAspmDisabled, ///< Disabled
+ PcieLinkAspmL0s, ///< L0s only
+ PcieLinkAspmL1, ///< L1 only
+ PcieLinkAspmL0sAndL1, ///< L0s and L1
+ PcieLinkAspmL0sDownstreamOnly, ///< L0s Donnstream Port Only
+ PcieLinkAspmL0sDownstreamOnlyAndL1 ///< L0s Donnstream Port and L1
+} PCIE_LINK_ASPM;
+
+/// PCIe device type
+typedef enum {
+ PcieDeviceEndPoint, ///< Endpoint
+ PcieDeviceLegacyEndPoint, ///< Legacy endpoint
+ PcieDeviceRootComplex = 4, ///< Root complex
+ PcieDeviceUpstreamPort, ///< Upstream port
+ PcieDeviceDownstreamPort, ///< Downstream Port
+ PcieDevicePcieToPcix, ///< PCIe to PCI/PCIx bridge
+ PcieDevicePcixToPcie, ///< PCI/PCIx to PCIe bridge
+ PcieNotPcieDevice = 0xff ///< unknown device
+} PCIE_DEVICE_TYPE;
+
+/// PCIe Link Mode
+typedef enum {
+ PcieLinkModeGen2, ///< Gen 2
+ PcieLinkModeGen1, ///< Gen 1
+ PcieLinkModeGen2SoftwareInitiated, ///< Gen 2 software
+ PcieLinkModeGen2AdvertizeOnly ///< Gen 2 advertise only
+} PCIE_LINK_MODE;
+
+/// PCIE Link Status
+typedef enum {
+ PcieLinkStatusNotConnected, ///< not connected
+ PcieLinkStatusConnected, ///< connected
+ PcieLinkStatusInCompliance, ///< compliant
+ PcieLinkStatusTrainingInProgress, ///< training in progress
+ PcieLinkStatusVcoNegotiationInProgress, ///< Vco negotiation in progress
+} PCIE_LINK_STATUS;
+
+/// PCIE Link Width Information
+typedef enum {
+ PcieLinkMaxWidth, ///< max width
+ PcieLinkCurrentWidth, ///< current width
+} PCIE_LINK_WIDTH_INFO;
+
+/// PCIE Link Training
+typedef enum {
+ PcieLinkTrainingRelease, ///< training release
+ PcieLinkTrainingHold ///< training hold
+} PCIE_LINK_TRAINING;
+
+/// PCIE Strap Mode
+typedef enum {
+ PcieCoreStrapConfigStart, ///< start
+ PcieCoreStrapConfigStop ///< stop
+} PCIE_STRAP_MODE;
+
+/// PCIE Link Width
+typedef enum {
+ PcieLinkWidth_x0 = 0, ///< x0
+ PcieLinkWidth_x1 = 1, ///< x1
+ PcieLinkWidth_x2, ///< x2
+ PcieLinkWidth_x4, ///< x4
+ PcieLinkWidth_x8, ///< x8
+ PcieLinkWidth_x12, ///< x12
+ PcieLinkWidth_x16 ///< x16
+} PCIE_LINK_WIDTH;
+
+/// PCIe Transmitter deemphasis advertise
+typedef enum {
+ PcieTxDeemphasis6dB = 0, ///< -6dB
+ PcieTxDeemphasis3p5dB, ///< -3.5dB
+} PCIE_LINK_DEEMPASIS;
+
+/// PCIe Transmitter deemphasis advertise
+typedef enum {
+ PcieTxDriveStrangth26mA = 0, ///< 26mA
+ PcieTxDriveStrangth20mA, ///< 20mA
+ PcieTxDriveStrangth22mA, ///< 22mA
+ PcieTxDriveStrangth24mA, ///< 24mA
+} PCIE_LINK_DRIVE_STRANGTH;
+
+/// PCIe Channel type
+typedef enum {
+ PcieShortChannel = 1, ///< Short Channel
+ PcieMediumChannel, ///< Medium Channel
+ PcieLongChannel, ///< Long Channel
+} NB_PCIE_CHANNEL_TYPE;
+
+/// PCI Core Reset
+typedef enum {
+ PcieCoreResetAllDeassert = 1, ///< deassert
+ PcieCoreResetAllAssert, ///< assert
+ PcieCoreResetAllCheck, ///< check
+} PCI_CORE_RESET;
+
+/// Misc PCIE Core Setting
+typedef struct {
+ UINT32 CoreDisabled :1; ///< Core not present or disabled
+ UINT32 PowerOffPll :1; ///< Enable power off PLL if group of lanes controlled by PLL unused
+ UINT32 PowerOffPllInL1 :1; ///< Enable Power off PLL in L1
+ UINT32 LclkClockGating :1; ///< Enable LCLK clock gating
+ UINT32 TxClockGating :1; ///< Enable TX clock gating
+ UINT32 PowerOffUnusedLanes :1; ///< Enable Power off pads for unused Lanes
+ UINT32 CplBufferAllocation :1; ///< Enable special/optimized CPL buffer allocation
+ UINT32 PerformanceMode :1; ///< Enable support PCIe Reference Clock overclocking. In addition to rump-up PCIe reference clock
+ UINT32 TxDriveStrength :2; /**< TX Drive strength (Only applicable if PCIE_CORE_SETTING::ChannelType == 0).
+ * @li @b 0 - 26mA
+ * @li @b 1 - 20mA
+ * @li @b 2 - 22mA
+ * @li @b 3 - 24mA
+ */
+ UINT32 SkipConfiguration :1; ///< Special case to skip core configuration (configured outside of CIMx)
+ UINT32 TxHalfSwingMode :1; ///< Half Swing Mode for PCIe Transmitters (Only applicable if PCIE_CORE_SETTING::ChannelType == 0).
+ UINT32 ChannelType :3; /**< Group PCIe PHY setting for channel with specific trace length
+ * @li @b 0 - Use individual parameters to configure PCIe PHY (see PCIE_CORE_SETTING::TxHalfSwingMode,
+ PCIE_CORE_SETTING::TxDriveStrength, PCIE_EXT_PORT_CONFIG::PortDeemphasis).
+ * @li @b 1 - Short Channel.
+ * @li @b 2 - Midium Channel.
+ * @li @b 3 - Long Channel.
+ */
+ UINT32 DetectPowerOffPllInL1 :1; ///< Enable detection if endpoint L1 acceptable latency allow Enable Power off PLL in L1.
+ UINT32 TxClockOff :1; ///< Disable TX clock if possible
+ UINT32 LclkClockOff :1; ///< Disable LCLK clock if possible
+ UINT32 RefClockInput :1; ///< Use dedicated ref. clock input (only applicable GPP1 and GPP2 cores). By default SB ref clock is used.
+ UINT32 Reserved :2; ///<
+ UINT32 CoreDisableStatus :1; /**< Output status of core disable/enable
+ * @li @b 0 = Core not disabled
+ * @li @b 1 = Core Disabled
+ */
+} PCIE_CORE_SETTING;
+
+/// Misc Configuration
+typedef struct {
+ UINT32 DisableHideUnusedPorts :1; ///< Hide unused ports if no EP was detected and port non hotpluggable
+ UINT32 Peer2Peer :1; ///< Enable Peer to Peer.
+ UINT32 DisableGfxWorkaround :1; ///< disable RV370/RV380 workaround
+ UINT32 NbSbVc1 :1; ///< Enable VC1 for NB SB Audio traffic
+} PCIE_MISC_CONFIG;
+
+/// Extended PCIE Port Configuration
+typedef struct {
+ UINT32 PortL1ImmediateACK :1; ///< Validation feature
+ UINT32 PortLinkWidth :3; /**< Port Link width
+ * @li @b 0 - Auto. Default max link width.
+ * @li @b 1 - x1
+ * @li @b 2 - x2
+ * @li @b 3 - x4
+ * @li @b 4 - x8
+ * @li @b 6 - x16
+ */
+ UINT32 PortMapping :4; /**< Device number mapping info
+ * @li @b 0 - Default mapping
+ * @li @b n - PCI device number for port (Valid device numbers are 2/3/4/5/6/7/9/10/11/12/13).
+ */
+ UINT32 PortHotplugDevMap :2; /**< PCA9539 device map.
+ *Only valid if PortHotplug = 1
+ */
+ UINT32 PortHotplugByteMap :1; /**< PCA9539 channel map.
+ *Only valid if PortHotplug = 1
+ */
+ UINT32 PortPowerLimit :8; ///< Slot power limit in W
+ UINT32 Reserved :2; ///< Reserved
+ UINT32 PortDeemphasis :2; /**< Port deempasis adverise (Only applicable if PCIE_CORE_SETTING::ChannelType == 0).
+ * @li @b 0 - 6dB
+ * @li @b 1 - 3.5dB
+ */
+
+} PCIE_EXT_PORT_CONFIG;
+
+/// PCIE Port Configuration
+typedef struct {
+ UINT32 PortPresent :1; /**< Port connection
+ * @li @b 0 - Port has no slot or EP connected. Link not needs to be trained.
+ * @li @b 1 - Has slot or EP connected. Link needs to be trained.
+ */
+ UINT32 PortDetected :1; /**< Scratch bit to record status of training
+ * @li @b 0 - EP not detected
+ * @li @b 1 - EP detected
+ */
+ UINT32 PortCompliance :1; /**< Link compliance mode
+ * @li @b 0 - Link in operational mode
+ * @li @b 1 - Force link into compliance mode
+ */
+ UINT32 PortLinkMode :2; /**< Link speed mode configuration
+ * @li @b 0 - GEN2 Autonomous (GEN2 capability advertized and and immediate link speed change initiated).
+ * @li @b 1 - GEN1
+ * @li @b 2 - GEN2 Software Initiated (Port trained to Gen1 thereafter if EP report GEN2 capability port reconfigured to GEN2)
+ * @li @b 3 - GEN2 advertize only (RC only advertize GEN2 capability and not initiate transition to GEN2 speed)
+ */
+ UINT32 PortHotplug :2; /**< Port Hotplug configuration
+ * @li @b 0 - Hotplug Disabled
+ * @li @b 1 - Server Hotplug Enabled
+ * @li @b 2 - Reserved
+ * @li @b 3 - Reserved
+ */
+ UINT32 PortAspm :3; /**< Port ASPM support
+ * @li @b 0 - Disabled
+ * @li @b 1 - L0s enable
+ * @li @b 2 - L1 enable
+ * @li @b 3 - L0s + L1 enable
+ * @li @b 4 - L0s Downstream Only
+ * @li @b 5 - L0s Downstream Only + L1
+ * @li <b>4..7</b> - Reserved
+ */
+ UINT32 PortReversed :1; /**< Port lanes reversed
+ * @li @b 0 - Lanes non reversed
+ * @li @b 1 - Lanes reversed
+ */
+ UINT32 ForcePortDisable :1; /**< Port Disable after PCIE training
+ * @li @b 0 - Do not force port disable
+ * @li @b 1 - Force port disable
+ */
+ UINT32 PortAlwaysVisible :1; /**< Port always visible
+ * @li @b 1 - Port always visible
+ */
+} PCIE_PORT_CONFIG;
+
+/// PCIE default configuration parameters structure
+typedef struct {
+ PCIE_MISC_CONFIG PcieConfiguration; ///< PCIE configuration
+ PCIE_CORE_SETTING CoreSetting[5]; ///< Core Setting
+ UINT16 DeviceInitMaskS1; ///< Bit mask of ports id to be initialized at stage 1
+ UINT16 DeviceInitMaskS2; ///< Bit mask of ports id to be initialized at stage 2
+ UINT16 ResetToTrainingDelay; ///< Delay (in 1ms) after reset deassert before training started
+ UINT16 TrainingToLinkTestDelay; ///< Delay (in 1ms) after training started but before pooling link state
+ UINT16 ReceiverDetectionPooling; ///< Total amount time (in 1ms of pooling for passing receiver detection stage
+} PCIE_DEFAULT_CONFIG;
+
+/// Link Info
+typedef struct {
+ UINT8 LinkWidth; ///< width
+ UINT8 MaxLinkWidth; ///< max width
+ UINT8 Line0Offset; ///< line 0 offset
+} LINK_INFO;
+
+/// Port Static Info
+typedef struct {
+ UINT8 TrainingAddress; ///< training address
+ UINT8 ReversalAddress; ///< reversal address
+ UINT8 DeemphasisAddress; ///< de-emphasis address
+ UINT8 MappingAddress; ///< mapping address
+ UINT8 HotplugAddress; ///< Hotplug address
+} PORT_STATIC_INFO;
+
+/// Core Info
+typedef struct {
+ UINT32 CoreSelector; ///< core selector
+ UINT16 PortIdBitMap; ///< port Id
+ UINT8 TrainingRegister; ///< training
+ UINT8 DeemphasisRegister; ///< de-emphasis
+ UINT8 StrapRegister; ///< strap
+ UINT8 StrapAddress; ///< strap address
+ UINT8 HotplugRegister; ///< Hotplug descriptor register
+ UINT8 TxDriveStrengthRegister; ///< Tx drive strength register
+ UINT8 TxDriveStrengthOffset; ///< Tx drive strength bit offeset
+ UINT8 TxHalfSwingRegister; ///< Tx half swing register
+ UINT8 TxHalfSwingOffset; ///< Tx half swing bit offset
+ UINT8 TxHalfSwingDeepmhasisRegister; ///< Tx half swing deephasis register
+ UINT8 TxHalfSwingDeepmhasisOffset; ///< Tx half swing deephasis register
+ UINT8 TxOffOffset; ///< Tx shutdown enable offset
+ UINT8 LclkOffOffset; ///< Lclk shutdown enable offset
+ UINT8 LclkPermOffOffset; ///< Lclk Perm shutdown enable offset
+} CORE_INFO;
+
+/// Port Information
+typedef struct {
+ UINT8 MaxLinkWidth; ///< max link width
+ UINT8 Line0Offset; ///< offset
+ UINT8 SlaveCplBuffers; ///< Alternative to default CPL buffer count
+} PORT_INFO;
+
+/// GPP Configuration Info
+typedef struct {
+ PORT_INFO *PortInfoPtr; ///< port information
+ UINT32 PortIdMap; ///< port id map
+} GPP_CFG_INFO;
+
+
+#define GPP1_CORE 0x40000
+#define GPP2_CORE 0x60000
+#define GPP3a_CORE 0x70000
+#define GPP3b_CORE 0x30000
+#define SB_CORE 0x50000
+
+#define GPP_CONFIG_GPP420000 0x01
+#define GPP_CONFIG_GPP411000 0x02
+#define GPP_CONFIG_GPP222000 0x03
+#define GPP_CONFIG_GPP221100 0x04
+#define GPP_CONFIG_GPP211110 0x05
+#define GPP_CONFIG_GPP111111 0x06
+
+#define GFX_CONFIG_A 0x01
+#define GFX_CONFIG_B 0x02
+
+#define GFX_CONFIG_AAAA (GFX_CONFIG_A | (GFX_CONFIG_A << 8) | (GFX_CONFIG_A << 16) | (GFX_CONFIG_A << 24))
+#define GFX_CONFIG_AABB (GFX_CONFIG_A | (GFX_CONFIG_A << 8) | (GFX_CONFIG_B << 16) | (GFX_CONFIG_B << 24))
+
+#define PCIE_CAP_ID 0x10
+
+
+#pragma pack(pop)
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c
new file mode 100644
index 0000000000..38bc41fb1a
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c
@@ -0,0 +1,507 @@
+/**
+ * @file
+ *
+ * ASPM support.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+VOID
+PcieAspmSetOnRc (
+ IN PCI_ADDR Device,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+SCAN_STATUS
+PcieSetDeviceAspm (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Function
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Port ASPM.
+ * Enable ASPM states on RC and EP. Only states supported by both RC and EP
+ * will be enabled.
+ *
+ *
+ * @param[in] PortId Pcie Port ID
+ * @param[in] AsmpState ASPM states to enable.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+PcieAsmpEnableOnPort (
+ IN PORT PortId,
+ IN PCIE_LINK_ASPM AsmpState,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR Port;
+ UINT8 Lx;
+ PCI_ADDR NbPciAddress;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "PcieAsmpEnableOnPort Enter PortId [%d]\n", PortId));
+ NbPciAddress.AddressValue = NB_SBDFO;
+ switch (AsmpState) {
+ case PcieLinkAspmDisabled:
+ return ;
+ case PcieLinkAspmL0s:
+ Lx = ASPM_UPSTREAM_L0s | ASPM_DOWNSTREAM_L0s;
+ break;
+ case PcieLinkAspmL1:
+ Lx = ASPM_L1;
+ break;
+ case PcieLinkAspmL0sAndL1:
+ Lx = ASPM_UPSTREAM_L0s | ASPM_DOWNSTREAM_L0s | ASPM_L1;
+ break;
+ case PcieLinkAspmL0sDownstreamOnly:
+ Lx = ASPM_DOWNSTREAM_L0s;
+ break;
+ case PcieLinkAspmL0sDownstreamOnlyAndL1:
+ Lx = ASPM_DOWNSTREAM_L0s | ASPM_L1;
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ return ;
+ }
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+//NB-SB link
+ if (PortId == 8 && NbPciAddress.AddressValue == 0) {
+ if (PcieSbInitAspm ((Lx & ASPM_L1) | ((Lx & ASPM_UPSTREAM_L0s)?ASPM_L0s:0), pConfig) == AGESA_SUCCESS) {
+ PcieAspmEnableOnFunction (Port, (Lx & ASPM_L1) | ((Lx & ASPM_DOWNSTREAM_L0s)?ASPM_L0s:0), pConfig);
+ }
+ return ;
+ }
+ PcieAspmSetOnRc (Port, Lx, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "PcieAsmpEnableOnPort Exit. Lx[0x%x]\n", Lx));
+ return ;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable Common Clock on PCIe Link
+ *
+ *
+ *
+ * @param[in] Downstream Downstream PCIe port PCI address
+ * @param[in] Upstream Upstream PCIe port PCI address
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+VOID
+PcieAspmEnableCommonClock (
+ IN PCI_ADDR Downstream,
+ IN PCI_ADDR Upstream,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT16 DownstreamCommonClockCap;
+ UINT16 UpstreamCommonClockCap;
+ UINT16 Value;
+ UINT8 DownstreamPcieCapPtr;
+ UINT8 UpstreamPcieCapPtr;
+ DownstreamPcieCapPtr = LibNbFindPciCapability (Downstream.AddressValue, PCIE_CAP_ID, pConfig);
+ UpstreamPcieCapPtr = LibNbFindPciCapability (Upstream.AddressValue, PCIE_CAP_ID, pConfig);
+ if (DownstreamPcieCapPtr == 0 || UpstreamPcieCapPtr == 0) {
+ return ;
+ }
+ LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessWidth16, &DownstreamCommonClockCap, pConfig);
+ if ((DownstreamCommonClockCap & BIT6) != 0) {
+ //Aready enabled
+ return ;
+ }
+ LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x12) , AccessWidth16, &DownstreamCommonClockCap, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream Common Clock Capability %d:%d:%d - %x\n", Downstream.Address.Bus, Downstream.Address.Device, Downstream.Address.Function, DownstreamCommonClockCap));
+ LibNbPciRead (Upstream.AddressValue | (UpstreamPcieCapPtr + 0x12) , AccessWidth16, &UpstreamCommonClockCap, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream Common Clock Capability %d:%d:%d - %x\n", Upstream.Address.Bus, Upstream.Address.Device, Upstream.Address.Function, UpstreamCommonClockCap));
+ if ((DownstreamCommonClockCap & UpstreamCommonClockCap & BIT12) != 0) {
+ //Enable common clock
+ PcieAspmCommonClockOnFunction (Downstream, pConfig);
+ PcieAspmCommonClockOnDevice (Upstream, pConfig);
+// LibNbPciRMW (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT6, pConfig);
+// LibNbPciRMW (Upstream.AddressValue | (UpstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT6, pConfig);
+ //Reatrain link
+ LibNbPciRMW (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT5, pConfig);
+ do {
+ LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x12) , AccessWidth16, (UINT16*)&Value, pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE);
+ } while ((Value & BIT11) != 0);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set "Common Clock" enable on function
+ *
+ *
+ *
+ * @param[in] Device PCI address of function.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmCommonClockOnDevice (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 Value;
+ UINT8 MaxFunc;
+ UINT8 CurrentFunc;
+ LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Value, pConfig);
+ MaxFunc = (Value & BIT7)?7:0;
+ for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) {
+ Device.Address.Function = CurrentFunc;
+ if (LibNbIsDevicePresent (Device, pConfig)) {
+ PcieAspmCommonClockOnFunction (Device, pConfig);
+ }
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set "Common Clock" enable on function
+ *
+ *
+ *
+ * @param[in] Function PCI address of function.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmCommonClockOnFunction (
+ IN PCI_ADDR Function,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 PcieCapPtr;
+ PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, pConfig);
+ if (PcieCapPtr != 0) {
+ LibNbPciRMW (Function.AddressValue | (PcieCapPtr + 0x10) , AccessS3SaveWidth8, (UINT32)~(BIT6), BIT6, pConfig);
+ }
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable ASPM on PCIe Link
+ *
+ *
+ *
+ * @param[in] Downstream Downstream PCIe port PCI address
+ * @param[in] Upstream Upstream PCIe port PCI address
+ * @param[in] Lx Lx ASPM bitmap.
+ * Lx[0] - reserved
+ * Lx[1] - L1 enable
+ * Lx[2] - L0s enable for upstream ports
+ * Lx[3] - L0s enable for downstream ports
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+VOID
+PcieAspmEnableOnLink (
+ IN PCI_ADDR Downstream,
+ IN PCI_ADDR Upstream,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ ASPM_LINK_INFO AspmLinkInfo;
+ AspmLinkInfo.UpstreamLxCap = PcieAspmGetPmCapability (Upstream, pConfig);
+ AspmLinkInfo.DownstreamLxCap = PcieAspmGetPmCapability (Downstream, pConfig);
+ AspmLinkInfo.DownstreamPort = Downstream;
+ AspmLinkInfo.UpstreamPort = Upstream;
+ AspmLinkInfo.RequestedLx = Lx;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream ASPM Capability %d:%d:%d - %x\n", Downstream.Address.Bus, Downstream.Address.Device, Downstream.Address.Function, AspmLinkInfo.DownstreamLxCap));
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream ASPM Capability %d:%d:%d - %x\n", Upstream.Address.Bus, Upstream.Address.Device, Upstream.Address.Function, AspmLinkInfo.UpstreamLxCap));
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Requested ASPM State - %x\n", Lx));
+ AspmLinkInfo.DownstreamLx = AspmLinkInfo.UpstreamLxCap & AspmLinkInfo.DownstreamLxCap & Lx & ASPM_L1;
+ AspmLinkInfo.UpstreamLx = AspmLinkInfo.DownstreamLx;
+ if ((AspmLinkInfo.UpstreamLxCap & ASPM_L0s) != 0 && (Lx & ASPM_UPSTREAM_L0s) != 0) {
+ AspmLinkInfo.UpstreamLx |= ASPM_L0s;
+ }
+ if ((AspmLinkInfo.DownstreamLxCap & ASPM_L0s) != 0 && (Lx & ASPM_DOWNSTREAM_L0s) != 0) {
+ AspmLinkInfo.DownstreamLx |= ASPM_L0s;
+ }
+#ifndef ASPM_WORKAROUND_DISABLE
+ PcieAspmWorkarounds (&AspmLinkInfo, pConfig);
+#endif
+ LibNbCallBack (PHCB_AmdPcieAsmpInfo, (UINTN)&AspmLinkInfo, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream ASPM State - %x\n", AspmLinkInfo.UpstreamLx));
+ PcieAspmEnableOnDevice (Upstream, AspmLinkInfo.UpstreamLx, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream ASPM State - %x\n", AspmLinkInfo.DownstreamLx));
+ PcieAspmEnableOnFunction (Downstream, AspmLinkInfo.DownstreamLx, pConfig);
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set ASMP State on all function of PCI device
+ *
+ *
+ *
+ * @param[in] Device PCI address of device.
+ * @param[in] Lx Lx ASPM bitmap.
+ * Lx[0] = L0s enable
+ * Lx[1] - L1 enable
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmEnableOnDevice (
+ IN PCI_ADDR Device,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 Value;
+ UINT8 MaxFunc;
+ UINT8 CurrentFunc;
+
+ LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Value, pConfig);
+ MaxFunc = (Value & BIT7)?7:0;
+ for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) {
+ Device.Address.Function = CurrentFunc;
+ if (LibNbIsDevicePresent (Device, pConfig)) {
+ PcieAspmEnableOnFunction (Device, Lx, pConfig);
+ }
+ }
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set ASMP State on PCIe device function
+ *
+ *
+ *
+ * @param[in] Function PCI address of function.
+ * @param[in] Lx Lx ASPM bitmap.
+ * Lx[0] = L0s enable
+ * Lx[1] - L1 enable
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmEnableOnFunction (
+ IN PCI_ADDR Function,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 PcieCapPtr;
+ PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, pConfig);
+ if (PcieCapPtr != 0) {
+ LibNbPciRMW (Function.AddressValue | (PcieCapPtr + 0x10) , AccessS3SaveWidth8, (UINT32)~(BIT0 & BIT1), Lx, pConfig);
+ }
+}
+
+/**----------------------------------------------------------------------------------------*/
+/**
+ * Port/Endpoint ASMP capability
+ *
+ *
+ *
+ * @param[in] Device PCI address of downstream port.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval Bitmap of actual supported Lx states
+ */
+ /*----------------------------------------------------------------------------------------*/
+UINT8
+PcieAspmGetPmCapability (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 PcieCapPtr;
+ UINT8 Value;
+ PcieCapPtr = LibNbFindPciCapability (Device.AddressValue, PCIE_CAP_ID, pConfig);
+ if (PcieCapPtr == 0) {
+ return 0;
+ }
+ LibNbPciRead (Device.AddressValue | (PcieCapPtr + 0x0D) , AccessWidth8, &Value, pConfig);
+ return (Value >> 2) & 3;
+}
+
+
+/**----------------------------------------------------------------------------------------*/
+/**
+ * Scan PCIe topology
+ *
+ *
+ *
+ * @param[in] This Pointer to instance of scan protocol
+ * @param[in] Function PCI address of found device/function.
+ *
+ * @retval SCAN_FINISHED Scan for device finished.
+ */
+ /*----------------------------------------------------------------------------------------*/
+SCAN_STATUS
+PcieSetDeviceAspm (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Function
+ )
+{
+ PCIE_DEVICE_TYPE DeviceType;
+ UINT8 SecondaryBus;
+ ASPM_WORKSPACE *WorkspacePtr;
+ WorkspacePtr = (ASPM_WORKSPACE*)This;
+
+ DeviceType = PcieGetDeviceType (Function, This->pConfig);
+ if (DeviceType == PcieDeviceRootComplex || DeviceType == PcieDeviceDownstreamPort) {
+ PCI_ADDR UpstreamDevice;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached downstream port\n"));
+ //Lets enable Common clock
+ LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig);
+ LibNbPciRMW(Function.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffff, 0, This->pConfig); //This done to help UEFI bootscript restore bud topology.
+ if (SecondaryBus == 0) {
+ return SCAN_FINISHED;
+ }
+ //New Downstream Port
+ WorkspacePtr->LinkCount++;
+ if (WorkspacePtr->DownstreamPort.AddressValue == 0) {
+ WorkspacePtr->DownstreamPort.AddressValue = Function.AddressValue;
+ }
+ //Lets enable Common clock
+ UpstreamDevice.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0);
+ if (LibNbIsDevicePresent (UpstreamDevice, This->pConfig)) {
+ PcieAspmEnableCommonClock (Function, UpstreamDevice, This->pConfig);
+ }
+ This->ScanBus (This, UpstreamDevice);
+ if (WorkspacePtr->DownstreamPort.AddressValue == Function.AddressValue) {
+ WorkspacePtr->DownstreamPort.AddressValue = 0;
+ PcieAspmEnableOnLink (Function, UpstreamDevice, WorkspacePtr->Lx, This->pConfig);
+ }
+ } else if (DeviceType == PcieDeviceUpstreamPort ) {
+ PCI_ADDR DownstreamDevice;
+
+ if (WorkspacePtr->DownstreamPort.AddressValue == 0) {
+ return SCAN_FINISHED;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached upstream port\n"));
+ LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig);
+ LibNbPciRMW(Function.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffff, 0, This->pConfig); //This done to help UEFI bootscript restore bud topology.
+ if (SecondaryBus == 0) {
+ return SCAN_FINISHED;
+ }
+ DownstreamDevice.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0);
+ This->ScanBus (This, DownstreamDevice);
+ } else if (DeviceType < PcieDeviceLegacyEndPoint) {
+ // We reach end of link @toDo code to check exit latency.
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached endpoint \n"));
+ }
+ return SCAN_FINISHED;
+}
+
+/**----------------------------------------------------------------------------------------*/
+/**
+ * Scan RC PCIe topology to setup ASPM
+ *
+ *
+ *
+ * @param[in] Device PCI address of downstream port.
+ * @param[in] Lx Lx ASPM bitmap.
+ * Lx[0] - reserved
+ * Lx[1] - L1 enable
+ * Lx[2] - L0s enable for upstream ports
+ * Lx[3] - L0s enable for downstream ports
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmSetOnRc (
+ IN PCI_ADDR Device,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ ASPM_WORKSPACE AspmWorkspace;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieSetPortAspm Enter\n"));
+ LibAmdMemFill (&AspmWorkspace, 0, sizeof (AspmWorkspace), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ AspmWorkspace.ScanPciePort.pConfig = pConfig;
+ AspmWorkspace.ScanPciePort.ScanBus = LibNbScanPciBus;
+ AspmWorkspace.ScanPciePort.ScanDevice = LibNbScanPciDevice;
+ AspmWorkspace.ScanPciePort.ScanFunction = PcieSetDeviceAspm;
+ AspmWorkspace.Lx = Lx;
+ AspmWorkspace.ScanPciePort.ScanFunction (&AspmWorkspace.ScanPciePort, Device);
+ if (AspmWorkspace.LinkCount > 1) {
+ LibNbScanPciBridgeBuses (&AspmWorkspace.ScanPciePort, Device);
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieSetPortAspm Exit\n"));
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h
new file mode 100644
index 0000000000..63a88a0c0e
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h
@@ -0,0 +1,131 @@
+/**
+ * @file
+ *
+ * ASPM support.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+#ifndef _NBPCIEASPM_H_
+#define _NBPCIEASPM_H_
+
+VOID
+PcieAsmpEnableOnPort (
+ IN PORT PortId,
+ IN PCIE_LINK_ASPM AsmpState,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+UINT8
+PcieAspmGetPmCapability (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieAspmEnableOnDevice (
+ IN PCI_ADDR Device,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieAspmEnableOnFunction (
+ IN PCI_ADDR Function,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieAspmEnableOnLink (
+ IN PCI_ADDR Downstream,
+ IN PCI_ADDR Upstream,
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieAspmEnableCommonClock (
+ IN PCI_ADDR Downstream,
+ IN PCI_ADDR Upstream,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+VOID
+PcieAspmCommonClockOnDevice (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieAspmCommonClockOnFunction (
+ IN PCI_ADDR Function,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#pragma pack (push, 1)
+
+/// Framework for ASPM enable
+typedef struct {
+ PCI_SCAN_PROTOCOL ScanPciePort; ///< PCI scan protocol
+ PCI_ADDR DownstreamPort; ///< Downstream port to enable ASPM
+ UINT8 MaxL0sLatency; ///< TBD
+ UINT8 MaxL1Latency; ///< TBD
+ UINT8 LinkCount; ///< TBD
+ UINT8 Lx; ///< ASPM state to enable
+} ASPM_WORKSPACE;
+
+#define ASPM_UPSTREAM_L0s BIT2
+#define ASPM_DOWNSTREAM_L0s BIT3
+#define ASPM_L1 BIT1
+#define ASPM_L0s BIT0
+
+/// Framework for callback ASPM capability callback
+typedef struct {
+ PCI_ADDR DownstreamPort; ///< Downstream port PCI address to enable ASPM
+ PCI_ADDR UpstreamPort; ///< Upstream port PCI address to enable ASPM
+ UINT8 DownstreamLxCap; ///< Downstream port ASPM capability
+ UINT8 UpstreamLxCap; ///< Upstream port ASPM capability
+ UINT8 DownstreamLx; ///< Downstream port ASPM setting
+ UINT8 UpstreamLx; ///< Upstream port ASPM setting
+ UINT8 RequestedLx; ///< Requested port ASPM setting
+} ASPM_LINK_INFO;
+
+#pragma pack (pop)
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c
new file mode 100644
index 0000000000..a77623e2c2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c
@@ -0,0 +1,105 @@
+/**
+ * @file
+ *
+ * PCIe link width control.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Allocate CPL buffers
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer. *
+ */
+VOID
+PcieLibCplBufferAllocation (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT PortId;
+ BOOLEAN IsAllocationEnabled;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCplBufferAllocation Enter [CoreId = %d]\n", CoreId));
+ IsAllocationEnabled = FALSE;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) {
+ PCI_ADDR Port;
+ PORT_INFO *pPortInfo;
+ pPortInfo = PcieLibGetPortInfo (PortId, pConfig);
+ if (pPortInfo->SlaveCplBuffers != 0) {
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d , Port Address 0x%x, CplBuffers, %d\n", PortId, Port.AddressValue, pPortInfo->SlaveCplBuffers));
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~(0x3f << 8), pPortInfo->SlaveCplBuffers << 8, pConfig);
+ IsAllocationEnabled = TRUE;
+ }
+ }
+ }
+ if (IsAllocationEnabled) {
+ CORE CoreAddress;
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT11), BIT11, pConfig);
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCplBufferAllocation Exit\n"));
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h
new file mode 100644
index 0000000000..87d3b30722
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * PCIe link width control.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIECPLBUFFERS_H_
+#define _NBPCIECPLBUFFERS_H_
+
+VOID
+PcieLibCplBufferAllocation (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c
new file mode 100644
index 0000000000..1111556270
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c
@@ -0,0 +1,475 @@
+/**
+ * @file
+ *
+ * PCIe silicon specific functions library.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "HotplugFirmware.h"
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+#define MCU_CLEAR_BLOCK_LENGTH 16
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+INDIRECT_REG_ENTRY
+STATIC
+PcieMiscInitTable[] = {
+ {
+ NB_MISC_REG20,
+ (UINT32)~BIT1,
+ 0x0
+ }, //enable static device remapping by default
+ {
+ NB_MISC_REG22,
+ 0xffffffff,
+ BIT27 | (0x8 << 12) | (0x8 << 16) | (0x8 << 20)
+ },
+ {
+ NB_MISC_REG2B,
+ 0xffffffff,
+ (0x8 << 12)
+ },
+ {
+ NB_MISC_REG6C,
+ 0xffffffff,
+ (0x8 << 16)
+ },
+ {
+ NB_MISC_REG6B,
+ 0xffffffff,
+ (UINT32) (0x1f << 27)
+ }, //[13][12]Turn Off Offset Cancellation
+ {
+ NB_MISC_REG37,
+ (UINT32)~(BIT11 + BIT12 + BIT13),
+ 0x0
+ }, //[14][13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG67,
+ (UINT32)~(BIT26 + BIT10 + BIT11),
+ BIT11
+ }, //[13]Disables Rx Clock gating in CDR
+ //[16]Sets Electrical Idle Threshold
+ {
+ NB_MISC_REG2C,
+ (UINT32)~(BIT10),
+ 0x0
+ }, //[13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG2A,
+ (UINT32)~(BIT17 + BIT16),
+ BIT17
+ }, //[16]Sets Electrical l Idle Threshold
+ {
+ NB_MISC_REG32,
+ (UINT32)~(0x3F << 20),
+ (UINT32) (0x2A << 20)
+ } //[17][16]Sets Electrical Idle Threshold
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc Initialization prior port training.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+PcieLibPreTrainingInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 ServerHotplugMask;
+ BOOLEAN SmuWa;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPreTrainingInit Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ ServerHotplugMask = 0;
+//Init Misc registers
+ LibNbIndirectTableInit (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieMiscInitTable[0],NULL),
+ (sizeof (PcieMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+//Setup peer-to-peer
+ if (pPcieConfig->PcieConfiguration.Peer2Peer == ON) {
+ if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (3, pConfig)] == GFX_CONFIG_AABB) {
+ Value = 0x08080404;
+ } else {
+ Value = 0x08080008;
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG49, AccessWidth32, 0, Value, pConfig);
+ if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (12, pConfig)] == GFX_CONFIG_AABB) {
+ Value = 0xFFFF0404;
+ } else {
+ Value = 0xFFFF0008;
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2F, AccessWidth32, 0, Value, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG48, AccessWidth32, (UINT32)~(BIT8), 0xffff0000, pConfig);
+ }
+
+ //Remap device number
+#ifndef DEVICE_REMAP_DISABLE
+ if (PciePortRemapInit (pConfig) != AGESA_SUCCESS ) {
+ REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_DEVICE_REMAP, 0, 0, 0, 0, pConfig);
+ }
+#endif
+
+#ifndef HOTPLUG_SUPPORT_DISABLED
+ ServerHotplugMask = PcieInitHotplug (pConfig);
+#endif
+
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, pConfig);
+ SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE;
+
+ if (SmuWa || ServerHotplugMask != 0) {
+ UINT32 BlockIndex;
+ UINT32 SmuWaData;
+ UINT16 Address;
+ UINT32 Data[MCU_CLEAR_BLOCK_LENGTH];
+
+ LibNbMcuControl (AssertReset, pConfig);
+ // clear SMU RAM
+ LibAmdMemFill (&Data[0], 0, sizeof (Data), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ for (Address = 0; Address < (16 * 1024); Address = Address + 4 * MCU_CLEAR_BLOCK_LENGTH) {
+ LibNbLoadMcuFirmwareBlock (Address, MCU_CLEAR_BLOCK_LENGTH, &Data[0], pConfig);
+ }
+ //Load SMU firmware
+ for (BlockIndex = 0; BlockIndex < Fm.NumberOfBlock; BlockIndex++) {
+ LibNbLoadMcuFirmwareBlock (Fm.BlockArray[BlockIndex].Address, Fm.BlockArray[BlockIndex].Length, Fm.BlockArray[BlockIndex].Data, pConfig);
+ }
+ if (SmuWa) {
+ SmuWaData = LibHtGetSmuWaData (pConfig);
+ LibNbLoadMcuFirmwareBlock (0xFE70, 0x1, &SmuWaData, pConfig);
+ }
+ SmuWaData = ((SmuWa == TRUE) ? 0x100 : 0x100) | ((ServerHotplugMask != 0) ? 0x1 : 0);
+ LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, pConfig);
+
+ LibNbMcuControl (DeAssertReset, pConfig);
+ }
+
+#ifndef HOTPLUG_SUPPORT_DISABLED
+ PcieCheckHotplug (ServerHotplugMask, pConfig);
+#endif
+
+}
+
+INDIRECT_REG_ENTRY PcieCoreInitTable[] = {
+ {
+ NB_BIFNB_REG10,
+ (UINT32)~(BIT10 + BIT11 + BIT12),
+ BIT12
+ },
+ {
+ NB_BIFNB_REG20,
+ (UINT32)~(BIT8 + BIT9),
+ BIT9
+ },
+ {
+ NB_BIFNB_REG02,
+ (UINT32)~(BIT0),
+ BIT0
+ },
+ {
+ NB_BIFNB_REG40,
+ (UINT32)~(BIT14 + BIT15),
+ BIT15
+ },
+ {
+ NB_BIFNB_REGC2,
+ (UINT32)~(BIT25),
+ BIT25
+ },
+ {
+ NB_BIFNB_REGC1,
+ (UINT32)~(BIT0),
+ (BIT0 + BIT1 + BIT2)
+ },
+ {
+ NB_BIFNB_REG1C,
+ 0x0,
+ (4 << 6) + (4 << 1) + 1
+ }
+};
+
+INDIRECT_REG_ENTRY PcieRd790CoreInitTable[] = {
+ {
+ NB_BIFNB_REGC2,
+ (UINT32)~(BIT14),
+ (BIT14)
+ },
+ {
+ NB_BIFNB_REGC1,
+ (UINT32)~(BIT2),
+ 0x0
+ },
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Core registers
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieLibCommonCoreInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 CoreAddress;
+ NB_INFO NbInfo;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit (CoreId = %d) Enter\n", CoreId));
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+
+ LibNbIndirectTableInit (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ CoreAddress,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieCoreInitTable[0],NULL),
+ (sizeof (PcieCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+
+ if (CoreAddress == SB_CORE) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG10 | CoreAddress, AccessWidth32, (UINT32)~BIT9, BIT9, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT26, BIT26 + BIT1, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG1C | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
+ }
+ if ( NbInfo.Type < NB_SR5690 ) {
+ LibNbIndirectTableInit (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ CoreAddress,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRd790CoreInitTable[0], NULL),
+ (sizeof (PcieRd790CoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit Exit\n"));
+};
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Core after training is completed
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer. *
+ */
+
+
+VOID
+PcieLibCoreAfterTrainingInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 CoreAddress;
+ PCIE_CONFIG *pPcieConfig;
+ PCI_ADDR ClkPciAddress;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT9), 0, pConfig);
+//Save core setting in scratch register
+ LibNbPciIndexWrite (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ NB_BIFNB_REG01 | CoreAddress,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->CoreSetting[CoreId],
+ pConfig
+ );
+//Save general setting in scratch
+ LibNbEnableClkConfig (pConfig);
+ LibNbPciWrite (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig);
+ LibNbDisableClkConfig (pConfig);
+
+}
+
+
+INDIRECT_REG_ENTRY PciePortInitTable[] = {
+ {
+ NB_BIFNBP_REG02,
+ (UINT32)~(BIT15),
+ BIT15
+ },
+ {
+ NB_BIFNBP_REGA1,
+ (UINT32)~(BIT24 + BIT26),
+ BIT11
+ },
+ {
+ NB_BIFNBP_REGB1,
+ 0xffffffff,
+ BIT28 + BIT23 + BIT19 + BIT20
+ },
+ {
+ NB_BIFNBP_REGA4,
+ (UINT32)~(BIT0),
+ 0x0
+ },
+ {
+ NB_BIFNBP_REGA2,
+ (UINT32)~(BIT13),
+ BIT13
+ },
+ {
+ NB_BIFNBP_REGA3,
+ (UINT32)~(BIT9),
+ BIT9
+ },
+ {
+ NB_BIFNBP_REGA0,
+ 0xffff000f,
+ 0x6830
+ },
+ {
+ NB_BIFNBP_REGC1,
+ 0xfffffff0,
+ 0xC
+ },
+ {
+ NB_BIFNBP_REG70,
+ (UINT32)~(BIT16 + BIT17 + BIT18),
+ BIT16 + BIT18
+ }
+};
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init port registers
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieLibCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR Port;
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 PcieSlotCapability;
+ UINT32 CoreAddress;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit PortId %d Enter\n", PortId));
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ CoreAddress = PcieLibGetCoreAddress (PcieLibGetCoreId (PortId, pConfig), pConfig);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+
+ LibNbIndirectTableInit (
+ Port.AddressValue | NB_BIF_INDEX,
+ 0x0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PciePortInitTable[0],NULL),
+ (sizeof (PciePortInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+ if (CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE || CoreAddress == GPP3b_CORE) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~(BIT16 + BIT17 + BIT18), (BIT17 + BIT18), pConfig);
+ if (CoreAddress == GPP3a_CORE) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGB1, AccessWidth32, (UINT32)~(BIT22), BIT22, pConfig);
+ }
+ }
+// Set completion timeout
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessS3SaveWidth8, 0xF0, 0x6, pConfig);
+ //if (CoreAddress != SB_CORE) {
+ // LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
+ //}
+//For hotplug ports
+ //if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ||
+ // pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON ||
+ // LibNbGetRevisionInfo (pConfig).Revision == NB_REV_A11) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG20, AccessWidth32, (UINT32)~BIT19, 0x0, pConfig);
+ //}
+
+// Enable Immediate ACK
+ if (pPcieConfig->ExtPortConfiguration[PortId].PortL1ImmediateACK == ON) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA0, AccessWidth32, (UINT32)~BIT23, BIT23, pConfig);
+ }
+//Set up slot capability
+ PcieSlotCapability = (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit << 7) |
+ ((Port.Address.Device | Port.Address.Bus << 5 ) << 19);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessS3SaveWidth32, (UINT32)~((0x3ff << 7) | (0x1fff << 19)), PcieSlotCapability, pConfig);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG5A, AccessS3SaveWidth16, (UINT32)~BIT8, BIT8, pConfig);
+//Set interrupt pin info
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG3D, AccessS3SaveWidth8, 0x0, 0x1, pConfig);
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit Exit\n"));
+};
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c
new file mode 100644
index 0000000000..25ef38f587
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c
@@ -0,0 +1,343 @@
+/**
+ * @file
+ *
+ * Routines to support Hotplug.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdSbLib.h"
+
+#ifndef HOTPLUG_SUPPORT_DISABLED
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+#define ATTN_BUTTON_PRESENT BIT0
+#define PWR_CONTROLLER_PRESENT BIT1
+#define MRL_SENSOR_PRESENT BIT2
+#define ATTN_INDICATOR_PRESENT BIT3
+#define PWR_INDICATOR_PRESENT BIT4
+#define HOTPLUG_SURPRISE BIT5
+#define HOTPLUG_CAPABLE BIT6
+
+#define ATTN_BUTTON_PRESSED BIT0
+#define PWR_FAULT_DETECTED BIT1
+#define MRL_SENSOR_CHANGED BIT2
+#define PRESENCE_DETECT_CHANGED BIT3
+#define COMMAND_COMPLETED BIT4
+#define MRL_SENSOR_STATE BIT5
+#define PRESENCE_DETECT_STATE BIT6
+#define DL_STATE_CHANGED BIT8
+
+#define PWR_CONTROLLER_CNTL BIT10
+#define NO_COMMAND_COMPLETED_SUPPORTED BIT18
+#define SERVER_HOTPLUG_CAPABILITY \
+ (ATTN_BUTTON_PRESENT | PWR_CONTROLLER_PRESENT | ATTN_INDICATOR_PRESENT | PWR_INDICATOR_PRESENT | HOTPLUG_CAPABLE)
+#define NATIVE_HOTPLUG_CAPABILITY \
+ (HOTPLUG_SURPRISE | HOTPLUG_CAPABLE)
+
+#define SERVER_HOTPLUG 1
+#define NATIVE_HOTPLUG 2
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+ /*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+UINT32
+PcieInitHotplug (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 ServerHotplugPortMask;
+ PORT PortId;
+ PCI_ADDR ClkPciAddress;
+ NB_INFO NbInfo;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ ServerHotplugPortMask = 0;
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ if (NbInfo.Type == NB_SR5690) {
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) {
+ UINT8 HpDescriptorRegister;
+ UINT8 HpDescriptorOffset;
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress;
+ if (HpDescriptorOffset != 0xff) {
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister;
+ //Enable CLK config
+ LibNbEnableClkConfig (pConfig);
+ //Setup descriptor
+ LibNbPciRMW (
+ ClkPciAddress.AddressValue | HpDescriptorRegister ,
+ AccessWidth32,
+ 0xffffffff,
+ ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset,
+ pConfig
+ );
+ //Hide CLK config
+ LibNbDisableClkConfig (pConfig);
+ // Enable power fault
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig);
+ //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig);
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig);
+ }
+ }
+ }
+ }
+ return ServerHotplugPortMask;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ * @param[in] ServerHotplugPortMask ServerHotplugPortMask
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+PcieCheckHotplug (
+ IN UINT32 ServerHotplugPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT PortId;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Enter\n"));
+ //Check if Firmware loaded successfully
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ //Check Firmware Loaded successfully
+ if ((ServerHotplugPortMask & (1 << PortId)) != 0) {
+ UINT32 Count;
+ PCI_ADDR Port;
+ UINT16 SlotStatus;
+
+ Count = 30; //Setup counter for 30ms
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig);
+ } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count));
+ if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) {
+ REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n"));
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, (UINT32)~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig);
+ } else {
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) {
+ //Power on slot
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, (UINT32)~PWR_CONTROLLER_CNTL, 0x0, pConfig);
+ }
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Exit\n"));
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init Ports Hotplug capability.
+ * Initialize hotplug controller init port hotplug capability
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval AGESA_SUCCESS Hotplug controller successfully initialized.
+ * @retval AGESA_FAIL Failure during initialization of hotplug controller.
+ */
+/*----------------------------------------------------------------------------------------*/
+/*
+AGESA_STATUS
+PcieInitHotplug (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT32 ServerHotplugPortMask;
+ PORT PortId;
+ PCI_ADDR ClkPciAddress;
+ NB_INFO NbInfo;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ ServerHotplugPortMask = 0;
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ Status = AGESA_SUCCESS;
+ if (NbInfo.Type == NB_SR5690) {
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) {
+ UINT8 HpDescriptorRegister;
+ UINT8 HpDescriptorOffset;
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress;
+ if (HpDescriptorOffset != 0xff) {
+ ServerHotplugPortMask |= 1 << PortId;
+ HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister;
+ //Enable CLK config
+ LibNbEnableClkConfig (pConfig);
+ //Setup descriptor
+ LibNbPciRMW (
+ ClkPciAddress.AddressValue | HpDescriptorRegister ,
+ AccessWidth32,
+ 0xffffffff,
+ ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset,
+ pConfig
+ );
+ //Hide CLK config
+ LibNbDisableClkConfig (pConfig);
+ // Enable power fault
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig);
+ //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig);
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig);
+ }
+ }
+ }
+ if (ServerHotplugPortMask != 0) {
+ UINT32 FirmwareLength;
+ FirmwareLength = sizeof (Firmware);
+ if (FirmwareLength > 0) {
+ UINT32 *pFirmware;
+ pFirmware = (UINT32*)FIX_PTR_ADDR (&Firmware[0], NULL);
+ //Load firmware
+ LibNbMcuControl (AssertReset, pConfig);
+ LibNbLoadMcuFirmwareBlock (0x200, (sizeof (Firmware) - 64), pFirmware, pConfig);
+ LibNbLoadMcuFirmwareBlock (0xFFC0, 64, &pFirmware[(sizeof (Firmware) - 64) / 4], pConfig);
+ LibNbMcuControl (DeAssertReset, pConfig);
+ }
+ }
+ //Check if Firmware loaded successfully
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ //Check Firmware Loaded successfully
+ if ((ServerHotplugPortMask & (1 << PortId)) != 0) {
+ UINT32 Count;
+ PCI_ADDR Port;
+ UINT16 SlotStatus;
+
+ Count = 30; //Setup counter for 30ms
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig);
+ } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count));
+ if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) {
+ Status = AGESA_ERROR;
+ REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n", PortId));
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, ~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig);
+ } else {
+ //Clear Status
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig);
+ if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) {
+ //Power on slot
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, ~PWR_CONTROLLER_CNTL, 0x0, pConfig);
+ }
+ }
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Exit. Status[0x%x]\n", Status));
+ return Status;
+}
+*/
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h
new file mode 100644
index 0000000000..1b7ba040b2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h
@@ -0,0 +1,62 @@
+/**
+ * @file
+ *
+ * PCIe hotplug support.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#ifndef _NBPCIEHOTPLUG_H_
+#define _NBPCIEHOTPLUG_H_
+
+
+UINT32
+PcieInitHotplug (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieCheckHotplug (
+ IN UINT32 ServerHotplugPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ );
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c b/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c
new file mode 100644
index 0000000000..6fdf2b120c
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c
@@ -0,0 +1,720 @@
+/**
+ * @file
+ *
+ * PCIe Early initialization.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+ /*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PCIE Init for all NB.
+ * Basic programming / EP training. After this call EP are fully operational.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+AmdPcieEarlyInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (PcieEarlyInit, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge PCIE Init.
+ * Basic programming / EP training. After this call EP are fully operational on particular NB.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieEarlyInit (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieEarlyInit Enter\n"));
+ Status = PcieLibInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0 , 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ Status = PciePreTrainingInit (NbConfigPtr);
+ Status = PcieInitPorts (NbConfigPtr);
+ Status = PcieAfterTrainingInit (NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieEarlyInit Exit [0x%x]\n", Status));
+ return Status;
+}
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc initialization prior port link training started
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PciePreTrainingInit (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ CORE CoreId ;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePreTrainingInit Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ //Unhide all ports
+ PcieLibUnHidePorts (pConfig);
+ if (pPcieConfig->PcieMmioBaseAddress != 0 && pPcieConfig->PcieMmioSize != 0) {
+ PcieLibSetPcieMmioBase (pPcieConfig->PcieMmioBaseAddress, pPcieConfig->PcieMmioSize, pConfig);
+ }
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreId %d CoreSetting = 0x%x\n", CoreId, *((UINT32*)&pConfig->pPcieConfig->CoreSetting[CoreId])));
+ //if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) {
+ //Configure cores
+ if (pPcieConfig->CoreSetting[CoreId].SkipConfiguration == OFF) {
+ PcieLibSetCoreConfiguration (CoreId, pConfig);
+ }
+ //Init core registers
+ PcieLibCommonCoreInit (CoreId, pConfig);
+ //}
+ }
+ PcieLibPreTrainingInit (pConfig);
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreId %d CoreSetting = 0x%x\n", CoreId, *((UINT32*)&pConfig->pPcieConfig->CoreSetting[CoreId])));
+ //Init CPL buffer allocation
+ //if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF && pPcieConfig->CoreSetting[CoreId].CplBufferAllocation == ON) {
+ if (pPcieConfig->CoreSetting[CoreId].CplBufferAllocation == ON) {
+ PcieLibCplBufferAllocation (CoreId, pConfig);
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePreTrainingInit Exit\n"));
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc initialization after port training complete
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieAfterTrainingInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ CORE CoreId;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+// if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) {
+ //Configure cores
+ PcieLibCoreAfterTrainingInit (CoreId, pConfig);
+// }
+ }
+ //Hide all Ports
+ PcieLibHidePorts (pConfig);
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Train PCIE Ports
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieInitPorts (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+
+ Status = AGESA_SUCCESS;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ if (pPcieConfig->DeviceInitMaskS1 != 0) {
+ Status = PcieInitSelectedPorts (pPcieConfig->DeviceInitMaskS1, pConfig);
+ }
+ if (pPcieConfig->DeviceInitMaskS2 != 0) {
+ Status = PcieInitSelectedPorts (pPcieConfig->DeviceInitMaskS2, pConfig);
+ }
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Train PCIE Ports selected for this stage
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieInitSelectedPorts (
+ IN UINT16 SelectedPortMask,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ PORT PortId;
+ BOOLEAN RequestResetDelay;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitSelectedPorts (Ports = 0x%x) Enter\n", SelectedPortMask));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ Status = AGESA_SUCCESS;
+ RequestResetDelay = FALSE;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d PortConfiguration = 0x%x ExtPortConfiguration = 0x%x\n", PortId, *((UINT32*)&pPcieConfig->PortConfiguration[PortId]), *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId])));
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) {
+ PCIE_LINK_MODE LinkMode;
+ //Deassert slot reset. Bring EP out of reset
+ Status = LibNbCallBack (PHCB_AmdPortResetDeassert, 1 << PortId, pConfig);
+ if (Status == AGESA_SUCCESS) {
+ //STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ResetToTrainingDelay * 1000, 0);
+ RequestResetDelay = TRUE;
+ }
+ //Init common registers
+ PcieLibCommonPortInit (PortId, pConfig);
+ //Check if we already have device failure to go to Gen2 before
+ if (PcieLibCheckGen2Disabled (PortId, pConfig)) {
+ pPcieConfig->PortConfiguration[PortId].PortLinkMode = PcieLinkModeGen1;
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB; // this is to workaround Gen2
+ }
+ //@todo Add handling for scratch register for PCIE Gen
+ switch (pPcieConfig->PortConfiguration[PortId].PortLinkMode) {
+ case PcieLinkModeGen2:
+ case PcieLinkModeGen2AdvertizeOnly:
+ case PcieLinkModeGen1:
+ LinkMode = pPcieConfig->PortConfiguration[PortId].PortLinkMode;
+ break;
+ default:
+ LinkMode = PcieLinkModeGen1;
+ }
+ PcieLibSetLinkMode (PortId, LinkMode, pConfig);
+ //Enable Compliance Mode
+ if (pPcieConfig->PortConfiguration[PortId].PortCompliance == ON) {
+ PcieLibSetLinkCompliance (PortId, pConfig);
+ }
+ } else {
+ //Port disabled
+ SelectedPortMask &= (~(1 << PortId));
+ }
+ }
+ }
+ if (RequestResetDelay) {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ResetToTrainingDelay * 1000, 0);
+ }
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ //Release Port Training
+ PcieLibPortTrainingControl (PortId, PcieLinkTrainingRelease, pConfig);
+ }
+ }
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->TrainingToLinkTestDelay * 1000, 0);
+ Status = PcieCheckSelectedPorts (SelectedPortMask, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitSelectedPorts Exit\n"));
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check link state on selected ports.
+ *
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieCheckSelectedPorts (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ PORT PortId;
+ UINT16 PortMask;
+ UINT16 CurrentPortMask;
+ PCIE_LINK_STATUS PortsLinkStatus[MAX_PORT_ID + 1];
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckSelectedPorts (Ports = 0x%x) Enter\n", SelectedPortMask));
+ Status = AGESA_SUCCESS;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ PortMask = SelectedPortMask;
+ // Clear up link state storage
+ LibAmdMemFill (PortsLinkStatus, 0, sizeof (PortsLinkStatus), (AMD_CONFIG_PARAMS *)&(pPcieConfig->sHeader));
+ // Initial check for link status on all ports
+ if (PortMask != 0) {
+ PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig);
+ }
+ // Check if training on any ports in progress
+ PortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #1 PortMask = 0x%x\n", PortMask));
+ if (PortMask != 0) {
+ // Try to recover ports in case of broken lane
+ if (PcieBrokenLaneWorkaround (PortMask, pConfig) != AGESA_UNSUPPORTED) {
+ // Update port status array
+ PortMask |= PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected);
+ PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig);
+ }
+ }
+ // Check if training on any ports still in progress
+ CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress);
+ if (PortMask != CurrentPortMask) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_BROKEN_LINE, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig);
+ }
+ PortMask = CurrentPortMask;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #2 PortMask = 0x%x\n", PortMask));
+ if (PortMask != 0) {
+ // Try to recover port training by downgrading link speed to Gen1
+ if (PcieGen2Workaround (PortMask, pConfig) != AGESA_UNSUPPORTED) {
+ PortMask |= PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected);
+ PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig);
+ }
+ }
+ // Check if training on any ports still in progress
+ CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress);
+ if (PortMask != CurrentPortMask) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_GEN2_FAIL, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig);
+ }
+ PortMask = CurrentPortMask;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #3 PortMask = 0x%x\n", PortMask));
+ if (PortMask != 0) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_TRAINING_FAIL, PortMask, 0, 0, 0, pConfig);
+ PcieMiscWorkaround (&PortsLinkStatus[0], pConfig);
+ }
+ //Get bitmap of successfully trained ports
+ PortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #4 PortMask = 0x%x\n", PortMask));
+ if (PortMask != 0) {
+ // Check if VCO negotiation is completed
+ PcieCheckVco (PortMask, &PortsLinkStatus[0], pConfig);
+ }
+ CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected);
+ if (PortMask != CurrentPortMask) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_VCO_NEGOTIATON, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig);
+ }
+ PortMask = CurrentPortMask;
+ //Update status port status info
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (PortsLinkStatus[PortId] == PcieLinkStatusInCompliance) {
+ pPcieConfig->PortConfiguration[PortId].PortCompliance = ON;
+ } else {
+ if (PortsLinkStatus[PortId] == PcieLinkStatusConnected) {
+ if (LibNbCallBack (PHCB_AmdPortTrainingCompleted, Port.AddressValue, pConfig) == AGESA_ERROR) {
+ PortsLinkStatus[PortId] = 0;
+ }
+ if (PortsLinkStatus[PortId] == PcieLinkStatusConnected &&
+ pPcieConfig->PcieConfiguration.DisableGfxWorkaround == OFF &&
+ PcieLibGetPortLinkInfo (PortId, pConfig).MaxLinkWidth >= PcieLinkWidth_x8 &&
+ PcieGfxWorkarounds (PortId, pConfig) != AGESA_SUCCESS) {
+ //CIMX_ASSERT (FALSE);
+ PortsLinkStatus[PortId] = 0;
+ }
+ if (PortsLinkStatus[PortId] == PcieLinkStatusConnected) {
+ pPcieConfig->PortConfiguration[PortId].PortDetected = ON;
+ PcieLibSetLinkWidth (PortId, pPcieConfig->ExtPortConfiguration[PortId].PortLinkWidth, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug == OFF) {
+ //Port training on Hold if Link in not connected and not in compliance
+ PcieLibPortTrainingControl (PortId, PcieLinkTrainingHold, pConfig);
+ }
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF ||
+ pPcieConfig->PortConfiguration[PortId].PortHotplug == ON) {
+ // For all port without devices and hotplug ports
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~BIT19, BIT19, pConfig);
+ }
+ LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG01, AccessWidth32, (UINT32*)&pPcieConfig->PortConfiguration[PortId], pConfig);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig);
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckSelectedPorts Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Workaround for broken TX line.
+ *
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieBrokenLaneWorkaround (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PORT PortId;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieBrokenLaneWorkaround Enter\n"));
+ Status = AGESA_UNSUPPORTED;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ LINK_INFO LinkInfo = PcieLibGetPortLinkInfo (PortId, pConfig);
+ if (LinkInfo.MaxLinkWidth > PcieLinkWidth_x1 && LinkInfo.LinkWidth < LinkInfo.MaxLinkWidth) {
+ PcieLibPowerOffPortLanes (PortId, LinkInfo.LinkWidth, pConfig);
+ if (PcieLibResetSlot (PortId, pConfig) == AGESA_SUCCESS) {
+ Status = AGESA_SUCCESS;
+ }
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieBrokenLaneWorkaround Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Workaround for device violating Gen2 spec.
+ * Downgrade link speed to Gen1.
+ *
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieGen2Workaround (
+ IN UINT16 SelectedPortMask,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ PORT PortId;
+ BOOLEAN RequestPciReset;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGen2Workaround Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ RequestPciReset = FALSE;
+ Status = AGESA_UNSUPPORTED;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2 ||
+ pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2AdvertizeOnly ||
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis == PcieTxDeemphasis3p5dB) {
+ //Degrade link speed to Gen1
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB;
+ PcieLibSetLinkMode (PortId, PcieLinkModeGen1, pConfig);
+ PcieLibSetGen2Disabled (PortId, pConfig);
+ if (PcieLibResetSlot (PortId, pConfig) != AGESA_SUCCESS) {
+ //Slot reset logic not supported request PCI reset.
+ RequestPciReset = TRUE;
+ }
+ //Report back to caller that potential downgrade case is detected.
+ Status = AGESA_SUCCESS;
+ }
+ }
+ if (RequestPciReset) {
+ PcieLibRequestPciReset (pConfig);
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGen2Workaround Enter\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Try to recover system by issuing system wide PCI reset.
+ *
+ *
+ *
+ * @param[in] PortsLinkStatus Array of link status for every Port
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieMiscWorkaround (
+ IN PCIE_LINK_STATUS *PortsLinkStatus,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PORT PortId;
+ UINT16 PortMask;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieMiscWorkaround Enter\n"));
+ Status = AGESA_UNSUPPORTED;
+ PortMask = PcieFindPortsWithLinkStatus (PortsLinkStatus, PcieLinkStatusTrainingInProgress);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if ((PortMask & (1 << PortId)) != 0) {
+ if (PcieLibRequestPciReset (pConfig)!= AGESA_SUCCESS) {
+ break;
+ }
+ PortMask = PcieFindPortsWithLinkStatus (PortsLinkStatus, PcieLinkStatusTrainingInProgress);
+ if (PortMask == 0) {
+ break;
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieMiscWorkaround Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check VCO negotiation complete.
+ * Routine will retry retrain device infinitely if VCO negotiation is failing.
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] PortsLinkStatus Array of link status for every Port
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieCheckVco (
+ IN UINT16 SelectedPortMask,
+ IN PCIE_LINK_STATUS *PortsLinkStatus,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT16 VcoNegotiationInProgressPortMask;
+ PORT PortId;
+ UINT16 VcoStatus;
+ UINT32 LinkRetrainCount;
+ UINT32 VcoPoll;
+ UINT32 Value;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]VcoNegotiationInProgress Enter\n"));
+ Status = AGESA_SUCCESS;
+ VcoNegotiationInProgressPortMask = SelectedPortMask;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (VcoNegotiationInProgressPortMask & (1 << PortId)) {
+ // For each port where VCO needs to be checked
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ PortsLinkStatus[PortId] = PcieLinkStatusVcoNegotiationInProgress;
+ for (LinkRetrainCount = 0; LinkRetrainCount < 10; LinkRetrainCount++) {
+ // Poll for 200 ms for VC0 negotioation completion
+ for (VcoPoll = 0; VcoPoll < 200; VcoPoll++) {
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &VcoStatus, pConfig);
+ if ((VcoStatus & BIT1) != 0) {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ } else {
+ PortsLinkStatus[PortId] = PcieLinkStatusConnected;
+ break;
+ }
+ } //For each VcoPoll
+ if (PortsLinkStatus[PortId] == PcieLinkStatusVcoNegotiationInProgress) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_MISC), " Vco Not Completed. Retrain link on PortId %d\n", PortId));
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig);
+ Value = (Value & 0xfffffe80) | ((Value & 0x70) >> 4) | BIT8;
+ LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig);
+ } else {
+ break; //Vco negotiations complete
+ }
+ } //For each LinkRetrainCount
+ if (PortsLinkStatus[PortId] == PcieLinkStatusVcoNegotiationInProgress) {
+ PortsLinkStatus[PortId] = PcieLinkStatusNotConnected;
+ }
+ } // Vco negotiations required
+ } //For each port
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]VcoNegotiationInProgress Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get bit map of ports with particular link status
+ *
+ *
+ *
+ * @param[in] PortLinkStatus Pointer to array of link status for every Port
+ * @param[in] LinkStatus LinkStatus to search for.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+UINT16
+PcieFindPortsWithLinkStatus (
+ IN PCIE_LINK_STATUS *PortLinkStatus,
+ IN PCIE_LINK_STATUS LinkStatus
+ )
+{
+ UINT16 PortMask;
+ PORT PortId;
+
+ PortMask = 0;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PortLinkStatus[PortId] == LinkStatus) PortMask |= (1 << PortId);
+ }
+ return PortMask;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Gather link state for selected ports.
+ *
+ *
+ * @param[in] SelectedPortMask Bitmap of port ID selected for training.
+ * @param[in] PortLinkStatus Pointer to array of link status for every Port
+ * @param[in] Pooling Time in MS to pool for link status change.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+PCIE_LINK_STATUS
+PcieGetPortsLinkStatus (
+ IN UINT16 SelectedPortMask,
+ IN OUT PCIE_LINK_STATUS *PortLinkStatus,
+ IN UINT32 Pooling,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_LINK_STATUS Status;
+ PORT PortId;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGetPortsLinkStatus Enter\n"));
+ Status = PcieLinkStatusNotConnected;
+ Pooling *= 10;
+ while (Pooling-- != 0 && Status != PcieLinkStatusConnected) {
+ Status = PcieLinkStatusConnected; //Set up initial overall state as connected
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ //Work only on selected ports
+ if ((SelectedPortMask & (1 << PortId)) != 0) {
+ PCI_ADDR Port;
+ UINT32 LinkState;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig); //Get PCI address of this port
+ //Get link state
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, pConfig);
+ LinkState &= 0x3F;
+ //CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_MISC), " PortId %d LinkState = 0x%x \n", PortId, LinkState));
+ printk(BIOS_INFO, "[NBPCIE] PortId %02d LinkState = 0x%x \n", PortId, LinkState);
+ //Check if link in L0 state
+
+ if (LinkState == 0x10) {
+ PortLinkStatus[PortId] = PcieLinkStatusConnected;
+ } else {
+ Status = PcieLinkStatusNotConnected;
+ //Check if link in compliance mode
+ if (LinkState == 0x7) {
+ PortLinkStatus[PortId] = PcieLinkStatusInCompliance;
+ } else {
+ //Check if we passed receiver detection. It will indicate that device present.
+ if (LinkState > 0x4) {
+ PortLinkStatus[PortId] = PcieLinkStatusTrainingInProgress;
+ }
+ }
+ }
+ }
+ }
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 100, 0);
+ }
+ return Status;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c b/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c
new file mode 100644
index 0000000000..17ae4f746b
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c
@@ -0,0 +1,505 @@
+/**
+ * @file
+ *
+ * PCIE Late Initialization
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd PCIE Late Init for all NB.
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+AGESA_STATUS
+AmdPcieLateInit (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (PcieLateInit, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd PCIE Late Init for all NB.
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+AGESA_STATUS
+AmdPcieLateInitWa (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (PcieLateInitWa, ConfigPtr);
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd PCIE Special Init for all NB.
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+AGESA_STATUS
+AmdPcieValidatePortState (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (PcieValidatePortState, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd PCIE S3 Init fro all NB.
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+AGESA_STATUS
+AmdPcieS3Init (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (PcieLateInit, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB PCIE Late Init.
+ * Extended programming. Enable power management and misc capability.
+ * Prepare PCIE subsystem to boot to OS.
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateInit (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ PcieLibUnHidePorts (NbConfigPtr);
+ Status = PcieLateValidateConfiguration (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ PcieLibHidePorts (NbConfigPtr);
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ PcieLibLateInit (NbConfigPtr);
+ Status = PcieLateInitPorts (NbConfigPtr);
+ Status = PcieLateInitCores (NbConfigPtr);
+ PcieLibHidePorts (NbConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB PCIE Late Init.
+ * Extended programming. Enable power management and misc capability.
+ * Prepare PCIE subsystem to boot to OS.
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateInitWa (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 Value;
+ BOOLEAN SmuWa;
+ LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, NbConfigPtr);
+ SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE;
+ if (SmuWa) {
+ UINT32 SmuWaData;
+ LibNbMcuControl (AssertReset, NbConfigPtr);
+ SmuWaData = LibNbReadMcuRam (0xFE74, NbConfigPtr);
+ SmuWaData &= 0x00ff;
+ LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, NbConfigPtr);
+ LibNbMcuControl (DeAssertReset, NbConfigPtr);
+ }
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Late init PCIE Ports
+ *
+ *
+ *
+* @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateInitPorts (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ PORT PortId;
+ BOOLEAN IsIommuEnabled;
+ NB_INFO NbInfo;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitPorts Enter\n"));
+ IsIommuEnabled = LibNbIsIommuEnabled (NbConfigPtr);
+ NbInfo = LibNbGetRevisionInfo (NbConfigPtr);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ Status = AGESA_SUCCESS;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ CORE CoreId;
+ CoreId = PcieLibGetCoreId (PortId, NbConfigPtr);
+ if (!PcieLibIsValidCoreId (CoreId, NbConfigPtr)) {
+ PcieLibPowerOffPortLanes (PortId, PcieLinkWidth_x0, NbConfigPtr);
+ } else if (PcieLibIsValidPortId (PortId, NbConfigPtr)) {
+ PCIE_LINK_WIDTH LinkWidth;
+ PCI_ADDR Port;
+ LinkWidth = PcieLibGetLinkWidth (PortId, NbConfigPtr);
+ CoreId = PcieLibGetCoreId (PortId, NbConfigPtr);
+ Port = PcieLibGetPortPciAddress (PortId, NbConfigPtr);
+ PcieLateCommonPortInit (PortId, NbConfigPtr);
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON) {
+ if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2SoftwareInitiated) {
+ PcieInitiateSoftwareGen2 (PortId, NbConfigPtr);
+ }
+ PcieAsmpEnableOnPort (PortId, (UINT8)pPcieConfig->PortConfiguration[PortId].PortAspm, NbConfigPtr);
+ }
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70 , AccessS3SaveWidth32, (UINT32)~BIT12, 0, NbConfigPtr); //PCIE should not ignore malformed packet error or ATS request
+ if (pPcieConfig->PortConfiguration[PortId].PortCompliance == OFF &&
+ pPcieConfig->PortConfiguration[PortId].PortHotplug == OFF &&
+ pPcieConfig->CoreSetting[CoreId].PowerOffUnusedLanes == ON) {
+ PcieLibPowerOffPortLanes (PortId, LinkWidth, NbConfigPtr);
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitPorts Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Late init PCIE Cores. Core level feature/power management etc.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateInitCores (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ CORE CoreId;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitCores Enter\n"));
+ Status = AGESA_SUCCESS;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Init CoreId [%d]\n", CoreId));
+ if (pPcieConfig->CoreSetting[CoreId].PowerOffPllInL1 == ON) {
+ PcieLibEnablePllPowerOffInL1 (CoreId, pConfig);
+ }
+ if (pPcieConfig->CoreSetting[CoreId].PowerOffPll == ON) {
+ PcieLibPowerOffPll (CoreId, pConfig);
+ }
+ PcieLibMiscLateCoreSetting (CoreId, pConfig);
+ PcieLibManageTxClock (CoreId, pConfig);
+ PcieLibManageLclkClock (CoreId, pConfig);
+ }
+#ifndef VC1_SUPPORT_DISABLE
+ if (NB_SBDFO == 0 && pPcieConfig->PcieConfiguration.NbSbVc1 == ON) {
+ PcieNbSbSetupVc (pConfig);
+ }
+#endif
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitCores Exit\n"));
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Set up NB-SB virtual channel for audio traffic
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieNbSbSetupVc (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 VCStatus;
+ PCI_ADDR Port;
+
+ Port = PcieLibGetPortPciAddress (8, pConfig);
+ if (PcieSbSetupVc (pConfig) == AGESA_SUCCESS) {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG124, AccessS3SaveWidth8, 0x01, 0, pConfig);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG130, AccessS3SaveWidth32, (UINT32)~(BIT24 + BIT25 + BIT26), 0xFE + BIT24, pConfig);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG130, AccessS3SaveWidth32, 0xffffffff, BIT31, pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG134, AccessWidth32, &VCStatus, pConfig);
+ } while (VCStatus & BIT17);
+ PcieSbEnableVc (pConfig);
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Late common Port Init
+ *
+ *
+ * @param[in] PortId Port Id
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ Status = AGESA_SUCCESS;
+
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Initiate SW Gen2 switch
+ *
+ *
+ *
+ * @param[in] PortId Port Id.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieInitiateSoftwareGen2 (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 LinkSpeedCap;
+ UINT8 PcieCapPtr;
+ UINT8 SecondaryBus;
+ UINT32 Value;
+ UINT32 Counter;
+ PCI_ADDR Ep;
+ PCI_ADDR Port;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitiateSoftwareGen2 PortId[%d] Enter\n", PortId));
+ Counter = 5000;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG19, AccessWidth8, &SecondaryBus, pConfig);
+ Ep.AddressValue = 0;
+ Ep.Address.Bus = SecondaryBus;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE] SecondaryBus = 0x%x \n", SecondaryBus));
+ PcieCapPtr = LibNbFindPciCapability (Ep.AddressValue, PCIE_CAP_ID, pConfig);
+ LibNbPciRead (Ep.AddressValue | (PcieCapPtr + 0xC), AccessWidth8, &LinkSpeedCap, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE] PcieCapPtr = 0x%x \n", PcieCapPtr));
+ if ((LinkSpeedCap & 0xf) < 2) {
+ return;
+ }
+ PcieLibSetLinkMode (PortId, PcieLinkModeGen2, pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA4 , AccessS3SaveWidth32, (UINT32)~(BIT18), BIT18 , pConfig);
+ do {
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE);
+ LibNbPciIndexRead (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA5, AccessWidth32, &Value, pConfig);
+ } while ((UINT8)Value != 0x10 && Counter-- != 0);
+ LibNbPciIndexRead (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA4, AccessWidth32, &Value, pConfig);
+ if ((Value & BIT24) != 0) {
+ //Initiate link speed change
+ LibNbPciIndexRMW (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA4, AccessS3SaveWidth32, ((UINT32)~BIT7), BIT7, pConfig);
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitiateSoftwareGen2 Exit\n"));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Validate input parameters configuration for PCie Late Init call.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLateValidateConfiguration (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ NB_INFO NbInfo;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateValidateConfiguration Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ if (pPcieConfig == NULL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, pConfig);
+ CIMX_ASSERT (FALSE);
+ return AGESA_FATAL;
+ }
+ if (pPcieConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) {
+ PcieLibInitializer (pConfig);
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateValidateConfiguration Exit\n"));
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PcieValidatePortState
+ * Port disable or port visibility control
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieValidatePortState (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = AGESA_SUCCESS;
+ PcieLibUnHidePorts (NbConfigPtr);
+ PcieLibValidatePortStateInit (NbConfigPtr);
+ PcieForcePortsVisibleOrDisable (NbConfigPtr);
+ PcieLibHidePorts (NbConfigPtr);
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PciePortsVisibleOrDisable
+ * Set ports always visible or disable based on input parameter
+ *
+ *
+ *
+* @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieForcePortsVisibleOrDisable (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ PORT PortId;
+ PCI_ADDR Port;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, NbConfigPtr)) {
+ Port = PcieLibGetPortPciAddress (PortId, NbConfigPtr);
+ if (pPcieConfig->PortConfiguration[PortId].ForcePortDisable == ON ) {
+ pPcieConfig->PortConfiguration[PortId].PortPresent = OFF;
+ pPcieConfig->PortConfiguration[PortId].PortDetected = OFF;
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible == ON) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~BIT19, BIT19, NbConfigPtr);
+ pPcieConfig->PortConfiguration[PortId].PortPresent = ON;
+ pPcieConfig->PortConfiguration[PortId].PortDetected = ON;
+ }
+ LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG01, AccessWidth32, (UINT32*)&pPcieConfig->PortConfiguration[PortId], NbConfigPtr);
+ }
+ }
+}
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c
new file mode 100644
index 0000000000..8b1782e7bb
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c
@@ -0,0 +1,486 @@
+/**
+ * @file
+ *
+ * PCIe silicon specific functions library.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc Initialization in late init
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+PcieLibLateInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ PORT PortId;
+ PCIE_CONFIG *pPcieConfig;
+ PCI_ADDR ClkPciAddress;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ //Restore general setting in scratch
+ LibNbEnableClkConfig (pConfig);
+ LibNbPciRead (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig);
+ LibNbDisableClkConfig (pConfig);
+ // Restore Core setting from scratch
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+// if (PcieLibIsCoreAccessible (CoreId, pConfig) && pPcieConfig->CoreSetting[CoreId].CoreDisabled != ON ) {
+ UINT32 CoreAddress;
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ LibNbPciIndexRead (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ NB_BIFNB_REG01 | CoreAddress,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->CoreSetting[CoreId],
+ pConfig
+ );
+// } else {
+// pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON;
+// }
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Core Setting CoreId %d Setting %x Enter\n", CoreId, (UINT32)(pPcieConfig->CoreSetting[CoreId])));
+ }
+ // Restore port Setting from scratch
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig)) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ //Reload port configuration from scratch register
+ LibNbPciIndexRead (
+ Port.AddressValue | NB_BIF_INDEX,
+ NB_BIFNBP_REG01,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->PortConfiguration[PortId],
+ pConfig
+ );
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig);
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Port setting PortId %d Setting %x Enter\n", PortId, (UINT32)(pPcieConfig->PortConfiguration[PortId])));
+ } else {
+ *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId]) = 0;
+ *((UINT32*)&pPcieConfig->PortConfiguration[PortId]) = 0;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc Initialization in validate port state
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+VOID
+PcieLibValidatePortStateInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ PORT PortId;
+ UINT32 PortAlwaysVisible;
+ UINT32 ForcePortDisable;
+ PCIE_CONFIG *pPcieConfig;
+ PCI_ADDR ClkPciAddress;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ //Restore general setting in scratch
+ LibNbEnableClkConfig (pConfig);
+ LibNbPciRead (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig);
+ LibNbDisableClkConfig (pConfig);
+ // Restore Core setting from scratch
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+// if (PcieLibIsCoreAccessible (CoreId, pConfig) && pPcieConfig->CoreSetting[CoreId].CoreDisabled != ON ) {
+ UINT32 CoreAddress;
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ LibNbPciIndexRead (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ NB_BIFNB_REG01 | CoreAddress,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->CoreSetting[CoreId],
+ pConfig
+ );
+// } else {
+// pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON;
+// }
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Core Setting CoreId %d Setting %x Enter\n", CoreId, (UINT32)(pPcieConfig->CoreSetting[CoreId])));
+ }
+ // Restore port Setting from scratch
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig)) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ PortAlwaysVisible = pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible;
+ ForcePortDisable = pPcieConfig->PortConfiguration[PortId].ForcePortDisable;
+ //Reload port configuration from scratch register
+ LibNbPciIndexRead (
+ Port.AddressValue | NB_BIF_INDEX,
+ NB_BIFNBP_REG01,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->PortConfiguration[PortId],
+ pConfig
+ );
+ pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible = PortAlwaysVisible;
+ pPcieConfig->PortConfiguration[PortId].ForcePortDisable = ForcePortDisable;
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig);
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Port setting PortId %d Setting %x Enter\n", PortId, (UINT32)(pPcieConfig->PortConfiguration[PortId])));
+ } else {
+ *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId]) = 0;
+ *((UINT32*)&pPcieConfig->PortConfiguration[PortId]) = 0;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable LCLK clock gating or shutdown LCLK clock banch if possible
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieLibManageLclkClock (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ UINT32 Mask;
+ PCI_ADDR ClkPciAddress;
+ UINT32 CoreAddress;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibManageLclkClock [CoreId %d] Enter \n", CoreId));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ ClkPciAddress = pConfig->NbPciAddress;
+ ClkPciAddress.Address.Function = 1;
+ LibNbEnableClkConfig (pConfig);
+
+ if (pPcieConfig->CoreSetting[CoreId].LclkClockGating == ON) {
+ ClkPciAddress.Address.Register = NB_CLK_REGE8;
+ Value = 0;
+ Mask = 0;
+ switch (CoreAddress) {
+ case GPP1_CORE:
+ ClkPciAddress.Address.Register = NB_CLK_REG94;
+ Mask = BIT16;
+ break;
+ case GPP2_CORE:
+ Value = BIT28;
+ break;
+ case GPP3a_CORE:
+ Value = BIT31;
+ break;
+ case GPP3b_CORE:
+ Value = BIT25;
+ break;
+ case SB_CORE:
+ ClkPciAddress.Address.Register = NB_CLK_REG94;
+ Mask = BIT24;
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ }
+ LibNbPciRMW (ClkPciAddress.AddressValue, AccessS3SaveWidth32, ~Mask, Value, pConfig);
+ }
+ if (pPcieConfig->CoreSetting[CoreId].LclkClockOff == ON) {
+ UINT8 ActiveCoreMap;
+ ActiveCoreMap = PcieLibGetActiveCoreMap (pConfig);
+ if ((ActiveCoreMap & (1 << CoreId)) == 0) {
+ //Core not active we can shutdown LCLK permanantly
+ CORE_INFO *pCoreInfo;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Shutdown LCKL clock\n"));
+ pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig);
+ ClkPciAddress.Address.Register = NB_CLK_REGE0;
+ pPcieConfig->CoreSetting[CoreId].CoreDisableStatus = ON;
+ // We have to setup Index for BIFNB to point out to SB core. After this point core registers no longer accesasable
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, 0x00 | SB_CORE, AccessS3SaveWidth32, 0xffffffff, 0x00, pConfig);
+ LibNbPciRMW (ClkPciAddress.AddressValue, AccessS3SaveWidth32, 0xffffffff, 1 << pCoreInfo->LclkOffOffset, pConfig);
+
+ Value = 0;
+ if (CoreAddress == GPP1_CORE) {
+ if ((ActiveCoreMap & 0xb) == 0 && !LibNbIsIommuEnabled (pConfig)) {
+ // Can shutdown master core
+ Value = 1 << pCoreInfo->LclkPermOffOffset;
+ }
+ } else {
+ Value = 1 << pCoreInfo->LclkPermOffOffset;
+ }
+ if (Value != 0) {
+ NbIommuDisconnectPcieCore (CoreId, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG27, AccessS3SaveWidth32, 0xffffffff, Value, pConfig);
+
+ }
+ }
+ }
+ LibNbDisableClkConfig (pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Power Off Pll for unused lanes.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieLibPowerOffPll (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 CoreAddress;
+ UINT32 PowerOfPllValue;
+ UINT32 PadsMap;
+ //UINT32 TxClockOffValue;
+ UINT32 PowerOfPllRegister;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ PowerOfPllValue = 0;
+ PadsMap = 0;
+ //TxClockOffValue = 0;
+ PowerOfPllRegister = NB_MISC_REG23;
+
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG65 | CoreAddress, AccessS3SaveWidth32, &PadsMap, pConfig);
+ if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) {
+ if ((PadsMap & 0xf0) == 0xf0) {
+ //Power Off PLL1
+ PowerOfPllValue |= (BIT1 | BIT3);
+ if ((PadsMap & 0x0f) == 0x0f && pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AABB) {
+ //Power Off PLL0
+ PowerOfPllValue |= (BIT0 | BIT2);
+ }
+ }
+ if (CoreAddress == GPP2_CORE) {
+ PowerOfPllValue <<= 8;
+ //TxClockOffValue = BIT1;
+ } else {
+ //TxClockOffValue = BIT0;
+ }
+ if ((UINT16)PadsMap != 0xffff) {
+ //TxClockOffValue = 0; //Do not disable TX clock in case any line is ON
+ }
+ }
+ if (CoreAddress == GPP3a_CORE ) {
+ if ((UINT16)PadsMap == 0x3F3F) {
+ PowerOfPllValue = BIT18 | BIT16;
+ //TxClockOffValue = BIT2;
+ }
+ }
+ if (CoreAddress == GPP3b_CORE ) {
+ PowerOfPllRegister = NB_MISC_REG2E;
+ if ((UINT16)PadsMap == 0x0F0F) {
+ PowerOfPllValue = BIT8 | BIT6;
+ //TxClockOffValue = BIT3;
+ }
+ }
+ //Power Off Pll
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, PowerOfPllRegister , AccessS3SaveWidth32, 0xffffffff, PowerOfPllValue, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Power off PLL CoreId %d, Value 0x%x\n", CoreId, PowerOfPllValue));
+ //Turn off TXCLK
+ //LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, TxClockOffValue, pConfig);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable TX clock gating or shutdown TX clock if possible
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer. *
+ */
+VOID
+PcieLibManageTxClock (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 CoreAddress;
+ UINT32 Value;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ if (pPcieConfig->CoreSetting[CoreId].TxClockGating == ON) {
+ switch (CoreAddress) {
+ case GPP1_CORE:
+ Value = BIT4;
+ break;
+ case GPP2_CORE:
+ Value = BIT5;
+ break;
+ case GPP3a_CORE:
+ Value = BIT6;
+ break;
+ case GPP3b_CORE:
+ Value = BIT24;
+ break;
+ case SB_CORE:
+ Value = BIT7;
+ break;
+ default:
+ Value = 0;
+ CIMX_ASSERT (FALSE);
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, Value, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessS3SaveWidth32, (UINT32)~BIT6, BIT6, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG11 | CoreAddress, AccessS3SaveWidth32, 0xfffffff0, 0x0C, pConfig);
+ }
+ if (pPcieConfig->CoreSetting[CoreId].TxClockOff == ON) {
+ UINT8 ActiveCoreMap;
+ ActiveCoreMap = PcieLibGetActiveCoreMap (pConfig);
+ if ((ActiveCoreMap & (1 << CoreId)) == 0) {
+ //Core not active we can shutdown TX clk permanantly
+ CORE_INFO *pCoreInfo;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Shutdown TX clock\n"));
+ pPcieConfig->CoreSetting[CoreId].CoreDisableStatus = ON;
+ pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, 1 << pCoreInfo->TxOffOffset, pConfig);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable Pll Power Down in L1.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer. *
+ */
+VOID
+PcieLibEnablePllPowerOffInL1 (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 Value;
+ UINT32 CoreAddress;
+ PORT PortId;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ if (pPcieConfig->CoreSetting[CoreId].DetectPowerOffPllInL1 == ON && !PciePllOffComatibilityTest (CoreId, pConfig)) {
+ return;
+ }
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) {
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) {
+ // set up max exit latency requirment for hotplug ports
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC1 , AccessS3SaveWidth32, 0xffffffff, 0xf, pConfig);
+ }
+ }
+ }
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ Value = BIT8;
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessS3SaveWidth32, (UINT32)~(BIT9 + BIT4), BIT3 + BIT0 + BIT12, pConfig);
+ if (CoreAddress == GPP3b_CORE || CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE) {
+ Value |= BIT3;
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG02 | CoreAddress, AccessS3SaveWidth32, 0xffffffff, Value, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc. core setting.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express- Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieLibMiscLateCoreSetting (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+//Lock
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ NB_BIFNB_REG10 | PcieLibGetCoreAddress (CoreId, pConfig),
+ AccessS3SaveWidth32,
+ 0xffffffff,
+ BIT0,
+ pConfig
+ );
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieLib.c
new file mode 100644
index 0000000000..2e91cb6c1a
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieLib.c
@@ -0,0 +1,1604 @@
+/**
+ * @file
+ *
+ * PCIe silicon specific functions library.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+UINT32
+PcieLibGetCoreConfiguration (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieLibValidateGfxConfig (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+CORE_INFO CoreInfoTable[] = {
+ { // GPP1_CORE_ID = 0 It is GFX Core (GPP1 Core)
+ GPP1_CORE, // Core Selector
+ (BIT2 | BIT3), // Port ID Mask. Defines what ports belongs
+ NB_MISC_REG08,
+ NB_MISC_REG28, // De-emphasis register
+ NB_MISC_REG26, // Strap control register
+ 28, // Strap bit offset
+ NB_CLK_REGF0,
+ NB_MISC_REG35, 26, // TX drive strength and offset
+ NB_MISC_REG35, 18, // TX half swing
+ NB_MISC_REG36, 24, // TX zero deemphasis
+ 0,
+ 28,
+ 23
+ },
+ { // GPP2_CORE_ID = 1 It is GFX2 Core (GPP2 Core)
+ GPP2_CORE, // Core Selector
+ (BIT11 | BIT12), // Port ID Mask. Defines what ports belongs
+ NB_MISC_REG08,
+ NB_MISC_REG27, // De-emphasis register
+ NB_MISC_REG26, // Strap control register
+ 29, // Strap bit offset
+ NB_CLK_REGF0,
+ NB_MISC_REG35, 28, // TX drive strength and offset
+ NB_MISC_REG35, 19, // TX half swing
+ NB_MISC_REG36, 26, // TX zero deemphasis
+ 1,
+ 29,
+ 24
+ },
+ { // GPP3a_CORE_ID = 2 It is GPP Core (GPP3a Core)
+ GPP3a_CORE, // Core Selector
+ (BIT4 | BIT5 | BIT6 | BIT7 | BIT9 | BIT10), // Port ID Mask. Defines what ports belongs
+ NB_MISC_REG08,
+ NB_MISC_REG28, // De-emphasis register
+ NB_MISC_REG26, // Strap control register
+ 30, // Strap bit offset
+ NB_CLK_REGF4,
+ NB_MISC_REG35, 30, // TX drive strength and offset
+ NB_MISC_REG35, 20, // TX half swing
+ NB_MISC_REG36, 28, // TX zero deemphasis
+ 2,
+ 30,
+ 25
+ },
+ { // GPP3b_CORE_ID = 3 It is GPP2 Core (GPP3b Core)
+ GPP3b_CORE, // Core Selector
+ (BIT13), // Port ID Mask. Defines what ports belongs
+ NB_MISC_REG2A,
+ NB_MISC_REG2D, // De-emphasis register
+ NB_MISC_REG2D, // Strap control register
+ 21, // Strap bit offset
+ NB_CLK_REGF4,
+ NB_MISC_REG2C, 4, // TX drive strength and offset
+ NB_MISC_REG2C, 2, // TX half swing
+ NB_MISC_REG2B, 10, // TX zero deemphasis
+ 3,
+ 31,
+ 26
+ },
+ { // SB_CORE_ID = 4 It is SB Core
+ SB_CORE, // Core Selector
+ (BIT8), // Port ID Mask. Defines what ports belongs
+ NB_MISC_REG08,
+ NB_MISC_REG6F, // De-emphasis register
+ 0x0,
+ 0x0,
+ 0x0,
+ NB_MISC_REG68, 8, // TX drive strength and offset
+ NB_MISC_REG67, 27, // TX half swing
+ NB_MISC_REG68, 20, // TX zero deemphasis
+ 0xff,
+ 0xff,
+ 0xff
+ }
+};
+
+
+PORT_INFO pGfxPortFullA = {
+ PcieLinkWidth_x16, 0, 0
+};
+
+PORT_INFO pGfxPortA = {
+ PcieLinkWidth_x8, 0, 96
+};
+
+PORT_INFO pGfxPortB = {
+ PcieLinkWidth_x8, 8, 96
+};
+
+PORT_INFO pGpp420000[] = {
+ {PcieLinkWidth_x4, 0, 56},
+ {PcieLinkWidth_x2, 4, 28}
+};
+
+PORT_INFO pGpp411000[] = {
+ {PcieLinkWidth_x4, 0, 56},
+ {PcieLinkWidth_x1, 4, 14},
+ {PcieLinkWidth_x1, 5, 14}
+};
+
+PORT_INFO pGpp222000[] = {
+ {PcieLinkWidth_x2, 0, 28},
+ {PcieLinkWidth_x2, 2, 28},
+ {PcieLinkWidth_x2, 4, 28}
+};
+
+PORT_INFO pGpp221100[] = {
+ {PcieLinkWidth_x2, 0, 28},
+ {PcieLinkWidth_x2, 2, 28},
+ {PcieLinkWidth_x1, 4, 14},
+ {PcieLinkWidth_x1, 5, 14}
+};
+
+PORT_INFO pGpp211110[] = {
+ {PcieLinkWidth_x2, 0, 28},
+ {PcieLinkWidth_x1, 2, 14},
+ {PcieLinkWidth_x1, 3, 14},
+ {PcieLinkWidth_x1, 4, 14},
+ {PcieLinkWidth_x4, 0, 0 }, //Dummy entry
+ {PcieLinkWidth_x1, 5, 14}
+};
+
+PORT_INFO pGpp111111[] = {
+ {PcieLinkWidth_x1, 0, 14},
+ {PcieLinkWidth_x1, 1, 14},
+ {PcieLinkWidth_x1, 2, 14},
+ {PcieLinkWidth_x1, 3, 14},
+ {PcieLinkWidth_x4, 0, 0 }, //Dummy entry
+ {PcieLinkWidth_x1, 4, 14},
+ {PcieLinkWidth_x1, 5, 14}
+};
+
+GPP_CFG_INFO GppCfgInfoTable[] = {
+ {pGpp420000, 0xff50fff4},
+ {pGpp411000, 0xf650fff4},
+ {pGpp222000, 0xff60f5f4},
+ {pGpp221100, 0xf760f5f4},
+ {pGpp211110, 0xf97065f4},
+ {pGpp111111, 0xfA907654}
+};
+
+CONST PORT_STATIC_INFO PortInfoTable[] = {
+//Training Reversal Deemp Mapping Hotplug Offset
+ {4 , 3, 0 , 4 , 0 }, //2
+ {5 , 4, 1 , 8 , 8 }, //3
+ {21, 7, 2 , 12 , 0 }, //4
+ {22, 8, 3 , 16 , 8 }, //5
+ {23, 9, 4 , 20 , 16 }, //6
+ {24, 10, 5 , 24 , 0xFF }, //7
+ {20, 0, 1 , 0xFF , 0xFF }, //8
+ {25, 11, 6 , 28 , 0xFF }, //9
+ {26, 12, 7 , 0 , 0xFF }, //10
+ {6 , 5, 30, 4 , 16 }, //11
+ {7 , 6, 31, 8 , 24 }, //12
+ {4 , 25, 5 , 12 , 24 } //13
+};
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Port Training Control
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] Operation Release or Hold training
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+VOID
+PcieLibPortTrainingControl (
+ IN PORT PortId,
+ IN PCIE_LINK_TRAINING Operation,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ CORE_INFO *pCoreInfo;
+ PORT_STATIC_INFO *pStaticPortInfo;
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig);
+ pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig);
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ pCoreInfo->TrainingRegister,
+ AccessWidth32,
+ ~(1 << pStaticPortInfo->TrainingAddress),
+ (Operation == PcieLinkTrainingHold)?(1 << pStaticPortInfo->TrainingAddress):0,
+ pConfig
+ );
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get PCI address of Port.
+ * Function return pcie Address based on port mapping and core configuration.
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+PCI_ADDR
+PcieLibGetPortPciAddress (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR Port;
+ UINT32 RemapEnable;
+ UINT32 RemapValue;
+ PORT_STATIC_INFO *pPortStaticInfo;
+
+ RemapEnable = 0;
+ RemapValue = 0;
+ pPortStaticInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig);
+ Port.AddressValue = pConfig->NbPciAddress.AddressValue;
+
+ LibNbPciIndexRead (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ NB_MISC_REG20,
+ AccessWidth32,
+ &RemapEnable,
+ pConfig
+ );
+ if (pPortStaticInfo->MappingAddress != 0xff && RemapEnable & BIT0) {
+ LibNbPciIndexRead (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ (PortId > 9)? NB_MISC_REG21:NB_MISC_REG20,
+ AccessWidth32,
+ &RemapValue,
+ pConfig
+ );
+ RemapValue = (RemapValue >> pPortStaticInfo->MappingAddress) & 0xf;
+ }
+ if (RemapValue == 0) {
+ RemapValue = PortId;
+ }
+ Port.Address.Device = RemapValue;
+ return Port;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Core register selector.
+ * Function return selector to access BIFNB register space for selected core
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+UINT32
+PcieLibGetCoreAddress (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ return PcieLibGetCoreInfo (CoreId, pConfig)->CoreSelector;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Core Id
+ * Function return PCIE core ID base on Port ID
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ * @retval Core ID.
+ */
+CORE
+PcieLibGetCoreId (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE_INFO *pCoreInfoTable = (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[0], NULL);
+ CORE CoreId;
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ if (pCoreInfoTable[CoreId].PortIdBitMap & (1 << PortId)) {
+ break;
+ }
+ }
+ return CoreId;
+}
+
+/*
+INDIRECT_REG_ENTRY
+STATIC
+PcieMiscInitTable[] = {
+ {
+ NB_MISC_REG20,
+ (UINT32)~BIT1,
+ 0x0
+ }, //enable static device remapping by default
+ {
+ NB_MISC_REG22,
+ 0xffffffff,
+ BIT27
+ }, //[10]CMGOOD_OVERRIDE for all 5 pcie cores.
+ {
+ NB_MISC_REG6B,
+ 0xffffffff,
+ (UINT32) (0x1f << 27)
+ }, //[13][12]Turn Off Offset Cancellation
+ {
+ NB_MISC_REG37,
+ (UINT32)~(BIT11 + BIT12 + BIT13),
+ 0x0
+ }, //[14][13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG67,
+ (UINT32)~(BIT26 + BIT10 + BIT11),
+ BIT11
+ }, //[13]Disables Rx Clock gating in CDR
+ //[16]Sets Electrical Idle Threshold
+ {
+ NB_MISC_REG2C,
+ (UINT32)~(BIT10),
+ 0x0
+ }, //[13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG2A,
+ (UINT32)~(BIT17 + BIT16),
+ BIT17
+ }, //[16]Sets Electrical l Idle Threshold
+ {
+ NB_MISC_REG32,
+ (UINT32)~(0x3F << 20),
+ (UINT32) (0x2A << 20)
+ } //[17][16]Sets Electrical Idle Threshold
+};
+*/
+
+
+
+UINT8 GppConfigTable[] = {
+ 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB
+};
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set Core Configuration.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieLibSetCoreConfiguration (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 LaneReversalValue;
+ PORT PortId;
+ PCIE_CONFIG *pPcieConfig;
+ CORE_INFO *pCoreInfo;
+ CORE CoreAddress;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration CoreId = %d Configuration = 0x%x Enter\n", CoreId, pPcieConfig->CoreConfiguration[CoreId]));
+ pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ LaneReversalValue = 0;
+ PcieLibCoreReset (CoreId, PcieCoreResetAllAssert, pConfig);
+ PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig);
+ //Setup GFX/GFX2 core configuration
+ if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) {
+ if (pPcieConfig->CoreConfiguration[CoreId] == GFX_CONFIG_AABB) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT8:BIT9, pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0);
+ }
+ if (pPcieConfig->CoreSetting[CoreId].RefClockInput == ON) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG6C, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT9:BIT31, pConfig);
+ }
+ }
+ //Setup GPP core configuration
+ if (CoreAddress == GPP3a_CORE) {
+ UINT32 Mux;
+ UINT8 *pGppConfigTable;
+
+ Mux = 0;
+ pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL);
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ NB_MISC_REG67, AccessWidth32,
+ 0xfffffff0,
+ (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]],
+ pConfig
+ );
+ switch (pPcieConfig->CoreConfiguration[CoreId]) {
+ case GPP_CONFIG_GPP420000:
+ Mux = (pPcieConfig->PortConfiguration[6].PortReversed == ON)?0xF05BA00:0x055B000;
+ break;
+ case GPP_CONFIG_GPP411000:
+ Mux = 0x215B400;
+ break;
+ case GPP_CONFIG_GPP222000:
+ case GPP_CONFIG_GPP211110:
+ Mux = (pPcieConfig->PortConfiguration[4].PortReversed == ON)?0xFFF0AAA:0xFF0BAA0;
+ break;
+ case GPP_CONFIG_GPP221100:
+ Mux = 0x215B400;
+ break;
+ case GPP_CONFIG_GPP111111:
+ Mux = 0x2AA3554;
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ }
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, pConfig);
+ }
+ PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig);
+ PcieLibCoreReset (CoreId, PcieCoreResetAllDeassert, pConfig);
+ //Setup lane reversal
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig)) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON &&
+ pPcieConfig->PortConfiguration[PortId].PortReversed == ON &&
+ (pCoreInfo->PortIdBitMap & (1 << PortId)) != 0) {
+ PORT_STATIC_INFO *pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig);
+ LaneReversalValue |= (1 << (pStaticPortInfo->ReversalAddress));
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Port reversed Port Id %d Native Id %d, Reversal Address %d \n", PortId, PcieLibNativePortId (PortId, pConfig), pStaticPortInfo->ReversalAddress));
+ }
+ }
+ }
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ (CoreAddress == GPP3b_CORE) ? NB_MISC_REG2D : NB_MISC_REG27,
+ AccessWidth32, 0xffffffff,
+ LaneReversalValue,
+ pConfig
+ );
+ //Setup performance mode
+ if (pPcieConfig->CoreSetting[CoreId].PerformanceMode == ON) {
+ UINT32 RegisterAddress;
+ switch (CoreAddress) {
+ case GPP1_CORE:
+ RegisterAddress = NB_MISC_REG33;
+ break;
+ case GPP2_CORE:
+ RegisterAddress = NB_MISC_REG22;
+ break;
+ default:
+ RegisterAddress = 0;
+ break;
+ }
+ if (RegisterAddress != 0) {
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress , AccessWidth32, 0xfffffC00, 0xB5, pConfig);
+ }
+ }
+ //Setup Tx Drive Strength
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ pCoreInfo->TxDriveStrengthRegister ,
+ AccessWidth32,
+ ~(0x3 << pCoreInfo->TxDriveStrengthOffset),
+ pPcieConfig->CoreSetting[CoreId].TxDriveStrength << pCoreInfo->TxDriveStrengthOffset,
+ pConfig
+ );
+ //Setup Tx half swing
+ if (pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode == ON) {
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ pCoreInfo->TxHalfSwingRegister,
+ AccessWidth32,
+ ~(0x1 << pCoreInfo->TxHalfSwingOffset),
+ 0x0,
+ pConfig
+ );
+ // Setup half swing deemphasis
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ pCoreInfo->TxHalfSwingDeepmhasisRegister ,
+ AccessWidth32,
+ ~(0x3 << pCoreInfo->TxHalfSwingDeepmhasisOffset),
+ 0x0,
+ pConfig
+ );
+ }
+ //Finalize straps for this core
+ PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig);
+ PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration Exit\n"));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Core Configuration
+ * Function return GPPSB/GFX/GFX2 core configuration.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+UINT32
+PcieLibGetCoreConfiguration (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 CoreConfiguration;
+ UINT32 Value;
+ CORE CoreAddress;
+
+ CoreConfiguration = 0,
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (Core = 0x%x) Enter\n", CoreAddress));
+ if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) {
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, &Value, pConfig);
+ CoreConfiguration = (Value & ((CoreAddress == GPP1_CORE) ? BIT8:BIT9))? GFX_CONFIG_AABB:GFX_CONFIG_AAAA;
+ } else {
+ if (CoreAddress == GPP3a_CORE) {
+ UINT8 *pGppConfigTable;
+ pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL);
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, &Value, pConfig);
+ while (pGppConfigTable[CoreConfiguration] != (Value & 0xf)) {
+ CoreConfiguration++;
+ }
+ }
+ }
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (CoreConfiguration = 0x%x) Exit\n", CoreConfiguration));
+ return CoreConfiguration;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Return link misc information (max link width, current link width, lane 0 map)
+ *
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+LINK_INFO
+PcieLibGetPortLinkInfo (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ PCI_ADDR Port;
+ PORT_INFO *pPortInfo;
+ LINK_INFO LinkInfo = {0, 0, 0};
+
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ pPortInfo = PcieLibGetPortInfo (PortId, pConfig);
+//Read current link width
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig);
+ Value = (Value >> 4) & 0xf;
+ LinkInfo.LinkWidth = (UINT8)Value;
+ LinkInfo.MaxLinkWidth = pPortInfo->MaxLinkWidth;
+ LinkInfo.Line0Offset = pPortInfo->Line0Offset;
+// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d LinkWidth 0x%x MaxLinkWidth 0x%x Line0Offset %d\n", PortId, LinkInfo.LinkWidth, LinkInfo.MaxLinkWidth,LinkInfo.Line0Offset));
+ return LinkInfo;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if port in lane reversed configuration.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+BOOLEAN
+PcieLibIsPortReversed (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ BOOLEAN Result;
+ UINT32 Value;
+ PCIE_CONFIG *pPcieConfig;
+ PCI_ADDR Port;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG50, AccessWidth32, &Value, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortReversed == ON || (Value & BIT0) != 0) {
+ Result = TRUE;
+ } else {
+ Result = FALSE;
+ }
+ return Result;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if core id valid for current silicon
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+BOOLEAN
+PcieLibIsValidCoreId (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 CoreAddress;
+ NB_INFO NbInfo;
+
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ if (CoreAddress == GPP3b_CORE) {
+ if (NbInfo.Type == NB_RD890 || NbInfo.Type == NB_SR5690) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ if (CoreAddress == GPP2_CORE && (NbInfo.Type == NB_RD780 || NbInfo.Type == NB_RX780 || NbInfo.Type == NB_SR5650 || NbInfo.Type == NB_990X || NbInfo.Type == NB_970)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if port Id valid for current core configuration
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+BOOLEAN
+PcieLibIsValidPortId (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ NB_INFO NbInfo;
+
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ if (!PcieLibIsValidCoreId (CoreId, pConfig)) {
+ return FALSE;
+ }
+ if ((PortId == 3 || PortId == 12) && PcieLibGetCoreConfiguration (CoreId, pConfig) != GFX_CONFIG_AABB) {
+ return FALSE;
+ }
+ if (PortId == 3 && NbInfo.Type == NB_970) {
+ return FALSE;
+ }
+ if (PortId == 12 && NbInfo.Type == NB_SR5670) {
+ return FALSE;
+ }
+ if (PortId == 13 || PortId == 8) {
+ return TRUE;
+ } else {
+ return (PcieLibNativePortId (PortId, pConfig) == 0xf)?FALSE:TRUE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set Link mode. Gen1/Gen2/Gen2-Advertize
+ *
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] Operation Link Mode
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+
+VOID
+PcieLibSetLinkMode (
+ IN PORT PortId,
+ IN PCIE_LINK_MODE Operation,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR Port;
+ UINT8 LinkSpeed;
+ UINT32 LinkDeemphasisMask;
+ UINT32 LinkDeemphasisValue;
+ UINT32 RegA4Value;
+ UINT32 RegA2Value;
+ UINT32 RegC0Value;
+ CORE_INFO *pCoreInfo;
+ PORT_STATIC_INFO *pStaticPortInfo;
+ PCIE_CONFIG *pPcieConfig;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetLinkMode PortId %d Operation %d Enter\n", PortId, Operation));
+ LinkSpeed = 2;
+ RegA4Value = BIT29 + BIT0;
+ RegA2Value = 0;
+ RegC0Value = 0;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig);
+ pCoreInfo = PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig);
+
+ LinkDeemphasisValue = pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis << pStaticPortInfo->DeemphasisAddress;
+ LinkDeemphasisMask = ~(1 << pStaticPortInfo->DeemphasisAddress);
+
+ if (Operation == PcieLinkModeGen1 || Operation == PcieLinkModeGen2AdvertizeOnly) {
+ RegC0Value = BIT15;
+ RegA2Value = BIT13;
+ if (Operation == PcieLinkModeGen1) {
+ RegA4Value = 0;
+ LinkSpeed = 1;
+ LinkDeemphasisValue = 0;
+ }
+ }
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " pCoreInfo->DeemphasisRegister %x pStaticPortInfo->DeemphasisAddress %x LinkDeemphasisMask %x, LinkDeemphasisValue %x\n", pCoreInfo->DeemphasisRegister, pStaticPortInfo->DeemphasisAddress, LinkDeemphasisMask, LinkDeemphasisValue));
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA4 , AccessWidth32, (UINT32)~(BIT0 + BIT29), RegA4Value , pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, pCoreInfo->DeemphasisRegister, AccessWidth32, LinkDeemphasisMask, LinkDeemphasisValue , pConfig);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, LinkSpeed, pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0 , AccessWidth32, (UINT32)~(BIT15), RegC0Value , pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2 , AccessWidth32, (UINT32)~(BIT13), RegA2Value , pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Request PCIE reset to be executed
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLibRequestPciReset (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ SCRATCH_1 Scratch;
+
+ Status = AGESA_UNSUPPORTED;
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ if (Scratch.ResetCount == 0xf) {
+ Scratch.ResetCount = 0;
+ }
+ if (Scratch.ResetCount < 5) {
+ ++Scratch.ResetCount;
+ LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ if (LibNbCallBack (PHCB_AmdGeneratePciReset, WARM_RESET , pConfig) != AGESA_SUCCESS) {
+ LibNbIoRMW (0xCF9, AccessWidth8, 0, 0x6, pConfig);
+ }
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Control Core Reset
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] Operation Assert/Deassert/Check core reset
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+PCI_CORE_RESET
+PcieLibCoreReset (
+ IN CORE CoreId,
+ IN PCI_CORE_RESET Operation,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+ UINT32 CalibrationReset;
+ UINT32 GlobalReset;
+ UINT32 RegisterAddress;
+ UINT32 CoreAddress;
+
+ RegisterAddress = NB_MISC_REG08;
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ switch (CoreAddress) {
+ case GPP3b_CORE:
+ RegisterAddress = NB_MISC_REG2A; // break missing and it is not an error.
+ case GPP1_CORE:
+ CalibrationReset = BIT14;
+ GlobalReset = BIT15;
+ break;
+ case GPP2_CORE:
+ CalibrationReset = BIT12;
+ GlobalReset = BIT13;
+ break;
+ case GPP3a_CORE:
+ CalibrationReset = BIT30;
+ GlobalReset = BIT31;
+ break;
+ default:
+ return PcieCoreResetAllDeassert;
+ }
+ switch (Operation) {
+ case PcieCoreResetAllDeassert:
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~CalibrationReset, 0x0, pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, 0);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~GlobalReset, 0x0, pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0);
+ break;
+ case PcieCoreResetAllAssert:
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, 0xffffffff, CalibrationReset | GlobalReset, pConfig);
+ break;
+ case PcieCoreResetAllCheck:
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, &Value, pConfig);
+ Operation = (Value & (CalibrationReset | GlobalReset))?PcieCoreResetAllAssert:PcieCoreResetAllDeassert;
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ }
+ return Operation;
+}
+
+UINT8 GfxLineMapTable[] = {
+ 0x00, 0x01, 0x01, 0x03, 0x0f, 0x00, 0xFF
+};
+UINT8 GppLineMapTable[] = {
+ 0x00, 0x01, 0x03, 0x0F
+};
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Power off port lanes.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] Width Port Link Width.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+VOID
+PcieLibPowerOffPortLanes (
+ IN PORT PortId,
+ IN PCIE_LINK_WIDTH Width,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ LINK_INFO LinkInfo;
+ UINT32 PowerOffPads;
+ UINT32 CoreAddress;
+ UINT8* pLineMapTable;
+ UINT16 MaxLaneBitMap;
+ UINT16 LaneBitMap;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes (PortId = %d, Width = %d) Enter\n", PortId, Width));
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ LinkInfo = PcieLibGetPortLinkInfo (PortId, pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) {
+ pLineMapTable = &GfxLineMapTable[0];
+ LinkInfo.Line0Offset /= 2;
+ } else {
+ pLineMapTable = &GppLineMapTable[0];
+ }
+ pLineMapTable = (UINT8*)FIX_PTR_ADDR (pLineMapTable, NULL);
+ LaneBitMap = pLineMapTable[Width];
+ MaxLaneBitMap = pLineMapTable[LinkInfo.MaxLinkWidth];
+ if (PcieLibIsPortReversed (PortId, pConfig)) {
+ LaneBitMap = (UINT16)LibNbBitReverse ((UINT32)LaneBitMap, LibAmdBitScanForward (MaxLaneBitMap), LibAmdBitScanReverse (MaxLaneBitMap));
+ }
+ PowerOffPads = (MaxLaneBitMap ^ LaneBitMap) << LinkInfo.Line0Offset;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Pads %x Exit\n", PowerOffPads));
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG65 | CoreAddress, AccessWidth32, 0xffffffff, PowerOffPads | (PowerOffPads << 8), pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes Exit\n"));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Hide Unused Ports
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieLibHidePorts (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 PresentPortMask;
+ UINT32 DetectedPortMask;
+ UINT32 HotplugPortMask;
+ UINT32 Value;
+ PORT PortId;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ PresentPortMask = 0;
+ DetectedPortMask = 0;
+ HotplugPortMask = 0;
+ // Hide SB Port
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, 0, pConfig);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) {
+ PCI_ADDR Port;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON ) {
+ DetectedPortMask |= 1 << Port.Address.Device;
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) {
+ HotplugPortMask |= 1 << Port.Address.Device;
+ }
+ PresentPortMask |= 1 << Port.Address.Device;
+ }
+ }
+
+ if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) {
+ Value = PresentPortMask;
+ } else {
+ Value = DetectedPortMask | HotplugPortMask;
+ }
+ //CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Present Port 0x%x Visible Ports 0x%xExit\n",PresentPortMask,VisiblePortMask));
+ Value = (~((Value & (0xFC)) + ((Value & 0x3E00) << 7))) & 0x1F00FC;
+ // Hide GFX/GFX2/GPP/GPP2 Ports
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, 0xffffffff, Value, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Exit\n"));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * UnHide all PCIE Ports
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+VOID
+PcieLibUnHidePorts (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, (UINT32)~0x1F00FCul, 0, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, BIT6, pConfig);
+}
+
+
+
+PCIE_DEFAULT_CONFIG PcieDefaultConfig = {
+ {0, 1, 0, 0},
+ {
+ {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP1
+ {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP2
+ {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3a
+ {0, 1, 1, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3b
+ {0, 1, 0, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 0, 0, 0} //SB
+ },
+ (BIT2 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9 + BIT10 + BIT11 + BIT13) | (BIT3 + BIT12),
+ 0,
+ 2,
+ 0,
+ 60,
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for all NB.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdPcieInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ Status = LibNbApiCall (PcieLibInitializer, ConfigPtr);
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize default PCIE_CONFIG setting
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLibInitializer (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ PCIE_CONFIG *pPcieConfig;
+ PCIE_DEFAULT_CONFIG *pPcieDefaultConfig;
+ AMD_NB_CONFIG_BLOCK *ConfigPtr;
+ PORT PortId;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ if (pPcieConfig == NULL) {
+ return AGESA_WARNING;
+ }
+ if (pPcieConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) {
+ return AGESA_SUCCESS;
+ }
+ ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig);
+ LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)&(pPcieConfig->sHeader));
+ pPcieConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER;
+ pPcieDefaultConfig = (PCIE_DEFAULT_CONFIG*)FIX_PTR_ADDR (&PcieDefaultConfig, NULL);
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ pPcieConfig->CoreSetting[CoreId] = pPcieDefaultConfig->CoreSetting[CoreId];
+ }
+ pPcieConfig->PcieConfiguration = pPcieDefaultConfig->PcieConfiguration;
+ if (ConfigPtr->PlatformType == DesktopPlatform) {
+ pPcieConfig->PcieConfiguration.NbSbVc1 = ON;
+ }
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB;
+ }
+ pPcieConfig->CoreConfiguration[2] = PcieLibGetCoreConfiguration (2, pConfig);
+ pPcieConfig->ReceiverDetectionPooling = pPcieDefaultConfig->ReceiverDetectionPooling;
+ pPcieConfig->ResetToTrainingDelay = pPcieDefaultConfig->ResetToTrainingDelay;
+ pPcieConfig->ExtPortConfiguration[8].PortL1ImmediateACK = ON;
+ pPcieConfig->TrainingToLinkTestDelay = pPcieDefaultConfig->TrainingToLinkTestDelay;
+ pPcieConfig->DeviceInitMaskS1 = pPcieDefaultConfig->DeviceInitMaskS1;
+ pPcieConfig->DeviceInitMaskS2 = pPcieDefaultConfig->DeviceInitMaskS2;
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Exit\n"));
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Validate Gfx Core Configuration
+ *
+ *
+ *
+ *
+ *
+ */
+AGESA_STATUS
+PcieLibValidateGfxConfig (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibValidateGfxConfig Enter\n"));
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = \n", CoreId));
+ if (pPcieConfig->CoreConfiguration[CoreId] == 0x0) {
+ pPcieConfig->CoreConfiguration[CoreId] = (pPcieConfig->PortConfiguration[PortId].PortPresent == ON)?GFX_CONFIG_AABB:GFX_CONFIG_AAAA;
+ } else {
+ if (pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AABB &&
+ pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AAAA) {
+ //We have received request for unknown configuration.
+ //pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON;
+ pPcieConfig->PortConfiguration[PortId].PortPresent = 0;
+ pPcieConfig->PortConfiguration[PortId - 1].PortPresent = 0;
+ return AGESA_WARNING;
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = %x\n", CoreId, pPcieConfig->CoreConfiguration[CoreId]));
+ return AGESA_SUCCESS;
+}
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Validate input parameters for early PCIE init.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieLibInitValidateInput (
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_CONFIG *pPcieConfig;
+ NB_INFO NbInfo;
+ CORE CoreId;
+ PORT PortId;
+
+ NbInfo = LibNbGetRevisionInfo (pConfig);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ if (NbInfo.Type == NB_UNKNOWN || pPcieConfig == NULL) {
+ return AGESA_FATAL;
+ }
+ Status = AGESA_SUCCESS;
+ //Validate GFX configuration
+ if (PcieLibValidateGfxConfig (3, pConfig) != AGESA_SUCCESS) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP1_CORE , 0, 0, 0, pConfig);
+ Status = AGESA_WARNING;
+ }
+ if (PcieLibValidateGfxConfig (12, pConfig) != AGESA_SUCCESS) {
+ REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP2_CORE , 0, 0, 0, pConfig);
+ Status = AGESA_WARNING;
+ }
+ //Enable SB port on NB - SB chain and disable otherwise
+ pPcieConfig->PortConfiguration[8].PortPresent = (pConfig->NbPciAddress.AddressValue == 0)?ON:OFF;
+
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) {
+ //pPcieConfig->CoreSetting[CoreId].PowerOffUnusedLanes = OFF;
+ pPcieConfig->CoreSetting[CoreId].TxClockOff = OFF;
+ pPcieConfig->CoreSetting[CoreId].LclkClockOff = OFF;
+ pPcieConfig->CoreSetting[CoreId].PowerOffPll = OFF;
+ }
+ if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) {
+ //Set Trasmitter drive strength based on cahnnel type
+ if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) {
+ pPcieConfig->CoreSetting[CoreId].TxDriveStrength = (NbInfo.Revision == NB_REV_A11)? PcieTxDriveStrangth24mA : PcieTxDriveStrangth26mA;
+ } else {
+ pPcieConfig->CoreSetting[CoreId].TxDriveStrength = PcieTxDriveStrangth22mA;
+ }
+ // Enable half swing mode
+ if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieShortChannel) {
+ pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = ON;
+ } else {
+ pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = OFF;
+ }
+ }
+ }
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ if (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit == 0) {
+ pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit = 75; //Set 75W by default
+ }
+ if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) {
+ if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) {
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB;
+ } else {
+ pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB;
+ }
+ }
+ }
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Enable PCIE Extended configuration MMIO.
+ *
+ *
+ *
+ * @param[in] PcieMmioBase MMIO Base Address in 1MB unit.
+ * @param[in] PcieMmioSize MMIO Size in 1MB unit
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieLibSetPcieMmioBase (
+ IN UINT16 PcieMmioBase,
+ IN UINT16 PcieMmioSize,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 BAR3BusRange;
+
+ BAR3BusRange = LibAmdBitScanReverse ((UINT32)PcieMmioSize);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, (UINT32)~BIT3, 0x0, pConfig);
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, BIT6, pConfig);
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | (NB_PCI_REG84 + 2), AccessWidth8, (UINT32)~(0x7), (BAR3BusRange > 8)?0:BAR3BusRange, pConfig);
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG1C, AccessWidth32, 0, (UINT32) (PcieMmioBase << 20), pConfig);
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, 0, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG32, AccessWidth32, 0xffffffff, BIT28, pConfig);
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, 0xffffffff, BIT3, pConfig);
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG04, AccessWidth8, (UINT32)~BIT1, BIT1, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Assert/Deassert Strap valid enables programming for misc strap features.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] Operation Assert or deassert strap valid.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieLibStrapModeControl (
+ IN CORE CoreId,
+ IN PCIE_STRAP_MODE Operation,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE_INFO *pCoreInfo;
+
+ pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig);
+ LibNbPciIndexRMW (
+ pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ pCoreInfo->StrapRegister,
+ AccessS3SaveWidth32,
+ ~(1 << pCoreInfo->StrapAddress),
+ (Operation == PcieCoreStrapConfigStart)?(1 << pCoreInfo->StrapAddress):0,
+ pConfig
+ );
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Pcie Port Info.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+PORT_INFO*
+PcieLibGetPortInfo (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ UINT32 CoreConfig;
+ PORT_INFO *pPortInfo;
+ PORT NativePortId;
+ GPP_CFG_INFO *pGppCfgInfoTable;
+
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig);
+ switch (PcieLibGetCoreAddress (CoreId, pConfig)) {
+ case GPP1_CORE:
+ case GPP2_CORE:
+ pPortInfo = &pGfxPortFullA;
+ if (CoreConfig == GFX_CONFIG_AABB) {
+ if (PortId == 3 || PortId == 12) {
+ pPortInfo = &pGfxPortB;
+ } else {
+ pPortInfo = &pGfxPortA;
+ }
+ }
+ break;
+ case SB_CORE:
+ case GPP3b_CORE:
+ pPortInfo = &pGpp420000[0];
+ break;
+ case GPP3a_CORE:
+ pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL);
+ NativePortId = PcieLibNativePortId (PortId, pConfig);
+ if (NativePortId == 0xf) {
+ return NULL;
+ }
+ pPortInfo = &pGppCfgInfoTable->PortInfoPtr[NativePortId - 4];
+ break;
+ default:
+ return NULL;
+ }
+ return (PORT_INFO*)FIX_PTR_ADDR (pPortInfo, NULL);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Pointer to static port info
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+PORT_STATIC_INFO*
+PcieLibGetStaticPortInfo (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT_STATIC_INFO *pPortStaticInfo;
+
+ pPortStaticInfo = (PORT_STATIC_INFO*)FIX_PTR_ADDR (&PortInfoTable[PortId - MIN_PORT_ID], NULL);
+ return pPortStaticInfo ;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Native Port Id.
+ * Native Port Id can be different from Port ID only on GPPSB core ports.
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+PORT
+PcieLibNativePortId (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ CORE CoreId;
+ GPP_CFG_INFO *pGppCfgInfoTable;
+
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ if (PcieLibGetCoreAddress (CoreId, pConfig) == GPP3a_CORE) {
+ UINT32 CoreConfig;
+ CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig);
+ pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL);
+ return (pGppCfgInfoTable->PortIdMap >> ((PortId - 4) * 4)) & 0xF;
+ } else {
+ return PortId;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get pointer to Core info structure.
+ *
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+CORE_INFO*
+PcieLibGetCoreInfo (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ return (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[CoreId], NULL);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Reset Device in slot.
+ * Check if slot has controlled by GPI reset. If support toggle reset for 10us.
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+AGESA_STATUS
+PcieLibResetSlot (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbCallBack (PHCB_AmdPortResetSupported, (UINTN) (1 << PortId), pConfig);
+ if (Status == AGESA_SUCCESS) {
+ LibNbCallBack (PHCB_AmdPortResetAssert, (UINTN) (1 << PortId), pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 10, 0);
+ LibNbCallBack (PHCB_AmdPortResetDeassert, (UINTN) (1 << PortId), pConfig);
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Secondary level interface to check if Gen2 disabled.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+BOOLEAN
+PcieLibCheckGen2Disabled (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ SCRATCH_1 Scratch;
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ if ((Scratch.PortGen2Disable & (1 << (PortId - 2))) != 0) {
+ return FALSE;
+ } else {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Force Gen2 Disable\n"));
+ return TRUE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Request Gen 2 disabled on next boot.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+VOID
+PcieLibSetGen2Disabled (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *pConfig
+ )
+{
+ SCRATCH_1 Scratch;
+
+ LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+ Scratch.PortGen2Disable &= (~(1 << (PortId - 2)));
+ LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Force link to compliance mode
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieLibSetLinkCompliance (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCI_ADDR Port;
+ PCIE_CONFIG *pPcieConfig;
+
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen1) {
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0, AccessWidth32, (UINT32)~BIT13, BIT13, pConfig);
+ } else {
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, (UINT32)~BIT4, BIT4, pConfig);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get PCIe device type
+ *
+ *
+ *
+ * @param[in] Device PCI address of device.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval PCIe device type (see PCIE_DEVICE_TYPE)
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+PCIE_DEVICE_TYPE
+PcieGetDeviceType (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT8 PcieCapPtr;
+ UINT8 Value;
+
+ PcieCapPtr = LibNbFindPciCapability (Device.AddressValue, PCIE_CAP_ID, pConfig);
+ if (PcieCapPtr != 0) {
+ LibNbPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, pConfig);
+ return Value >> 4;
+ }
+ return PcieNotPcieDevice;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get bitmap of cores that have active or potentially active ports
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ * @retval Bitmap of cores
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+UINT8
+PcieLibGetActiveCoreMap (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT PortId;
+ CORE CoreId;
+ UINT8 ActiveCoreMap;
+ PCIE_CONFIG *pPcieConfig;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ ActiveCoreMap = 0;
+ //Check through Ports
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) {
+ if (pPcieConfig->PortConfiguration[PortId].PortCompliance == ON ||
+ pPcieConfig->PortConfiguration[PortId].PortDetected == ON ||
+ pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) {
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ ActiveCoreMap |= (1 << CoreId);
+ }
+ }
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Active Core Map = %x\n", ActiveCoreMap));
+ return ActiveCoreMap;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c
new file mode 100644
index 0000000000..ec3ec80f7e
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c
@@ -0,0 +1,160 @@
+/**
+ * @file
+ *
+ * PCIe link width control.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Set Pcie Link Width
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] LinkWidth New Link Width
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+AGESA_STATUS
+PcieLibSetLinkWidth (
+ IN PORT PortId,
+ IN PCIE_LINK_WIDTH LinkWidth,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PCIE_LINK_WIDTH NewLinkWidth;
+ PCIE_LINK_WIDTH CurrentLinkWidth;
+
+ Status = AGESA_SUCCESS;
+ NewLinkWidth = LinkWidth;
+ CurrentLinkWidth = PcieLibGetLinkWidth (PortId, pConfig);
+ if (NewLinkWidth == 0 || NewLinkWidth > CurrentLinkWidth) {
+ NewLinkWidth = CurrentLinkWidth;
+ }
+ if (NewLinkWidth == PcieLinkWidth_x12) {
+ NewLinkWidth = PcieLinkWidth_x8;
+ }
+ if (NewLinkWidth < CurrentLinkWidth) {
+ CORE CoreId;
+ UINT32 Value;
+ UINT32 CoreAddress;
+ BOOLEAN PoolPortStatus;
+ PCI_ADDR Port;
+
+ CoreId = PcieLibGetCoreId (PortId, pConfig);
+ CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
+ PoolPortStatus = TRUE;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ LibNbPciIndexRMW (NB_SBDFO | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessWidth32, (UINT32)~BIT0, BIT0, pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, 0xfffffff8, (NewLinkWidth) | BIT8 | BIT7, pConfig);
+ while (PoolPortStatus) {
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG6A, AccessWidth16, &Value, pConfig);
+ if ((Value & BIT11) == 0) {
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig);
+ if ((Value & BIT8) == 0) {
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &Value, pConfig);
+ if ((Value & BIT1) == 0) {
+ PoolPortStatus = FALSE;
+ }
+ }
+ }
+ }
+ LibNbPciIndexRMW (NB_SBDFO | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0 , pConfig);
+ LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, (UINT32)~BIT7, 0, pConfig);
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Return link with
+ *
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+PCIE_LINK_WIDTH
+PcieLibGetLinkWidth (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_LINK_WIDTH LinkWidth;
+ UINT32 Value;
+ PCI_ADDR Port;
+
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+// Read current link State
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &Value, pConfig);
+ if ((Value & 0x3f) == 0x10) {
+ //Read current link width
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig);
+ LinkWidth = (Value >> 4) & 0xf;
+ } else {
+ //Link not in L0
+ LinkWidth = PcieLinkWidth_x0;
+ }
+ return LinkWidth;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h
new file mode 100644
index 0000000000..8eab54172c
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h
@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * PCIe link width control.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIELINKWIDTH_H_
+#define _NBPCIELINKWIDTH_H_
+
+AGESA_STATUS
+PcieLibSetLinkWidth (
+ IN PORT PortId,
+ IN PCIE_LINK_WIDTH LinkWidth,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+PCIE_LINK_WIDTH
+PcieLibGetLinkWidth (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c
new file mode 100644
index 0000000000..ec2206bfca
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c
@@ -0,0 +1,193 @@
+/**
+ * @file
+ *
+ * PCIe Port device number remapping.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+SCAN_STATUS
+PciePllOffCheckFunction (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Function
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if EP allowed exit latency allowed PLL in L1 to be disabled on non hotplug ports.
+ *
+ *
+ * @param[in] CoreId CoreId
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+BOOLEAN
+PciePllOffComatibilityTest (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PLLOFF_WORKSPACE PllOffWorkspace;
+ PORT PortId;
+ BOOLEAN Result;
+ PCIE_CONFIG *pPcieConfig;
+ BOOLEAN IsHotplugPorst;
+ BOOLEAN IsNonHotplugPorts;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePllOffInL1ComatibilityTest Enter Core [%d]\n", CoreId));
+ LibAmdMemFill (&PllOffWorkspace, 0, sizeof (PllOffWorkspace), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ PllOffWorkspace.ScanPciePort.pConfig = pConfig;
+ PllOffWorkspace.ScanPciePort.ScanBus = LibNbScanPciBus;
+ PllOffWorkspace.ScanPciePort.ScanDevice = LibNbScanPciDevice;
+ PllOffWorkspace.ScanPciePort.ScanFunction = PciePllOffCheckFunction;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) {
+ if (pPcieConfig->PortConfiguration[PortId].PortHotplug == ON) {
+ IsHotplugPorst = TRUE;
+ continue; // Skip hotplug ports . Will make decision later.
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON) {
+ PCI_ADDR Port;
+ IsNonHotplugPorts = TRUE;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ PllOffWorkspace.ScanPciePort.ScanFunction (&PllOffWorkspace.ScanPciePort, Port);
+ }
+ }
+ }
+ if (PllOffWorkspace.MaxL1Latency != 0 && PllOffWorkspace.MaxL1Latency < 34) {
+ Result = FALSE;
+ } else {
+ Result = TRUE;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePllOffInL1ComatibilityTest Exit [%d]\n", Result));
+ return Result;
+}
+
+/**----------------------------------------------------------------------------------------*/
+/**
+ * Scan PCIe topology
+ *
+ *
+ *
+ * @param[in] This Pointer to instance of scan protocol
+ * @param[in] Function PCI address of found device/function.
+ *
+ * @retval SCAN_FINISHED Scan for device finished.
+ */
+ /*----------------------------------------------------------------------------------------*/
+SCAN_STATUS
+PciePllOffCheckFunction (
+ IN PCI_SCAN_PROTOCOL *This,
+ IN PCI_ADDR Function
+ )
+{
+ PLLOFF_WORKSPACE *WorkspacePtr;
+ PCIE_DEVICE_TYPE DeviceType;
+ UINT8 SecondaryBus;
+ PCI_ADDR Port;
+
+ WorkspacePtr = (PLLOFF_WORKSPACE*) This;
+ DeviceType = PcieGetDeviceType (Function, This->pConfig);
+ if (DeviceType == PcieDeviceRootComplex || DeviceType == PcieDeviceDownstreamPort) {
+ WorkspacePtr->LinkCount++;
+ //Lets enable Common clock
+ LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig);
+ if (SecondaryBus == 0) {
+ return SCAN_FINISHED;
+ }
+ Port.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0);
+ This->ScanBus (This, Port);
+ WorkspacePtr->LinkCount--;
+ } else if (DeviceType == PcieDeviceUpstreamPort ) {
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached upstream port\n"));
+ LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig);
+ if (SecondaryBus == 0) {
+ return SCAN_FINISHED;
+ }
+ Port.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0);
+ This->ScanBus (This, Port);
+ } else if (DeviceType <= PcieDeviceLegacyEndPoint) {
+ // We reach end of the link
+ UINT8 PcieCapPtr;
+ UINT32 Value;
+ UINT8 L1AcceptableLatency;
+ PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, This->pConfig);
+ if (PcieCapPtr != 0) {
+ LibNbPciRead (Function.AddressValue | (PcieCapPtr + 0x0D) , AccessWidth8, &Value, This->pConfig);
+ if (((Value >> 2) & ASPM_L1) != 0) {
+ LibNbPciRead ((Function.AddressValue | (PcieCapPtr + 4)), AccessWidth32, &Value, This->pConfig);
+ L1AcceptableLatency = ((UINT8) (1 << ((Value >> 9) & 0x7)) & 0x7F);
+ if (WorkspacePtr->LinkCount > 1) {
+ L1AcceptableLatency = L1AcceptableLatency + WorkspacePtr->LinkCount;
+ }
+ if (WorkspacePtr->MaxL1Latency < L1AcceptableLatency) {
+ WorkspacePtr->MaxL1Latency = L1AcceptableLatency;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached end of link at 0x%x with Acceptable Exit Latency %dus \n", Function.AddressValue, L1AcceptableLatency));
+ }
+ }
+ }
+ return SCAN_FINISHED;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h
new file mode 100644
index 0000000000..44193a528c
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h
@@ -0,0 +1,63 @@
+/**
+ * @file
+ *
+ * PLL off in L1 support.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+#ifndef _NBPLLCONTROL_H_
+#define _NBPLLCONTROL_H_
+
+BOOLEAN
+PciePllOffComatibilityTest (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+#pragma pack (push, 1)
+/// Framework for testing for ability to diable PLL in L1
+typedef struct {
+ PCI_SCAN_PROTOCOL ScanPciePort; ///< PCI scan protocol
+ PCI_ADDR DownstreamPort; ///< Downstream port to enable ASPM
+ UINT8 MaxL1Latency; ///< TBD
+ UINT8 LinkCount; ///< TBD
+} PLLOFF_WORKSPACE;
+
+#pragma pack (pop)
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c
new file mode 100644
index 0000000000..639f149565
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c
@@ -0,0 +1,182 @@
+/**
+ * @file
+ *
+ * PCIe Port device number remapping.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+PORT
+STATIC
+PciePortRemapAllocateDeviceId (
+ IN UINT8 *UnusedPortMap
+);
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Remap PCIe ports device number.
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+AGESA_STATUS
+PciePortRemapInit (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ PORT FinalDeviceIdList[MAX_PORT_ID + 1];
+ UINT8 UsedDeviceIdMap[MAX_PORT_ID + 1];
+ BOOLEAN IsDeviceRemapEnabled;
+ PORT PortId;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePortDeviceNumberRemap Enter \n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ Status = AGESA_SUCCESS;
+ IsDeviceRemapEnabled = FALSE;
+ // Remap Device
+ LibAmdMemFill (&UsedDeviceIdMap, 0, sizeof (UsedDeviceIdMap), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ LibAmdMemFill (&FinalDeviceIdList, 0, sizeof (FinalDeviceIdList), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (PcieLibIsValidPortId (PortId, pConfig)) {
+ PORT NativePortId = PcieLibNativePortId (PortId, pConfig);
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent) {
+ //FinalDeviceIdList[PortId] = PortId;
+ if (pPcieConfig->ExtPortConfiguration[PortId].PortMapping != 0) {
+ if (pPcieConfig->ExtPortConfiguration[PortId].PortMapping < MIN_PORT_ID ||
+ pPcieConfig->ExtPortConfiguration[PortId].PortMapping > MAX_PORT_ID ||
+ pPcieConfig->ExtPortConfiguration[PortId].PortMapping == 8) {
+ return AGESA_ERROR;
+ }
+ FinalDeviceIdList[NativePortId] = pPcieConfig->ExtPortConfiguration[PortId].PortMapping;
+ IsDeviceRemapEnabled = TRUE;
+ } else {
+ FinalDeviceIdList[NativePortId] = PortId;
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Requested Port Mapping %d -> %d\n", PortId, FinalDeviceIdList[PortId]));
+ if (UsedDeviceIdMap[FinalDeviceIdList[NativePortId]] == 0 ) {
+ UsedDeviceIdMap[FinalDeviceIdList[NativePortId]] = 1;
+ } else {
+ return AGESA_ERROR;
+ }
+ }
+ }
+ }
+ if (!IsDeviceRemapEnabled) {
+ return Status;
+ }
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PORT_STATIC_INFO *pStaticPortInfo;
+ pStaticPortInfo = PcieLibGetStaticPortInfo (PortId, pConfig);
+ if (pStaticPortInfo->MappingAddress == 0xFF) {
+ continue;
+ }
+ if (FinalDeviceIdList[PortId] == 0) {
+ FinalDeviceIdList[PortId] = PciePortRemapAllocateDeviceId (&UsedDeviceIdMap[0]);
+ }
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Port Mapping %d -> %d\n", PortId, FinalDeviceIdList[PortId]));
+ LibNbPciIndexRMW (
+ NB_SBDFO | NB_MISC_INDEX,
+ (PortId > 9)?NB_MISC_REG21:NB_MISC_REG20,
+ AccessWidth32,
+ 0xffffffff,
+ FinalDeviceIdList [PortId] << pStaticPortInfo->MappingAddress,
+ pConfig
+ );
+
+ }
+ LibNbPciIndexRMW (NB_SBDFO | NB_MISC_INDEX, NB_MISC_REG20, AccessWidth32, 0xffffffff, 0x3, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePortDeviceNumberRemap Exit [0x%x] \n", Status));
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Allocate Device number from unused port array.
+ *
+ *
+ *
+ * @param[in] UnusedPortMap Unused port array.
+ */
+
+PORT
+STATIC
+PciePortRemapAllocateDeviceId (
+ IN UINT8 *UnusedPortMap
+ )
+{
+ PORT PortId;
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (UnusedPortMap[PortId] == 0) {
+ UnusedPortMap[PortId] = 1;
+ break;
+ }
+ }
+ return PortId;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h
new file mode 100644
index 0000000000..32236f07a0
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+* PCIe Port device number remapping.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIEPORTREMAP_H_
+#define _NBPCIEPORTREMAP_H_
+
+AGESA_STATUS
+PciePortRemapInit (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c b/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c
new file mode 100644
index 0000000000..918fbd43f1
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c
@@ -0,0 +1,753 @@
+/**
+ * @file
+ *
+ * PCIe in recovery support
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+VOID
+PcieRecoveryCoreInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+VOID
+PcieRecoveryPortTraining (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ );
+
+VOID
+PcieRecoveryCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+PcieRecoveryCommonCoreInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+UINT32
+PcieRecoveryGetCoreAddress (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+PCI_ADDR
+PcieRecoveryGetPortPciAddress (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+PcieRecoveryPcieCheckPorts (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+VOID
+PcieRecoveryReleaseTraining (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ );
+
+PORT
+PcieRecoveryNativePortId (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * PCIE Recovery Init. Basic programming / EP training.
+ * After this call EP are fully operational.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+AGESA_STATUS
+AmdPcieEarlyInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+#ifdef PCIE_RECOVERY_SUPPORT
+ PcieRecoveryCoreInit (ConfigPtr);
+ PcieRecoveryPortTraining (ConfigPtr);
+#endif
+ return AGESA_SUCCESS;
+}
+
+
+#ifdef PCIE_RECOVERY_SUPPORT
+
+INDIRECT_REG_ENTRY
+STATIC
+PcieRecoveryMiscInitTable[] = {
+ {
+ NB_MISC_REG0C,
+ (UINT32)~0x001f00FC,
+ 0x00000000
+ },
+ {
+ NB_MISC_REG20,
+ (UINT32)~BIT1,
+ 0x0
+ }, //enable static device remapping by default
+ {
+ NB_MISC_REG22,
+ 0xffffffff,
+ BIT27
+ }, //[10]CMGOOD_OVERRIDE for all 5 pcie cores.
+ {
+ NB_MISC_REG6B,
+ 0xffffffff,
+ (UINT32) (0x1f << 27)
+ }, //[13][12]Turn Off Offset Cancellation
+ {
+ NB_MISC_REG37,
+ (UINT32)~(BIT11 + BIT12 + BIT13),
+ 0x0
+ }, //[14][13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG67,
+ (UINT32)~(BIT26 + BIT10 + BIT11),
+ BIT11
+ }, //[13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG2C,
+ (UINT32)~(BIT10),
+ 0x0
+ }, //[13]Disables Rx Clock gating in CDR
+ {
+ NB_MISC_REG2A,
+ (UINT32)~(BIT17 + BIT16),
+ BIT17
+ }, //[16]Sets Electrical l Idle Threshold
+ {
+ NB_MISC_REG32,
+ (UINT32)~(0x3F << 20),
+ (UINT32) (0x2A << 20)
+ }, //[17][16]Sets Electrical Idle Threshold
+ {
+ NB_MISC_REG28,
+ 0xffffff00,
+ 0x0
+ },
+ {
+ NB_MISC_REG27,
+ 0x3fffffff,
+ 0x0
+ },
+ {
+ NB_MISC_REG2D,
+ (UINT32)~(BIT5),
+ 0x0
+ }
+};
+
+// 2 3 4 5 6 7 8 9 A B C D
+UINT8 PortToCoreMappingTable[] = { 0xff, 0xff, 0, 0, 3, 3, 3, 3, 4, 3, 3, 1, 1, 3 };
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Minimum core initialization
+ *
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+VOID
+PcieRecoveryCoreInit (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ CORE CoreId;
+ PORT PortId;
+ AMD_NB_CONFIG *NbConfigPtr;
+ PCIE_CONFIG *pPcieConfig;
+
+ NbConfigPtr = &ConfigPtr->Northbridges[0];
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+//Init Misc registers
+ LibNbIndirectTableInit (
+ NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryMiscInitTable[0],NULL),
+ (sizeof (PcieRecoveryMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ NbConfigPtr
+ );
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) {
+ pPcieConfig->CoreSetting[PortToCoreMappingTable[PortId]].CoreDisabled = OFF;
+ }
+ }
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) {
+ //Init core registers and configuration
+ PcieRecoveryCommonCoreInit (CoreId, NbConfigPtr);
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Port link training initialization
+ *
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+VOID
+PcieRecoveryPortTraining (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ PORT PortId;
+ UINT32 PortToHideMap;
+ AMD_NB_CONFIG *NbConfigPtr;
+ PCIE_CONFIG *pPcieConfig;
+
+ PortToHideMap = 0;
+ NbConfigPtr = &ConfigPtr->Northbridges[0];
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) {
+ PcieRecoveryCommonPortInit (PortId, NbConfigPtr);
+ if (LibNbCallBack (PHCB_AmdPortResetDeassert, 1 << PortId, NbConfigPtr) == AGESA_SUCCESS) {
+ STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), pPcieConfig->ResetToTrainingDelay, 0);
+ }
+ if (PortId != 8) {
+ PcieRecoveryReleaseTraining (PortId, NbConfigPtr);
+ }
+ }
+ }
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ReceiverDetectionPooling, 0);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PCI_ADDR Port;
+ Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr);
+ if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PortId != 8) {
+ PcieRecoveryPcieCheckPorts (PortId, NbConfigPtr);
+
+ pPcieConfig->PortConfiguration[PortId].PortLinkMode = PcieLinkModeGen1;
+
+ LibNbPciIndexWrite (
+ Port.AddressValue | NB_BIF_INDEX,
+ NB_BIFNBP_REG01,
+ AccessWidth32,
+ (UINT32*)&pPcieConfig->PortConfiguration[PortId],
+ NbConfigPtr
+ );
+ }
+ if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF) {
+ PortToHideMap |= (1 << PortId);
+ }
+ }
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessWidth32, 0xffffffff, (PortToHideMap & 0xFC) | ((PortToHideMap & 0x3E00) << 7), NbConfigPtr);
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check link training Status
+ *
+ *
+ *
+ *
+ * @param[in] Config Northbridges configuration structure pointer.
+ *
+ */
+VOID
+PcieRecoveryPcieCheckPorts (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ PCI_ADDR Port;
+ UINT32 LinkState;
+ UINT32 LinkStatePooling;
+ UINT32 Value;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr);
+ LinkStatePooling = pPcieConfig->ReceiverDetectionPooling;
+ do {
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCoreInit PortId = %d LinkState 0x%x\n", PortId, LinkState));
+ LinkState &= 0x3F;
+ if (LinkState == 0x10) {
+ UINT16 VcoStatus;
+ BOOLEAN VcoNotCompleted;
+ UINT32 VcoPooling;
+ VcoNotCompleted = TRUE;
+ VcoPooling = 6000;
+ do {
+ LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &VcoStatus, NbConfigPtr);
+ if (VcoStatus & BIT1) {
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr);
+ Value = (Value & 0xfffffe80) | ((Value & 0x70) >> 4) | BIT8;
+ LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr);
+ STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 5000, 0);
+ } else {
+ VcoNotCompleted = FALSE;
+ }
+ } while (VcoNotCompleted || --VcoPooling != 0);
+ if (!VcoNotCompleted) {
+ pPcieConfig->PortConfiguration[PortId].PortDetected = ON;
+ }
+ } else {
+ STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 1000, 0);
+ }
+ } while (LinkState != 0x10 && --LinkStatePooling != 0);
+}
+
+
+UINT8 PortTrainingOffset[] = {
+ 4, 5, 21, 22, 23, 24, 20, 25, 26, 6, 7 , 4
+};
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check link training Status
+ *
+ *
+ *
+ *
+ * @param[in] Config Northbridges configuration structure pointer.
+ *
+ */
+VOID
+PcieRecoveryReleaseTraining (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PORT NativePortId;
+
+ NativePortId = PcieRecoveryNativePortId (PortId, NbConfigPtr);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryReleaseTraining PortId = %d NativeId %d BitOfset %d\n",
+ PortId, NativePortId, ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID]));
+ LibNbPciIndexRMW (
+ NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ (PortId == 13)? NB_MISC_REG2A:NB_MISC_REG08,
+ AccessWidth32,
+ ~(1 << ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID]),
+ 0,
+ NbConfigPtr
+ );
+}
+
+INDIRECT_REG_ENTRY PcieRecoveryPortInitTable[] = {
+ {
+ NB_BIFNBP_REG02,
+ (UINT32)~(BIT15),
+ BIT15
+ },
+ {
+ NB_BIFNBP_REGA1,
+ (UINT32)~(BIT24),
+ BIT11
+ },
+ {
+ NB_BIFNBP_REGB1,
+ 0xffffffff,
+ BIT28 + BIT23 + BIT19 + BIT20
+ },
+ {
+ NB_BIFNBP_REGA4,
+ (UINT32)~(BIT0),
+ 0x0
+ },
+ {
+ NB_BIFNBP_REGA2,
+ (UINT32)~(BIT13),
+ BIT13
+ },
+ {
+ NB_BIFNBP_REGA3,
+ (UINT32)~(BIT9),
+ BIT9
+ },
+ {
+ NB_BIFNBP_REGA0,
+ 0xffff00ff,
+ 0x6130
+ },
+ {
+ NB_BIFNBP_REG70,
+ (UINT32)~(BIT16 + BIT17 + BIT18),
+ BIT16 + BIT18
+ },
+ // Set Link for Gen1
+ {
+ NB_BIFNBP_REGC0,
+ (UINT32)~(BIT15),
+ BIT15
+ },
+ {
+ NB_BIFNBP_REGA2,
+ (UINT32)~(BIT13),
+ BIT13
+ },
+ {
+ NB_BIFNBP_REGA4,
+ (UINT32)~(BIT0 + BIT29),
+ 0x0
+ }
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Port basic register init
+ *
+ *
+ *
+ *
+ * @param[in] Config Northbridges configuration structure pointer.
+ *
+ */
+
+VOID
+PcieRecoveryCommonPortInit (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR Port;
+
+ Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr);
+ LibNbIndirectTableInit (
+ Port.AddressValue | NB_BIF_INDEX,
+ 0x0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryPortInitTable[0],NULL),
+ (sizeof (PcieRecoveryPortInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ NbConfigPtr
+ );
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessWidth8, 0xF0, 0x6, NbConfigPtr);
+ LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, 0x0, NbConfigPtr);
+}
+
+
+UINT8 GppConfigTable[] = {
+ 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB
+};
+
+INDIRECT_REG_ENTRY PcieRecoveryCoreInitTable[] = {
+ {
+ NB_BIFNB_REG10,
+ (UINT32)~(BIT10 + BIT11 + BIT12),
+ BIT12
+ },
+ {
+ NB_BIFNB_REG20,
+ (UINT32)~(BIT8 + BIT9),
+ BIT9
+ },
+ {
+ NB_BIFNB_REG02,
+ (UINT32)~(BIT0),
+ BIT0
+ },
+ {
+ NB_BIFNB_REG40,
+ (UINT32)~(BIT14 + BIT15),
+ BIT15
+ },
+ {
+ NB_BIFNB_REGC1,
+ (UINT32)~(BIT0),
+ (BIT0 + BIT1 + BIT2)
+ },
+ {
+ NB_BIFNB_REG1C,
+ 0x0,
+ (4 << 6) + (4 << 1) + 1
+ }
+};
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Core basic register init
+ *
+ *
+ *
+ *
+ * @param[in] Config Northbridges configuration structure pointer.
+ *
+ */
+
+VOID
+PcieRecoveryCommonCoreInit (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 CoreAddress;
+ PCIE_CONFIG *pPcieConfig;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit CoreID = %d Enter\n", CoreId));
+ CoreAddress = PcieRecoveryGetCoreAddress (CoreId, NbConfigPtr);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ //Setup GPP1 core configuration
+ if (CoreAddress == GPP1_CORE && (pPcieConfig->CoreConfiguration[0] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[3].PortPresent == ON)) {
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT15, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT28, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT8, NbConfigPtr);
+ STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, 0x0, NbConfigPtr);
+ }
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT15, 0x0, NbConfigPtr);
+ //Setup GPP2 core configuration
+ if (CoreAddress == GPP2_CORE && (pPcieConfig->CoreConfiguration[1] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[12].PortPresent == ON)) {
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT13, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT29, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT9, NbConfigPtr);
+ STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT29, 0x0, NbConfigPtr);
+ }
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT13, 0x0, NbConfigPtr);
+ //Setup GPP core configuration
+ if (CoreAddress == GPP3a_CORE) {
+ UINT32 Mux;
+ UINT8 *pGppConfigTable;
+ Mux = 0;
+ pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT31, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, BIT30, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, 0xfffffff0, (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]], NbConfigPtr);
+ switch (pPcieConfig->CoreConfiguration[CoreId]) {
+ case GPP_CONFIG_GPP420000:
+ Mux = (pPcieConfig->PortConfiguration[6].PortReversed == ON)?0xF05BA00:0x055B000;
+ break;
+ case GPP_CONFIG_GPP411000:
+ Mux = 0x215B400;
+ break;
+ case GPP_CONFIG_GPP222000:
+ case GPP_CONFIG_GPP211110:
+ Mux = (pPcieConfig->PortConfiguration[4].PortReversed == ON)?0xFFF0AAA:0xFF0BAA0;
+ break;
+ case GPP_CONFIG_GPP221100:
+ Mux = 0x215B400;
+ break;
+ case GPP_CONFIG_GPP111111:
+ Mux = 0x2AA3554;
+ break;
+ }
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, 0x0, NbConfigPtr);
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, (UINT32)~BIT31, 0x0, NbConfigPtr);
+ }
+ if (CoreAddress == GPP3b_CORE) {
+ LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2A, AccessWidth32, (UINT32)~BIT15, 0, NbConfigPtr);
+ }
+ LibNbIndirectTableInit (
+ NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX,
+ CoreAddress,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryCoreInitTable[0],NULL),
+ (sizeof (PcieRecoveryCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
+ NbConfigPtr
+ );
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit Exitr\n"));
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Core register selector.
+ * Function return selector to access BIFNB register space for selected core
+ *
+ *
+ * @param[in] CoreId PCI Express Core ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+UINT32
+PcieRecoveryGetCoreAddress (
+ IN CORE CoreId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 CoreAddress;
+ CoreAddress = GPP1_CORE;
+ switch (CoreId) {
+ case 0x0:
+ CoreAddress = GPP1_CORE;
+ break;
+ case 0x1:
+ CoreAddress = GPP2_CORE;
+ break;
+ case 0x2:
+ CoreAddress = GPP3a_CORE;
+ break;
+ case 0x3:
+ CoreAddress = GPP3b_CORE;
+ break;
+ case 0x4:
+ CoreAddress = SB_CORE;
+ break;
+ default:
+ CIMX_ASSERT (FALSE);
+ }
+ return CoreAddress;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get PCI address of Port.
+ * Function return pcie Address based on port mapping and core configuration.
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+PCI_ADDR
+PcieRecoveryGetPortPciAddress (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCI_ADDR Port;
+ Port = NbConfigPtr->NbPciAddress;
+ Port.Address.Device = PortId;
+ return Port;
+}
+
+UINT32 GppNativeIdTable[] = {
+ 0xff50fff4,
+ 0xf650fff4,
+ 0xff60f5f4,
+ 0xf760f5f4,
+ 0xf87065f4,
+ 0xf9807654
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Native Port Id.
+ * Native Port Id can be different from Port ID only on GPPSB core ports.
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+PORT
+PcieRecoveryNativePortId (
+ IN PORT PortId,
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ UINT32 GppNativeIdMap;
+ if (PortId > 3 && PortId < 11) {
+ GppNativeIdMap = ((UINT32*)FIX_PTR_ADDR (&GppNativeIdTable[0], NULL))[NbConfigPtr->pPcieConfig->CoreConfiguration[0x2] - 1];
+ return (GppNativeIdMap >> ((PortId - 4)*4)) & 0xF;
+ } else {
+ return PortId;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize default PCIE_CONFIG setting
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+PcieRecoveryInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ CORE CoreId;
+ pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr);
+ if (pPcieConfig == NULL) {
+ return AGESA_FATAL;
+ }
+ LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)NbConfigPtr);
+ pPcieConfig->ReceiverDetectionPooling = 120;
+ pPcieConfig->ResetToTrainingDelay = 4;
+ for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) {
+ pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON;
+ }
+ return AGESA_SUCCESS;
+}
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieSb.c b/src/vendorcode/amd/cimx/rd890/nbPcieSb.c
new file mode 100644
index 0000000000..3ef6094432
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieSb.c
@@ -0,0 +1,195 @@
+/**
+ * @file
+ *
+ * PCIe support for misc Southbridges.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Set up NB-SB virtual channel for audio traffic
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Set up NB-SB virtual channel for audio traffic
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+AGESA_STATUS
+PcieSbSetupVc (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT16 AlinkPort;
+
+ Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig);
+ if (Status != AGESA_SUCCESS) {
+ return Status;
+ }
+
+ LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x80000124, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffff01, 0, pConfig);
+ LibNbIoRMW (AlinkPort, AccessS3SaveWidth32 , 0x0, 0x80000130, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, (UINT32)~(BIT24 + BIT25 + BIT26), 0xFE + BIT24, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, BIT31, pConfig);
+ return AGESA_SUCCESS;
+}
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Set up NB-SB virtual channel for audio traffic
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+VOID
+PcieSbEnableVc (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT16 AlinkPort;
+ Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig);
+ if (Status != AGESA_SUCCESS) {
+ return;
+ }
+ LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0xC0000050, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, BIT3, pConfig);
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Init SB ASPM.
+ * Enable ASPM states on SB
+ *
+ *
+ * @param[in] Lx Lx ASPM bitmap. Lx[0] - L0s enable. Lx[1] - L1 enable.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieSbInitAspm (
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT16 AlinkPort;
+
+ Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig);
+ if (Status != AGESA_SUCCESS) {
+ return Status;
+ }
+ LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x40000038, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0x0, 0xA0, pConfig);
+ LibNbIoRMW (AlinkPort , AccessS3SaveWidth32, 0x0, 0x4000003c, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffff00ff, 0x6900, pConfig );
+ LibNbIoRMW (AlinkPort , AccessS3SaveWidth32, 0x0, 0x80000068, pConfig);
+ LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, Lx, pConfig);
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get Alink config address
+ *
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+AGESA_STATUS
+PcieSbAgetAlinkIoAddress (
+ OUT UINT16 *AlinkPort,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ SB_INFO SbInfo;
+ SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig));
+ if (SbInfo.Type == SB_UNKNOWN) {
+ return AGESA_UNSUPPORTED;
+ }
+ if (SbInfo.Type == SB_SB700) {
+ LibNbPciRead (MAKE_SBDFO (0, 0, 0x14, 0, 0xf0), AccessWidth16, AlinkPort, pConfig);
+ } else {
+ LibAmdSbPmioRead (0xE0, AccessWidth16, AlinkPort, NULL);
+ }
+ if (*AlinkPort == 0) {
+ return AGESA_UNSUPPORTED;
+ }
+ return AGESA_SUCCESS;
+} \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieSb.h b/src/vendorcode/amd/cimx/rd890/nbPcieSb.h
new file mode 100644
index 0000000000..2b0914c4a1
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieSb.h
@@ -0,0 +1,71 @@
+/**
+ * @file
+ *
+ * PCIe support for misc Southbridges.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIESB_H_
+#define _NBPCIESB_H_
+
+
+AGESA_STATUS
+PcieSbInitAspm (
+ IN UINT8 Lx,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieSbSetupVc (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieSbEnableVc (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+
+AGESA_STATUS
+PcieSbAgetAlinkIoAddress (
+ OUT UINT16 *AlinkPort,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c
new file mode 100644
index 0000000000..771c489ea0
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c
@@ -0,0 +1,436 @@
+/**
+ * @file
+ *
+ * Routines to support misc PCIe workarounds.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdSbLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+AGESA_STATUS
+PcieConfigureBridgeResources (
+ IN PCI_ADDR Port,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieFreeBridgeResources (
+ IN PCI_ADDR Port,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+ AGESA_STATUS
+PcieDeskewWorkaround (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+AGESA_STATUS
+PcieNvWorkaround (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+BOOLEAN
+PcieIsDeskewCardDetected (
+ IN UINT16 DeviceId
+ );
+
+ /*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc GFX Card Workaround
+ * RV3780/RV380 desk workaround. NV43 lost SSID workaround.
+ *
+ *
+ *
+ * @param[in] PortId PCI Express Port ID
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+AGESA_STATUS
+PcieGfxWorkarounds (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ AGESA_STATUS Status;
+ UINT32 Count;
+ UINT16 DeviceId;
+ UINT16 VendorId;
+ UINT8 DevClassCode;
+ PCI_ADDR Port;
+ PCI_ADDR Ep;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGfxWorkarounds PortId %d Enter\n", PortId));
+ Status = AGESA_SUCCESS;
+ Port = PcieLibGetPortPciAddress (PortId, pConfig);
+ Ep.AddressValue = MAKE_SBDFO (0, Port.Address.Bus + 5, 0, 0, 0);
+ if (PcieConfigureBridgeResources (Port, pConfig) != AGESA_SUCCESS) {
+ return AGESA_SUCCESS;
+ }
+ for (Count = 0; Count <= 5000; Count++) {
+ LibNbPciRead (Ep.AddressValue | 0x02, AccessWidth16, &DeviceId, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Endpoint Device ID %x\n", DeviceId));
+ if (DeviceId != 0xffff) {
+ break;
+ };
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0);
+ }
+ if (Count >= 5000) {
+ PcieLibRequestPciReset (pConfig);
+ return AGESA_WARNING;
+ }
+ LibNbPciRead (Ep.AddressValue | 0x02, AccessWidth16, &DeviceId, pConfig);
+ LibNbPciRead (Ep.AddressValue, AccessWidth16, &VendorId, pConfig);
+ if (VendorId == 0xffff) {
+ PcieLibRequestPciReset (pConfig);
+ return AGESA_WARNING;
+ }
+ LibNbPciRead (Ep.AddressValue | 0x0B , AccessWidth8, &DevClassCode, pConfig);
+ if (DevClassCode == 3) {
+ if (VendorId == 0x1002 && PcieIsDeskewCardDetected (DeviceId)) {
+ Status = PcieDeskewWorkaround (Ep, pConfig);
+ } else {
+ if (VendorId == 0x10DE) {
+ Status = PcieNvWorkaround (Ep, pConfig);
+ }
+ }
+ }
+ PcieFreeBridgeResources (Port, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGfxWorkarounds Exit [Status = 0x%x]\n", Status));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * RV370/RV380 Deskew workaround
+ *
+ *
+ *
+ * @param[in] Device Pcie Address of ATI RV370/RV380 card.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+AGESA_STATUS
+PcieDeskewWorkaround (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ UINTN MmioBase;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieDeskewWorkaround Enter\n"));
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ MmioBase = pPcieConfig->TempMmioBaseAddress << 20;
+ if (MmioBase == 0) {
+ return AGESA_SUCCESS;
+ }
+ LibNbPciWrite (Device.AddressValue | 0x18, AccessWidth32, &MmioBase, pConfig);
+ LibNbPciRMW (Device.AddressValue | 0x04, AccessWidth8 , (UINT32)~BIT1, BIT1, pConfig);
+ *(UINT16*)(MmioBase + 0x120) = 0xb700;
+ if (*(UINT16*) (MmioBase + 0x120) == 0xb700) {
+ *(UINT32*)(MmioBase + 0x124) = 0x13;
+ if (*(UINT32*) (MmioBase + 0x124) == 0x13) {
+ if (*(UINT32*) (MmioBase + 0x12C) & BIT8) {
+// TRACE((DMSG_PCIE_MISC,"Deskew ERROR Generate Reset\n"));
+ PcieLibRequestPciReset (pConfig);
+ return AGESA_WARNING;
+ }
+ }
+ }
+ LibNbPciRMW (Device.AddressValue | 0x04, AccessWidth8, (UINT32)~BIT1, 0x0, pConfig);
+ LibNbPciRMW (Device.AddressValue | 0x18, AccessWidth32, 0x0, 0x0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieDeskewWorkaround Exit\n"));
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NV43 card workaround (lost SSID)
+ *
+ *
+ *
+ * @param[in] Device Pcie Address of NV43 card.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+AGESA_STATUS
+PcieNvWorkaround (
+ IN PCI_ADDR Device,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 DeviceSSID;
+ PCIE_CONFIG *pPcieConfig;
+ UINTN MmioBase;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieNvWorkaround Enter\n"));
+ LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0B, AccessS3SaveWidth32, 0xffffffff, BIT2 + BIT1, pConfig);
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ MmioBase = pPcieConfig->TempMmioBaseAddress << 20;
+ if (MmioBase == 0) {
+ return AGESA_SUCCESS;
+ }
+ LibNbPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, ((UINT32)MmioBase) | 1, pConfig);
+ LibNbPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x2, pConfig);
+ LibNbPciRead (Device.AddressValue | 0x2c, AccessWidth32, &DeviceSSID, pConfig);
+ if (DeviceSSID != *(UINT32*) (MmioBase + 0x54)) {
+ LibNbPciRMW (Device.AddressValue | 0x40, AccessWidth32, 0x0, *(UINT32*) (MmioBase + 0x54), pConfig);
+ }
+ LibNbPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, 0x0, pConfig);
+ LibNbPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x0, pConfig);
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieNvWorkaround Exit\n"));
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Allocate temporary resources for Pcie P2P bridge
+ *
+ *
+ *
+ * @param[in] Port Pci Address of Port to initialize.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+AGESA_STATUS
+PcieConfigureBridgeResources (
+ IN PCI_ADDR Port,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PCIE_CONFIG *pPcieConfig;
+ UINT32 Value;
+ UINT32 MmioBase;
+
+ pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
+ MmioBase = pPcieConfig->TempMmioBaseAddress << 20;
+ if (MmioBase == 0) {
+ return AGESA_WARNING;
+ }
+ Value = Port.Address.Bus + ((Port.Address.Bus + 5) << 8) + ((Port.Address.Bus + 5) << 16);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG18, AccessWidth32, &Value, pConfig);
+ Value = MmioBase + (MmioBase >> 16);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG20, AccessWidth32, &Value, pConfig);
+ Value = 0x000fff0;
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG24, AccessWidth32, &Value, pConfig);
+ Value = 0x2;
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG04, AccessWidth8, &Value, pConfig);
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Free temporary resources for Pcie P2P bridge
+ *
+ *
+ *
+ * @param[in] Port Pci Address of Port to clear resource allocation.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+VOID
+PcieFreeBridgeResources (
+ IN PCI_ADDR Port,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 Value;
+
+ Value = 0;
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG04, AccessWidth8, &Value, pConfig);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG18, AccessWidth32, &Value, pConfig);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG20, AccessWidth32, &Value, pConfig);
+ LibNbPciWrite (Port.AddressValue | NB_PCIP_REG24, AccessWidth32, &Value, pConfig);
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Check if card required test for deskew workaround
+ *
+ *
+ *
+ *
+ *
+ */
+
+BOOLEAN
+PcieIsDeskewCardDetected (
+ IN UINT16 DeviceId
+ )
+{
+ if ((DeviceId >= 0x3150 && DeviceId <= 0x3152) || (DeviceId == 0x3154) ||
+ (DeviceId == 0x3E50) || (DeviceId == 0x3E54) ||
+ ((DeviceId & 0xfff8) == 0x5460) || ((DeviceId & 0xfff8) == 0x5B60)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Check if we can accsee to EP. Wait for up to 1 sec if EP requred extra time to initialize.
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+PcieEpReadyWorkaround (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ PORT PortId;
+ UINT8 TempBus;
+ PCI_ADDR Device;
+ TempBus = (UINT8) (pConfig->NbPciAddress.Address.Bus + 5);
+ Device.AddressValue = MAKE_SBDFO (0, TempBus, 0, 0, 0);
+ for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
+ PCI_ADDR Port;
+ Port.AddressValue = MAKE_SBDFO (0, pConfig->NbPciAddress.Address.Bus , PortId, 0, 0);
+ if (LibNbIsDevicePresent (Port, pConfig)) {
+ UINT32 LinkState;
+ LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, pConfig);
+ LinkState &= 0x3F;
+ if (LinkState == 0x10) {
+ BOOLEAN IsDevicePresent;
+ UINT32 PortBusConfiguration;
+ UINT32 Count;
+ Count = 1000;
+ LibNbPciRead (Port.AddressValue | 0x18, AccessWidth32, &PortBusConfiguration, pConfig);
+ LibNbPciRMW (Port.AddressValue | 0x18, AccessWidth32, 0x0, (TempBus << 8) | (TempBus << 16), pConfig);
+ do {
+ IsDevicePresent = LibNbIsDevicePresent (Device, pConfig);
+ STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, CIMX_S3_SAVE);
+ } while (IsDevicePresent == FALSE && Count-- != 0 );
+ LibNbPciWrite (Port.AddressValue | 0x18, AccessWidth32, &PortBusConfiguration, pConfig);
+ }
+ }
+ }
+}
+
+UINT16 AspmBrDeviceTable[] = {
+ 0x1002, 0x9441, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10B5, 0xFFFF, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0402, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0193, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0422, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0292, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x00F9, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0141, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0092, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D0, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D1, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D2, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D3, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D5, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D7, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01D8, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01DC, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01DE, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x01DF, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x016A, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x10DE, 0x0392, (UINT16)~(ASPM_L1 | ASPM_L0s),
+ 0x168C, 0xFFFF, (UINT16)~(ASPM_L0s)
+};
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Misc PCIe ASPM workarounds
+ *
+ * @param[in] AspmLinkInfoPtr Pointer to link ASPM info.
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+PcieAspmWorkarounds (
+ IN OUT ASPM_LINK_INFO *AspmLinkInfoPtr,
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ UINT32 UpstreamDeviceId;
+ UINT32 DownstreamDeviceId;
+ UINTN i;
+ LibNbPciRead (AspmLinkInfoPtr->UpstreamPort.AddressValue, AccessWidth32, &UpstreamDeviceId, pConfig);
+ LibNbPciRead (AspmLinkInfoPtr->UpstreamPort.AddressValue, AccessWidth32, &DownstreamDeviceId, pConfig);
+ for (i = 0; i < (sizeof (AspmBrDeviceTable) / sizeof (UINT16)); i = i + 3) {
+ UINT32 DeviceId;
+ UINT32 VendorId;
+ VendorId = AspmBrDeviceTable[i];
+ DeviceId = AspmBrDeviceTable[i + 1];
+ if (VendorId == (UINT16)UpstreamDeviceId || VendorId == (UINT16)DownstreamDeviceId ) {
+ if (DeviceId == 0xFFFF || DeviceId == (UpstreamDeviceId >> 16) || DeviceId == (DownstreamDeviceId >> 16)) {
+ AspmLinkInfoPtr->UpstreamLx &= AspmBrDeviceTable[i + 2];
+ AspmLinkInfoPtr->DownstreamLx &= AspmBrDeviceTable[i + 2];
+ }
+ }
+ }
+ if ((UINT16)UpstreamDeviceId == 0x168c) {
+ // Atheros (Ignore dev capability enable L1 if requested)
+ AspmLinkInfoPtr->UpstreamLx = AspmLinkInfoPtr->RequestedLx & ASPM_L1;
+ AspmLinkInfoPtr->DownstreamLx = AspmLinkInfoPtr->UpstreamLx;
+ LibNbPciRMW (AspmLinkInfoPtr->UpstreamPort.AddressValue | 0x70C, AccessS3SaveWidth32, 0x0, 0x0F003F01, pConfig);
+ }
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h
new file mode 100644
index 0000000000..4d72386ea2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h
@@ -0,0 +1,65 @@
+/**
+ * @file
+ *
+ * PCIe support for misc Southbridges.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBPCIEWORKAROUNDS_H_
+#define _NBPCIEWORKAROUNDS_H_
+
+
+AGESA_STATUS
+PcieGfxWorkarounds (
+ IN PORT PortId,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieEpReadyWorkaround (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+VOID
+PcieAspmWorkarounds (
+ IN OUT ASPM_LINK_INFO *AspmLinkInfoPtr,
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c b/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c
new file mode 100644
index 0000000000..cde7d06b18
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c
@@ -0,0 +1,383 @@
+/**
+ * @file
+ *
+ * Power on Reset register initialization.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+#include "amdDebugOutLib.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+AGESA_STATUS
+NbPorInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+/// PCI registers init table
+CONST REGISTER_ENTRY NbPorPciTable[] = {
+ {NB_PCI_REG04, 0xFD, 0x02},
+//Reg84h[4]=1 (EV6MODE) to allow decode of 640k-1MB
+ {NB_PCI_REG84, 0xEF, 0x10},
+//Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
+//Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
+ {NB_PCI_REG4C, 0x00, 0x42},
+//Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
+//Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge
+ {NB_PCI_REG4E, 0xFF, 0x05},
+//Set temporary NB TOM to 0xE0000000
+ {NB_PCI_REG90 + 3, 0x00, 0xE0}
+};
+
+/// MISCIND registers init table
+CONST INDIRECT_REG_ENTRY NbPorMiscTable[] = {
+// NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
+// Block non-snoop DMA request if PMArbDis is set.
+// Set BMSetDis
+ {
+ NB_MISC_REG0B,
+ 0xFFFF0000,
+ 0x00000180
+ },
+// NBCFG (NBMISCIND 0x0): NB_CNTL -
+// HIDE_NB_AGP_CAP ([0], default=1)HIDE
+// HIDE_P2P_AGP_CAP ([1], default=1)HIDE
+// HIDE_NB_GART_BAR ([2], default=1)HIDE
+// HIDE_MMCFG_BAR ([3], default=1)HIDE
+// AGPMODE30 ([4], default=0)DISABLE
+// AGP30ENCHANCED ([5], default=0)DISABLE
+// HIDE_AGP_CAP ([8], default=1)ENABLE
+ {
+ NB_MISC_REG00,
+ 0xFFFF0000,
+ 0x0000010e
+ },
+//NBMISIND:0x01 Bit[8]=1 IOC will forward the byte-enable (BE), which is 16'b0 for zero-byte reads, of the PCIE DMA request upstream to HTIU.
+//NBMISIND:0x01 Bit[9]=1 zero-byte reads.
+ {
+ NB_MISC_REG01,
+ 0xFFFFFFFF,
+ 0x00000310
+ },
+//NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow PWM features to work.
+ {
+ NB_MISC_REG40,
+ 0xffffffff,
+ 0x00000500
+ },
+//Enable slot power message
+ {
+ NB_MISC_REG51,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG53,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG55,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG57,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG59,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG5B,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG5D,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG5F,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG61,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG63,
+ 0x00000000,
+ 0x00100106
+ },
+ {
+ NB_MISC_REG1F,
+ 0x00000000,
+ 0x00100106
+ },
+//NBMISCIND:0x0C[13]= 1 Enables GSM Mode.
+ {
+ NB_MISC_REG0C,
+ 0xffffffff,
+ BIT13 + BIT20
+ },
+//NBMISCIND:0x12[16]= 1 ReqID for GPP1 and GPP2
+//NBMISCIND:0x12[17]= 1 ReqID for GPP3a, GPP3b, SB
+//NBMISCIND:0x12[18]= 0 ReqID override for SB
+//NBMISCIND:0x12[19]= 1 Enable INT accumulators
+//NBMISCIND:0x12[20, 21, 23]= 1 4103, 4125, 4155 4186 (A21).
+//NBMISCIND:0x12[22]=0 Prevent spurious DR of UMA request (RPR 5.9.3)
+ {
+ NB_MISC_REG12,
+ (UINT32)~(BIT18 + BIT22),
+ 0xBB0000
+ },
+//NBMISCIND:0x75[15.13,16..18,21..19,24..22,25..25] = 0x4 Enable AER
+//NBMISCIND:0x75[29]= 1 Device ID for hotplug and PME message.
+ {
+ NB_MISC_REG75,
+ (UINT32)~BIT28,
+ (4 << 13) | (4 << 16) | (4 << 19) | (4 << 22) | (4 << 25) | BIT29
+ },
+//PCIe CDR setting
+ {
+ NB_MISC_REG38,
+ 0xffffffff,
+ BIT6 + BIT7 + BIT14 + BIT15 + BIT22 + BIT23
+ },
+ {
+ NB_MISC_REG67,
+ 0xffffffff,
+ BIT21 + BIT22
+ },
+ {
+ NB_MISC_REG2C,
+ (UINT32)~(BIT0 + BIT1 + BIT19),
+ BIT0 + BIT1
+ },
+ {
+ NB_MISC_REG6C,
+ (UINT32)~(BIT10),
+ 0x0
+ },
+ {
+ NB_MISC_REG34,
+ (UINT32)~(BIT7 + BIT15 + BIT23),
+ 0x0
+ },
+ {
+ NB_MISC_REG37,
+ (UINT32)~(0xffful << 20),
+ (0xdddul << 20)
+ },
+ {
+ NB_MISC_REG68,
+ (UINT32)~(0xful << 16),
+ (0xd << 16)
+ },
+ {
+ NB_MISC_REG2B,
+ (UINT32)~(0xful << 24 ),
+ (0xd << 24)
+ },
+ // Enable ACS capability
+ {
+ NB_MISC_REG6A,
+ 0xffffffff,
+ BIT2
+ }
+};
+
+/// HTIUIND registers init table
+CONST INDIRECT_REG_ENTRY NbPorHtiuTable[] = {
+//HTIU x 05 [8] = 0x0 Enables PC checking for FCB release.
+//HTIU x 05 [13,13,3,14,10,12,17,18,15,4,6,19] = 0x1 Misc (A21)
+ {NB_HTIU_REG05, 0xFFFFFEFF, BIT8 + BIT16 + BIT13 + BIT3 + BIT14 + BIT10 + BIT12 + BIT17 + BIT18 + BIT15 +
+ BIT4 + BIT6 + BIT19 },
+ //HTIU x 06 [0] = 0x0 Enables writes to pass in-progress reads
+//HTIU x 06 [1] = 0x1 Enables streaming of CPU writes
+//HTIU x 06 [9] = 0x1 Enables extended write buffer for CPU writes
+//HTIU x 06 [13] = 0x1 Enables additional response buffers
+//HTIU x 06 [17] = 0x1 Enables special reads to pass writes
+//HTIU x 06 [16:15] = 0x3 Enables decoding of C1e/C3 and FID cycles
+//HTIU x 06 [25] = 0x1 Enables HTIU-display handshake bypass.
+//HTIU x 06 [30] = 0x1 Enables tagging fix
+ {NB_HTIU_REG06, 0xFFFFFFFE, 0x04203A202},
+//HTIU x 07 [0] = 0x1 Enables byte-write optimization for IOC requests
+//HTIU x 07 [1] = 0x0 Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used.
+//HTIU x 07 [2] = 0x0 Disables upstream system-management delay
+ {NB_HTIU_REG07, 0xFFFFFFF9, 0x0001 },
+//HTIU x 1C [31:17]=0xfff i.e. 0001 1111 1111 111 or 1FFE Enables all traffic to be detected as GSM traffic.
+ {NB_HTIU_REG1C, 0xFFFFFFFF, 0x1ffe0000 },
+//HTIU x 15 [27]=0x1 Powers down the chipset DLLs in the LS2 state.
+ {NB_HTIU_REG15, 0xFFFFFFFF, BIT27 },
+//Enable transmit PHY to reinitialize in HT1 mode when tristate is enabled
+//HTIU x 16 [10]=0x1 enable proper DLL reset sequence.
+ {NB_HTIU_REG16, 0xFFFFFFFF, BIT11 + BIT10},
+//HTIU x 2A [1:0]=0x1 Optimize chipset HT transmitter drive strength
+ {NB_HTIU_REG2A, 0xfffffffc, 0x00000001 }
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Amd Power on Reset Initialization for all NB.
+ *
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+
+AGESA_STATUS
+AmdPowerOnResetInit (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+
+ Status = LibNbApiCall (NbPowerOnResetInit, ConfigPtr);
+ return Status;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * NB Power on Reset Initialization.
+ * Basic registers initialization.
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+
+AGESA_STATUS
+NbPowerOnResetInit (
+ IN AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ REGISTER_ENTRY *pTable;
+ UINTN i;
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPOR_TRACE), "[NBPOR]NbPowerOnResetInit Enter\n"));
+ Status = NbPorInitValidateInput (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr);
+ CIMX_ASSERT (FALSE);
+ return Status;
+ }
+ //Init Pci Registers
+ pTable = (REGISTER_ENTRY*)FIX_PTR_ADDR (&NbPorPciTable[0], NULL);
+ for (i = 0; i < (sizeof (NbPorPciTable) / sizeof (REGISTER_ENTRY)); i++) {
+ LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | pTable->Register, AccessWidth8, pTable->Mask, pTable->Data, NbConfigPtr);
+ ++pTable;
+ }
+ //Init Misc registers
+ LibNbIndirectTableInit (
+ NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbPorMiscTable[0], NULL),
+ (sizeof (NbPorMiscTable) / sizeof (INDIRECT_REG_ENTRY)),
+ NbConfigPtr
+ );
+
+ //Init Htiu registers
+ LibNbIndirectTableInit (
+ NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbPorHtiuTable[0],NULL),
+ (sizeof (NbPorHtiuTable) / sizeof (INDIRECT_REG_ENTRY)),
+ NbConfigPtr
+ );
+
+ CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPOR_TRACE), "[NBPOR]NbPowerOnResetInit Exit\n"));
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Validate input parameters
+ *
+ *
+ *
+ *
+ * @param[in] pConfig Northbridge configuration structure pointer.
+ */
+
+
+AGESA_STATUS
+NbPorInitValidateInput (
+ IN AMD_NB_CONFIG *pConfig
+ )
+{
+ return (LibNbGetRevisionInfo (pConfig).Type == NB_UNKNOWN)?AGESA_FATAL:AGESA_SUCCESS;
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbRecovery.c b/src/vendorcode/amd/cimx/rd890/nbRecovery.c
new file mode 100644
index 0000000000..71c6959a25
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbRecovery.c
@@ -0,0 +1,192 @@
+/**
+ * @file
+ *
+ * Recovery support
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+/// PCI registers init table
+CONST REGISTER_ENTRY NbRecoveryPorPciTable[] = {
+ {NB_PCI_REG04,0xFD,0x02},
+//Reg84h[4]=1 (EV6MODE) to allow decode of 640k-1MB
+ {NB_PCI_REG84,0xEF,0x10},
+//Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
+//Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
+ {NB_PCI_REG4C,0x00,0x42},
+//Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
+//Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge
+ {NB_PCI_REG4E,0xFF,0x05},
+//Set temporary NB TOM to 0xE0000000
+ {NB_PCI_REG90 + 3, 0x00, 0xE0}
+};
+
+/// MISCIND registers init table
+CONST INDIRECT_REG_ENTRY NbRecoveryPorMiscTable[] = {
+// NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
+// Block non-snoop DMA request if PMArbDis is set.
+// Set BMSetDis
+ {NB_MISC_REG0B, 0xFFFF0000, 0x00000180},
+// NBCFG (NBMISCIND 0x0): NB_CNTL -
+// HIDE_NB_AGP_CAP ([0], default=1)HIDE
+// HIDE_P2P_AGP_CAP ([1], default=1)HIDE
+// HIDE_NB_GART_BAR ([2], default=1)HIDE
+// HIDE_MMCFG_BAR ([3], default=1)HIDE
+// AGPMODE30 ([4], default=0)DISABLE
+// AGP30ENCHANCED ([5], default=0)DISABLE
+// HIDE_AGP_CAP ([8], default=1)ENABLE
+ {NB_MISC_REG00, 0xFFFF0000, 0x0000010e},
+ {NB_MISC_REG01, 0xFFFFFFFF, 0x00000010},
+ {NB_MISC_REG0C, 0xFFFFFFFF, 0x001f00FC},
+//NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow PWM features to work.
+ {NB_MISC_REG40, 0xffffffff, 0x00000500},
+};
+
+/// HTIUIND registers init table
+INDIRECT_REG_ENTRY NbRecoveryPorHtiuTable[] = {
+//HTIU x 06 [0] = 0x0 Enables writes to pass in-progress reads
+//HTIU x 06 [1] = 0x1 Enables streaming of CPU writes
+//HTIU x 06 [9] = 0x1 Enables extended write buffer for CPU writes
+//HTIU x 06 [13] = 0x1 Enables additional response buffers
+//HTIU x 06 [17] = 0x1 Enables special reads to pass writes
+//HTIU x 06 [16:15] = 0x3 Enables decoding of C1e/C3 and FID cycles
+//HTIU x 06 [25] = 0x1 Enables HTIU-display handshake bypass.
+//HTIU x 06 [30] = 0x1 Enables tagging fix
+ {NB_HTIU_REG06, 0xFFFFFFFE, 0x04203A202},
+//HTIU x 07 [0] = 0x1 Enables byte-write optimization for IOC requests
+//HTIU x 07 [1] = 0x0 Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used.
+//HTIU x 07 [2] = 0x0 Disables upstream system-management delay
+ {NB_HTIU_REG07, 0xFFFFFFF9, 0x0001 },
+//HTIU x 1C [31:17]=0xfff i.e. 0001 1111 1111 111 or 1FFE Enables all traffic to be detected as GSM traffic.
+ {NB_HTIU_REG1C, 0xFFFFFFFF, 0x1ffe0000 }, //vsj-2007-09-04
+//Enable transmit PHY to reinitialize in HT1 mode when tristate is enabled
+ {NB_HTIU_REG16, 0xFFFFFFFF, BIT11 },
+//HTIU x 2A [1:0]=0x1 Optimize chipset HT transmitter drive strength
+ {NB_HTIU_REG2A, 0xfffffffc, 0x00000001 }
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Northbridge Power on Reset Initialization for all NB in system.
+ *
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+
+AGESA_STATUS
+AmdPowerOnResetInit (
+ IN AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ REGISTER_ENTRY *pTable;
+ AMD_NB_CONFIG *pConfig;
+ UINTN i;
+
+ pConfig = &ConfigPtr->Northbridges[0];
+ pTable = (REGISTER_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorPciTable[0], NULL);
+ for (i = 0; i < (sizeof (NbRecoveryPorPciTable) / sizeof (REGISTER_ENTRY)); i++) {
+ LibNbPciRMW (pConfig->NbPciAddress.AddressValue | pTable->Register, AccessWidth8, pTable->Mask, pTable->Data, pConfig);
+ ++pTable;
+ }
+ //Init Misc registers
+ LibNbIndirectTableInit (
+ ConfigPtr->Northbridges[0].NbPciAddress.AddressValue | NB_MISC_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorMiscTable[0],NULL),
+ (sizeof (NbRecoveryPorMiscTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+
+ //Init Htiu registers
+ LibNbIndirectTableInit (
+ ConfigPtr->Northbridges[0].NbPciAddress.AddressValue | NB_HTIU_INDEX,
+ 0,
+ (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorHtiuTable[0], NULL),
+ (sizeof (NbRecoveryPorHtiuTable) / sizeof (INDIRECT_REG_ENTRY)),
+ pConfig
+ );
+
+ return AGESA_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize misc setting
+ *
+ *
+ *
+ * @param[in] NbConfigPtr Northbridge configuration structure pointer.
+ *
+ */
+
+AGESA_STATUS
+MiscRecoveryInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ )
+{
+ return AGESA_SUCCESS;
+}
+
+
diff --git a/src/vendorcode/amd/cimx/rd890/nbRecovery.h b/src/vendorcode/amd/cimx/rd890/nbRecovery.h
new file mode 100644
index 0000000000..e6b04c0be4
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbRecovery.h
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * NB definitions
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBRECOVERY_H_
+#define _NBRECOVERY_H_
+
+
+AGESA_STATUS
+MiscRecoveryInitializer (
+ IN OUT AMD_NB_CONFIG *NbConfigPtr
+ );
+
+#endif \ No newline at end of file
diff --git a/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c b/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c
new file mode 100644
index 0000000000..f9b6132a14
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c
@@ -0,0 +1,98 @@
+/**
+ * @file
+ *
+ * Recovery support
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#include "NbPlatform.h"
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * AMD structures initializer for recovery.
+ *
+ *
+ *
+ * @param[in] ConfigPtr Northbridges configuration block pointer.
+ *
+ */
+
+AGESA_STATUS
+AmdInitializer (
+ IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
+ )
+{
+ AGESA_STATUS Status;
+ AMD_NB_CONFIG *NbConfigPtr;
+ NbConfigPtr = &ConfigPtr->Northbridges[0];
+ Status = MiscRecoveryInitializer (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ return Status;
+ }
+#ifdef PCIE_RECOVERY_SUPPORT
+ Status = PcieRecoveryInitializer (NbConfigPtr);
+ if (Status == AGESA_FATAL) {
+ return Status;
+ }
+#endif
+ return Status;
+
+}
diff --git a/src/vendorcode/amd/cimx/rd890/nbRegisters.h b/src/vendorcode/amd/cimx/rd890/nbRegisters.h
new file mode 100644
index 0000000000..621f1e9602
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbRegisters.h
@@ -0,0 +1,420 @@
+/**
+ * @file
+ *
+ * Registers definition.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBREGISTERS_H_
+#define _NBREGISTERS_H_
+
+#define NB_PCI_REG04 0x04
+#define NB_PCI_REG1C 0x1C
+#define NB_PCI_REG44 0x44
+#define NB_PCI_REG4C 0x4C
+#define NB_PCI_REG4E 0x4E
+#define NB_PCI_REG50 0x50
+#define NB_PCI_REG54 0x54
+#define NB_PCI_REG58 0x58
+#define NB_PCI_REG5C 0x5c
+#define NB_PCI_REG60 0x60
+#define NB_PCI_REG78 0x78
+#define NB_PCI_REG7C 0x7C
+#define NB_PCI_REG7F 0x7f
+#define NB_PCI_REG95 0x95
+#define NB_PCI_REG97 0x97
+#define NB_PCI_REG80 0x80
+#define NB_PCI_REG84 0x84
+#define NB_PCI_REG8C 0x8C
+#define NB_PCI_REG8D 0x8D
+#define NB_PCI_REG90 0x90
+#define NB_PCI_REG94 0x94
+#define NB_PCI_REG98 0x98
+#define NB_PCI_REG9C 0x9C
+#define NB_PCI_REGA0 0xA0
+#define NB_PCI_REGA4 0xA4
+#define NB_PCI_REGA6 0xA6
+#define NB_PCI_REGA7 0xA7
+#define NB_PCI_REGA8 0xA8
+#define NB_PCI_REGAC 0xAC
+#define NB_PCI_REGC8 0xC8
+#define NB_PCI_REGCB 0xCB
+#define NB_PCI_REGD1 0xD1
+#define NB_PCI_REGD2 0xD2
+#define NB_PCI_REGE0 0xE0
+#define NB_PCI_REGE8 0xE8
+#define NB_PCI_REGF8 0xF8
+#define NB_PCI_REGFC 0xFC
+
+#define NB_APC_REG04 0x04
+#define NB_APC_REG18 0x18
+
+/******************************************************************************************
+; PCIE Port PCI config registers
+;******************************************************************************************/
+
+#define NB_PCIP_REG04 0x04
+#define NB_PCIP_REG18 0x18
+#define NB_PCIP_REG19 0x19
+#define NB_PCIP_REG20 0x20
+#define NB_PCIP_REG24 0x24
+#define NB_PCIP_REG3D 0x3D
+#define NB_PCIP_REG5A 0x5A
+#define NB_PCIP_REG64 0x64
+#define NB_PCIP_REG68 0x68
+#define NB_PCIP_REG6A 0x6A
+#define NB_PCIP_REG6B 0x6b
+#define NB_PCIP_REG6C 0x6c
+#define NB_PCIP_REG70 0x70
+#define NB_PCIP_REG72 0x72
+#define NB_PCIP_REG80 0x80
+#define NB_PCIP_REG88 0x88
+#define NB_PCIP_REGE0 0xE0
+#define NB_PCIP_REG108 0x108
+#define NB_PCIP_REG124 0x124
+#define NB_PCIP_REG12A 0x12A
+#define NB_PCIP_REG130 0x130
+#define NB_PCIP_REG134 0x134
+
+
+/******************************************************************************************
+; HTIUNBIND register definition
+;******************************************************************************************/
+
+#define NB_HTIU_INDEX NB_PCI_REG94
+#define HTIU_WRITE 0x100
+
+#define NB_HTIU_REG05 (0x05 | HTIU_WRITE)
+#define NB_HTIU_REG06 (0x06 | HTIU_WRITE)
+#define NB_HTIU_REG07 (0x07 | HTIU_WRITE)
+#define NB_HTIU_REG0C (0x0C | HTIU_WRITE)
+#define NB_HTIU_REG12 (0x12 | HTIU_WRITE)
+#define NB_HTIU_REG15 (0x15 | HTIU_WRITE)
+#define NB_HTIU_REG16 (0x16 | HTIU_WRITE)
+#define NB_HTIU_REG17 (0x17 | HTIU_WRITE)
+#define NB_HTIU_REG19 (0x19 | HTIU_WRITE)
+#define NB_HTIU_REG1A (0x1A | HTIU_WRITE)
+#define NB_HTIU_REG1C (0x1C | HTIU_WRITE)
+#define NB_HTIU_REG1D (0x1D | HTIU_WRITE)
+#define NB_HTIU_REG1E (0x1E | HTIU_WRITE)
+#define NB_HTIU_REG2A (0x2A | HTIU_WRITE)
+#define NB_HTIU_REG2D (0x2D | HTIU_WRITE)
+#define NB_HTIU_REG30 (0x30 | HTIU_WRITE)
+#define NB_HTIU_REG31 (0x31 | HTIU_WRITE)
+#define NB_HTIU_REG32 (0x32 | HTIU_WRITE)
+#define NB_HTIU_REG34 (0x34 | HTIU_WRITE)
+#define NB_HTIU_REG37 (0x37 | HTIU_WRITE)
+#define NB_HTIU_REG3A (0x3A | HTIU_WRITE)
+#define NB_HTIU_REG3B (0x3B | HTIU_WRITE)
+#define NB_HTIU_REG3C (0x3C | HTIU_WRITE)
+#define NB_HTIU_REG46 (0x46 | HTIU_WRITE)
+#define NB_HTIU_REG4B (0x4B | HTIU_WRITE)
+#define NB_HTIU_REG50 (0x50 | HTIU_WRITE)
+#define NB_HTIU_REG55 (0x55 | HTIU_WRITE)
+#define NB_HTIU_REG56 (0x56 | HTIU_WRITE)
+#define NB_HTIU_REG57 (0x57 | HTIU_WRITE)
+#define NB_HTIU_REG58 (0x58 | HTIU_WRITE)
+#define NB_HTIU_REG59 (0x59 | HTIU_WRITE)
+#define NB_HTIU_REG5A (0x5A | HTIU_WRITE)
+#define NB_HTIU_REG5C (0x5C | HTIU_WRITE)
+#define NB_HTIU_REG5D (0x5D | HTIU_WRITE)
+#define NB_HTIU_REG5E (0x5E | HTIU_WRITE)
+#define NB_HTIU_REG5F (0x5F | HTIU_WRITE)
+#define NB_HTIU_REG60 (0x60 | HTIU_WRITE)
+#define NB_HTIU_REG61 (0x61 | HTIU_WRITE)
+#define NB_HTIU_REG62 (0x62 | HTIU_WRITE)
+#define NB_HTIU_REG63 (0x63 | HTIU_WRITE)
+#define NB_HTIU_REG64 (0x64 | HTIU_WRITE)
+#define NB_HTIU_REG65 (0x65 | HTIU_WRITE)
+#define NB_HTIU_REG66 (0x66 | HTIU_WRITE)
+#define NB_HTIU_REG68 (0x68 | HTIU_WRITE)
+#define NB_HTIU_REG6B (0x6B | HTIU_WRITE)
+#define NB_HTIU_REG6D (0x6D | HTIU_WRITE)
+#define NB_HTIU_REG70 (0x70 | HTIU_WRITE)
+#define NB_HTIU_REG71 (0x71 | HTIU_WRITE)
+#define NB_HTIU_REG72 (0x72 | HTIU_WRITE)
+#define NB_HTIU_REG73 (0x73 | HTIU_WRITE)
+#define NB_HTIU_REG74 (0x74 | HTIU_WRITE)
+#define NB_HTIU_REG75 (0x75 | HTIU_WRITE)
+#define NB_HTIU_REG87 (0x87 | HTIU_WRITE)
+#define NB_HTIU_REG88 (0x88 | HTIU_WRITE)
+#define NB_HTIU_REGA8 (0xA8 | HTIU_WRITE)
+#define NB_HTIU_REGA9 (0xA9 | HTIU_WRITE)
+
+/******************************************************************************************
+; Clock Configuration register
+;******************************************************************************************/
+#define NB_CLK_REG48 0x48
+#define NB_CLK_REG4C 0x4C
+#define NB_CLK_REG5C 0x5C
+#define NB_CLK_REG60 0x60
+#define NB_CLK_REG78 0x78
+#define NB_CLK_REG84 0x84
+#define NB_CLK_REG8C 0x8C
+#define NB_CLK_REG90 0x90
+#define NB_CLK_REG94 0x94
+#define NB_CLK_REGB0 0xB0
+#define NB_CLK_REGB4 0xB4
+#define NB_CLK_REGCC 0xCC
+#define NB_CLK_REGD4 0xD4
+#define NB_CLK_REGD5 0xD5
+#define NB_CLK_REGD6 0xD6
+#define NB_CLK_REGD8 0xD8
+#define NB_CLK_REGE0 0xE0
+#define NB_CLK_REGE4 0xE4
+#define NB_CLK_REGE8 0xE8
+#define NB_CLK_REGF0 0xF0
+#define NB_CLK_REGF4 0xF4
+#define NB_CLK_REGF8 0xF8
+#define NB_CLK_REGF9 0xF9
+#define NB_CLK_REGFA 0xFA
+#define NB_CLK_REGFB 0xFB
+
+/******************************************************************************************
+; MISCIND/NBCFG register definition
+;******************************************************************************************/
+#define NB_MISC_INDEX NB_PCI_REG60
+#define MISC_WRITE 0x80
+
+#define NB_MISC_REG00 (0x00 | MISC_WRITE)
+#define NB_MISC_REG01 (0x01 | MISC_WRITE)
+#define NB_MISC_REG07 (0x07 | MISC_WRITE)
+#define NB_MISC_REG08 (0x08 | MISC_WRITE)
+#define NB_MISC_REG0B (0x0B | MISC_WRITE)
+#define NB_MISC_REG0C (0x0C | MISC_WRITE)
+#define NB_MISC_REG12 (0x12 | MISC_WRITE)
+#define NB_MISC_REG1E (0x1E | MISC_WRITE)
+#define NB_MISC_REG1F (0x1F | MISC_WRITE)
+#define NB_MISC_REG20 (0x20 | MISC_WRITE)
+#define NB_MISC_REG21 (0x21 | MISC_WRITE)
+#define NB_MISC_REG22 (0x22 | MISC_WRITE)
+#define NB_MISC_REG23 (0x23 | MISC_WRITE)
+#define NB_MISC_REG24 (0x24 | MISC_WRITE)
+#define NB_MISC_REG26 (0x26 | MISC_WRITE)
+#define NB_MISC_REG27 (0x27 | MISC_WRITE)
+#define NB_MISC_REG28 (0x28 | MISC_WRITE)
+#define NB_MISC_REG29 (0x29 | MISC_WRITE)
+#define NB_MISC_REG2A (0x2A | MISC_WRITE)
+#define NB_MISC_REG2B (0x2B | MISC_WRITE)
+#define NB_MISC_REG2C (0x2C | MISC_WRITE)
+#define NB_MISC_REG2D (0x2D | MISC_WRITE)
+#define NB_MISC_REG2E (0x2E | MISC_WRITE)
+#define NB_MISC_REG2F (0x2F | MISC_WRITE)
+#define NB_MISC_REG32 (0x32 | MISC_WRITE)
+#define NB_MISC_REG33 (0x33 | MISC_WRITE)
+#define NB_MISC_REG34 (0x34 | MISC_WRITE)
+#define NB_MISC_REG35 (0x35 | MISC_WRITE)
+#define NB_MISC_REG36 (0x36 | MISC_WRITE)
+#define NB_MISC_REG37 (0x37 | MISC_WRITE)
+#define NB_MISC_REG38 (0x38 | MISC_WRITE)
+#define NB_MISC_REG39 (0x39 | MISC_WRITE)
+#define NB_MISC_REG3A (0x3A | MISC_WRITE)
+#define NB_MISC_REG3B (0x3B | MISC_WRITE)
+#define NB_MISC_REG3C (0x3C | MISC_WRITE)
+#define NB_MISC_REG40 (0x40 | MISC_WRITE)
+#define NB_MISC_REG48 (0x48 | MISC_WRITE)
+#define NB_MISC_REG49 (0x49 | MISC_WRITE)
+#define NB_MISC_REG4A (0x4A | MISC_WRITE)
+#define NB_MISC_REG4B (0x4B | MISC_WRITE)
+#define NB_MISC_REG4E (0x4E | MISC_WRITE)
+#define NB_MISC_REG4F (0x4F | MISC_WRITE)
+#define NB_MISC_REG51 (0x51 | MISC_WRITE)
+#define NB_MISC_REG53 (0x53 | MISC_WRITE)
+#define NB_MISC_REG55 (0x55 | MISC_WRITE)
+#define NB_MISC_REG57 (0x57 | MISC_WRITE)
+#define NB_MISC_REG59 (0x59 | MISC_WRITE)
+#define NB_MISC_REG5B (0x5B | MISC_WRITE)
+#define NB_MISC_REG5D (0x5D | MISC_WRITE)
+#define NB_MISC_REG5F (0x5F | MISC_WRITE)
+#define NB_MISC_REG61 (0x61 | MISC_WRITE)
+#define NB_MISC_REG63 (0x63 | MISC_WRITE)
+#define NB_MISC_REG66 (0x66 | MISC_WRITE)
+#define NB_MISC_REG67 (0x67 | MISC_WRITE)
+#define NB_MISC_REG68 (0x68 | MISC_WRITE)
+#define NB_MISC_REG69 (0x69 | MISC_WRITE)
+#define NB_MISC_REG6A (0x6A | MISC_WRITE)
+#define NB_MISC_REG6B (0x6B | MISC_WRITE)
+#define NB_MISC_REG6C (0x6C | MISC_WRITE)
+#define NB_MISC_REG6F (0x6f | MISC_WRITE)
+#define NB_MISC_REG74 (0x74 | MISC_WRITE)
+#define NB_MISC_REG75 (0x75 | MISC_WRITE)
+#define NB_MISC_REG76 (0x76 | MISC_WRITE)
+#define NB_MISC_REG7D (0x7D | MISC_WRITE)
+
+/******************************************************************************************
+; MISCIND/NBCFG register definition
+;******************************************************************************************/
+#define NB_MC_INDEX NB_PCI_REGE8
+#define MC_WRITE 0x200
+
+#define NB_MC_REG01 (0x01 | MC_WRITE)
+#define NB_MC_REG02 (0x02 | MC_WRITE)
+#define NB_MC_REG04 (0x04 | MC_WRITE)
+#define NB_MC_REG05 (0x05 | MC_WRITE)
+#define NB_MC_REG06 (0x06 | MC_WRITE)
+#define NB_MC_REG07 (0x07 | MC_WRITE)
+#define NB_MC_REG08 (0x08 | MC_WRITE)
+#define NB_MC_REG09 (0x09 | MC_WRITE)
+#define NB_MC_REG0B (0x0B | MC_WRITE)
+#define NB_MC_REG0C (0x0C | MC_WRITE)
+#define NB_MC_REG0D (0x0D | MC_WRITE)
+#define NB_MC_REG0E (0x0E | MC_WRITE)
+#define NB_MC_REG0F (0x0F | MC_WRITE)
+#define NB_MC_REG10 (0x10 | MC_WRITE)
+#define NB_MC_REG11 (0x11 | MC_WRITE)
+#define NB_MC_REG12 (0x12 | MC_WRITE)
+#define NB_MC_REG13 (0x13 | MC_WRITE)
+#define NB_MC_REG14 (0x14 | MC_WRITE)
+#define NB_MC_REG16 (0x16 | MC_WRITE)
+#define NB_MC_REG23 (0x23 | MC_WRITE)
+#define NB_MC_REG25 (0x25 | MC_WRITE)
+#define NB_MC_REG29 (0x29 | MC_WRITE)
+#define NB_MC_REG2A (0x2A | MC_WRITE)
+#define NB_MC_REG2C (0x2C | MC_WRITE)
+#define NB_MC_REG30 (0x30 | MC_WRITE)
+#define NB_MC_REG3C (0x3C | MC_WRITE)
+#define NB_MC_REG3D (0x3D | MC_WRITE)
+#define NB_MC_REG49 (0x49 | MC_WRITE)
+#define NB_MC_REG4A (0x4A | MC_WRITE)
+#define NB_MC_REG4B (0x4B | MC_WRITE)
+#define NB_MC_REG4C (0x4C | MC_WRITE)
+#define NB_MC_REG4D (0x4D | MC_WRITE)
+#define NB_MC_REGA0 (0xA0 | MC_WRITE)
+#define NB_MC_REGA1 (0xA1 | MC_WRITE)
+#define NB_MC_REGA2 (0xA2 | MC_WRITE)
+#define NB_MC_REGA3 (0xA3 | MC_WRITE)
+#define NB_MC_REGA4 (0xA4 | MC_WRITE)
+#define NB_MC_REGA5 (0xA5 | MC_WRITE)
+#define NB_MC_REGA6 (0xA6 | MC_WRITE)
+#define NB_MC_REGA7 (0xA7 | MC_WRITE)
+#define NB_MC_REGA8 (0xA8 | MC_WRITE)
+#define NB_MC_REGAA (0xAA | MC_WRITE)
+#define NB_MC_REGAF (0xAF | MC_WRITE)
+#define NB_MC_REGB0 (0xB0 | MC_WRITE)
+#define NB_MC_REGB2 (0xB2 | MC_WRITE)
+#define NB_MC_REGB1 (0xB1 | MC_WRITE)
+#define NB_MC_REGB4 (0xB4 | MC_WRITE)
+#define NB_MC_REGB5 (0xB5 | MC_WRITE)
+#define NB_MC_REGB6 (0xB6 | MC_WRITE)
+#define NB_MC_REGB7 (0xB7 | MC_WRITE)
+#define NB_MC_REGB8 (0xB8 | MC_WRITE)
+#define NB_MC_REGB9 (0xB9 | MC_WRITE)
+#define NB_MC_REGBA (0xBA | MC_WRITE)
+#define NB_MC_REGC1 (0xC1 | MC_WRITE)
+#define NB_MC_REGC2 (0xC2 | MC_WRITE)
+#define NB_MC_REGC3 (0xC3 | MC_WRITE)
+#define NB_MC_REGC4 (0xC4 | MC_WRITE)
+#define NB_MC_REGC5 (0xC5 | MC_WRITE)
+#define NB_MC_REGC8 (0xC8 | MC_WRITE)
+#define NB_MC_REGC9 (0xC9 | MC_WRITE)
+#define NB_MC_REGCA (0xCA | MC_WRITE)
+#define NB_MC_REGCB (0xCB | MC_WRITE)
+#define NB_MC_REGCC (0xCC | MC_WRITE)
+#define NB_MC_REGCE (0xCE | MC_WRITE)
+#define NB_MC_REGD0 (0xD0 | MC_WRITE)
+#define NB_MC_REGD2 (0xD2 | MC_WRITE)
+#define NB_MC_REGD3 (0xD3 | MC_WRITE)
+#define NB_MC_REGD6 (0xD6 | MC_WRITE)
+#define NB_MC_REGD7 (0xD7 | MC_WRITE)
+#define NB_MC_REGD8 (0xD8 | MC_WRITE)
+#define NB_MC_REGD9 (0xD9 | MC_WRITE)
+#define NB_MC_REGE0 (0xE0 | MC_WRITE)
+#define NB_MC_REGE1 (0xE1 | MC_WRITE)
+#define NB_MC_REGE8 (0xE8 | MC_WRITE)
+#define NB_MC_REGE9 (0xE9 | MC_WRITE)
+#define NB_MC_REGF0 (0xF0 | MC_WRITE)
+
+/******************************************************************************************
+; PCIEIND_P(BIFNBP) register definition
+;******************************************************************************************/
+#define NB_BIF_INDEX NB_PCI_REGE0
+
+#define NB_BIFNBP_REG01 0x01
+#define NB_BIFNBP_REG02 0x02
+#define NB_BIFNBP_REG10 0x10
+#define NB_BIFNBP_REG20 0x20
+#define NB_BIFNBP_REG40 0x40
+#define NB_BIFNBP_REG50 0x50
+#define NB_BIFNBP_REG70 0x70
+#define NB_BIFNBP_REGA0 0xA0
+#define NB_BIFNBP_REGA1 0xA1
+#define NB_BIFNBP_REGA2 0xA2
+#define NB_BIFNBP_REGA3 0xA3
+#define NB_BIFNBP_REGA4 0xA4
+#define NB_BIFNBP_REGA5 0xA5
+#define NB_BIFNBP_REGB1 0xB1
+#define NB_BIFNBP_REGC0 0xC0
+#define NB_BIFNBP_REGC1 0xC1
+
+/******************************************************************************************
+; PCIEIND(BIFNB) register definition
+;******************************************************************************************/
+#define NB_BIFNB_REG01 0x01
+#define NB_BIFNB_REG02 0x02
+#define NB_BIFNB_REG10 0x10
+#define NB_BIFNB_REG11 0x11
+#define NB_BIFNB_REG1C 0x1C
+#define NB_BIFNB_REG20 0x20
+#define NB_BIFNB_REG40 0x40
+#define NB_BIFNB_REG65 0x65
+#define NB_BIFNB_REGC1 0xC1
+#define NB_BIFNB_REGC2 0xC2
+#define NB_BIFNB_REGF9 0xF9
+
+
+#define MC_CLK_INDEX 0x60
+
+/******************************************************************************************
+; IOAPICCFG register definition
+;******************************************************************************************/
+#define NB_IOAPICCFG_INDEX NB_PCI_REGF8
+
+#define NB_IOAPICCFG_REG00 0x00
+#define NB_IOAPICCFG_REG01 0x01
+#define NB_IOAPICCFG_REG02 0x02
+#define NB_IOAPICCFG_REG03 0x03
+#define NB_IOAPICCFG_REG04 0x04
+#define NB_IOAPICCFG_REG05 0x05
+#define NB_IOAPICCFG_REG06 0x06
+#define NB_IOAPICCFG_REG07 0x07
+#define NB_IOAPICCFG_REG08 0x08
+#define NB_IOAPICCFG_REG09 0x09
+#define NB_IOAPICCFG_REG0A 0x0A
+
+#endif
diff --git a/src/vendorcode/amd/cimx/rd890/nbType.h b/src/vendorcode/amd/cimx/rd890/nbType.h
new file mode 100644
index 0000000000..ef224c3cb2
--- /dev/null
+++ b/src/vendorcode/amd/cimx/rd890/nbType.h
@@ -0,0 +1,1075 @@
+/*
+ * @file
+ *
+ * Misc definitions.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: CIMx-NB
+ * @e sub-project:
+ * @e \$Revision:$ @e \$Date:$
+ *
+ */
+/*****************************************************************************
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ***************************************************************************/
+
+#ifndef _NBTYPE_H_
+#define _NBTYPE_H_
+
+//#pragma pack(push, 1) //GCC ERROR
+
+#define CIMX_NB_REVISION "1.0.1.7"
+#define CIMX_NB_ID "SR5690"
+
+#ifndef MAX_NB_COUNT
+ //#define MAX_NB_COUNT 4
+ #error hi, MAX_NB_COUNT not define
+#endif
+
+#define MAX_PORT_ID 13
+#define MIN_PORT_ID 2
+
+#define MAX_CORE_ID 4
+
+
+typedef UINT32 PORT;
+typedef UINT32 CORE;
+
+
+
+/// The HT Path to Northbridge
+typedef struct {
+ UINT8 NodeID; ///< Node ID
+ UINT8 LinkID; /**< HT Link ID
+ * @par
+ * LinkID[3:0]- Link Id
+ * @li <b>0</b> - Link 0
+ * @li <b>1</b> - Link 1
+ * @li <b>2</b> - Link 2
+ * @li <b>3</b> - Link 3
+ * @par
+ * LinkID[7:4]- Sublink Id
+ * @li <b>1</b> - Sublink 0
+ * @li <b>2</b> - Sublink 1
+ *
+ * @PlatformDependant
+ */
+} HT_PATH;
+
+/// The configuration structure common header.
+typedef struct {
+ UINT16 Version; ///< Version of this structure
+ UINT16 Reserved; ///< Reserved for future use
+ UINT32 InitializerID; ///< Signature of initializer
+} AMD_COMMON_STRUCT_HEADER;
+
+/// The PCIE configuration parameters
+typedef struct {
+ AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header
+ PCIE_MISC_CONFIG PcieConfiguration; ///< General configuration option
+ UINT32 ExtPcieConfiguration; ///< Extended General configuration option (Reserved for future use)
+ UINT32 CoreConfiguration[5]; /**< Core configuration
+ * @li <b>CoreConfiguration[0]</b> - GPP1 Core Configuration
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">if CoreConfiguration[0] == 0 && PortConfiguration[3].PortPresent == 1 </TD></TR>
+ * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">CoreConfiguration[0] == 0x02020101</TD></TR>
+ * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">if CoreConfiguration[0] == 0 && PortConfiguration[3].PortPresent == 0</TD></TR>
+ * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">CoreConfiguration[0] == 0x01010101</TD></TR>
+ * </TABLE>
+ * @li <b>CoreConfiguration[1]</b> - GPP2 Core Configuration
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">if CoreConfiguration[1] == 0 && PortConfiguration[12].PortPresent == 1 </TD></TR>
+ * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">CoreConfiguration[1] == 0x02020101</TD></TR>
+ * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">if CoreConfiguration[1] == 0 && PortConfiguration[12].PortPresent == 0</TD></TR>
+ * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">CoreConfiguration[1] == 0x01010101</TD></TR>
+ * </TABLE>
+ * @li <b>CoreConfiguration[2]</b> - GPP3a Core Configuration
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=120> 4:2:0:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x1 </TD></TR>
+ * <TR><TD class="indexkey" width=120> 4:1:1:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x2</TD></TR>
+ * <TR><TD class="indexkey" width=120> 2:2:2:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x3</TD></TR>
+ * <TR><TD class="indexkey" width=120> 2:2:1:1:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x4</TD></TR>
+ * <TR><TD class="indexkey" width=120> 2:1:1:1:1:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x5</TD></TR>
+ * <TR><TD class="indexkey" width=120> 1:1:1:1:1:1 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x6</TD></TR>
+ * </TABLE>
+ * @li <b>CoreConfiguration[3]</b> - Reserved
+ * @li <b>CoreConfiguration[4]</b> - Reserved
+
+ * @PlatformDependant
+ */
+ PCIE_CORE_SETTING CoreSetting[5]; /**< Core setting
+ * see PCIE_CORE_SETTING for details
+ * @li <b>CoreSetting[0]</b> - GPP1 Core Settings
+ * @li <b>CoreSetting[1]</b> - GPP2 Core Settings
+ * @li <b>CoreSetting[2]</b> - GPP3a Core Settings
+ * @li <b>CoreSetting[3]</b> - GPP3b Core Settings
+ * @li <b>CoreSetting[4]</b> - SB Core setting
+ */
+ PCIE_PORT_CONFIG PortConfiguration[15]; /**< Port configuration
+ * see PCIE_PORT_CONFIG for details
+ * @li <b>PortConfiguration[0]</b> - Reserved
+ * @li <b>PortConfiguration[1]</b> - Reserved
+ * @li <b>PortConfiguration[2]</b> - PCIE Port Device 2 configuration
+ * @li <b>PortConfiguration[3]</b> - PCIE Port Device 3 configuration
+ * @li ...
+ * @li <b>PortConfiguration[13]</b> - PCIE Port Device 13 configuration
+ *
+ * @PlatformDependant
+ */
+ PCIE_EXT_PORT_CONFIG ExtPortConfiguration[15]; /**< Extended Port configuration
+ * see PCIE_EXT_PORT_CONFIG for details.
+ * @li <b>ExtPortConfiguration[0]</b> - Reserved
+ * @li <b>ExtPortConfiguration[1]</b> - Reserved
+ * @li <b>ExtPortConfiguration[2]</b> - PCIE Port Device 2 configuration
+ * @li <b>ExtPortConfiguration[3]</b> - PCIE Port Device 3 configuration
+ * @li ...
+ * @li <b>ExtPortConfiguration[13]</b> - PCIE Port Device 13 configuration
+ *
+ * @PlatformDependant
+ */
+
+ UINT16 PcieMmioBaseAddress; /**< PCIE Extended MMIO base address in 1MB Unit.
+ * If PcieMmioBaseAddress == 0 assume MMIO setup already done.
+ * PCIE MMIO range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Non Posted if enabled in NB.
+ * <b>IMPORTANT!!! </b>Platform which use Rev10 and later CPU family should use PCIE MMIO functionality provided by CPU See "Configuration Space" in "BIOS and Kernel Developer's Guide For AMD Family 10h"
+ *
+ * @PlatformDependant
+ */
+
+ UINT16 PcieMmioSize; /**< PCIE Extended MMIO size in 1MB Unit.
+ * if PcieMmioBaseAddress != 0 and PcieMmioSize == 0 ignore both parameters and assume MMIO setup already done
+ * if PcieMmioBaseAddress == 0 and PcieMmioSize != 0 ignore both parameters and assume MMIO setup already done
+ * PCIE MMIO range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Non Posted if enabled in NB.
+ * <b>IMPORTANT!!!</b>Platform which use Rev10 and later CPU family should use PCIE MMIO functionality provided by CPU See "Configuration Space" in "BIOS and Kernel Developer's Guide For AMD Family 10h"
+ *
+ * @PlatformDependant
+ */
+ UINT16 TempMmioBaseAddress; /**< Temporary MMIO base in 1MB Unit
+ * MMIO base address for temporary 256MB MMIO range.
+ * Range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Posted
+ *
+ * @PlatformDependant
+ */
+ UINT16 DeviceInitMaskS1; ///< Bit mask of ports to be initialized at stage 1
+ UINT16 DeviceInitMaskS2; ///< Bit mask of ports to be initialized at stage 2
+ UINT16 ResetToTrainingDelay; ///< Delay (in 1ms) after reset deassert before training started
+ UINT16 TrainingToLinkTestDelay; ///< Delay (in 1ms) after training started but before pooling link state
+ UINT16 ReceiverDetectionPooling; ///< Total amount time (in 1ms of pooling for passing receiver detection stage
+ UINT32 Reserved12[16]; ///< Reserved for internal use.
+} PCIE_CONFIG;
+
+
+
+/// The NB/IOMMU configuration
+typedef struct {
+ AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header
+ UINT8 UnitIdClumping; /**< Unit ID clamping.
+ * UnitId clamping configuration base on PCIE port 3/12 presence.
+ * @li <b>0</b> - Disable
+ * @li <b>1</b> - Dev3
+ * @li <b>2</b> - Dev12
+ * @li <b>3</b> - Dev3 & Dev12
+
+ * @FilledByInitializer
+ */
+ UINT8 P2PMode; /**< Peer-To-Peer (p2p) Modes
+ * Peep-To-Peer mode selection
+ * @li <b>0</b> - Default
+ * @li <b>1</b> - Mode 1
+ * @li <b>2</b> - Mode 2
+ * @li <b>0x8x</b> - Skip Initialization
+
+ * @FilledByInitializer
+ */
+ UINT8 Reserved2[2]; ///< Reserved for internal use.
+ UINT16 SysMemoryTomBelow4G; /**< Top of System memory below 4G in 1MB unit
+ * Top of physical memory including all reserved system memory etc.
+ * @PlatformDependant
+ */
+ UINT32 SysMemoryTomAbove4G; /**< Top of System memory above 4G in 1MB unit
+ * Top of physical memory including all reserved system memory etc.
+ * @PlatformDependant
+ */
+ UINT16 Reserved; ///< Used for internally to save APIC ID of Core 0.
+ UINT64 IommuBaseAddress; /**< IOMMU base address.
+ * 16kb aligned base address for IOMMU control registers
+ * @PlatformDependant
+ */
+ UINT64 BroadcastBaseAddress; /**< PCIE Broadcast MMIO base address.
+ * This feature can be utilized broadcast address aware driver (AMD GFX driver)
+ * If BroadcastBaseAddress == 0 MMIO will not be enabled
+ * @PlatformDependant
+ */
+ UINT16 BroadcastSize; /**< PCIE Broadcast MMIO size in MB.
+ * If BroadcastSize == 0 MMIO will not be enabled
+ * @PlatformDependant
+ */
+ UINT16 Reserved3; ///< Reserved for internal use.
+ UINT64 IoApicBaseAddress; /**< NB IO APIC Base address.
+ * If IoApicBaseAddress == 0 IOAPIC will not be enabled
+ * @PlatformDependant
+ */
+ UINT32 SSID; ///< NB Subsystem/Subvendor ID
+ UINT32 IommuTpologyInfo; ///< For intrernal use only
+ UINT32 Reserved4[8]; ///< Reserved for internal use.
+} NB_CONFIG;
+
+
+/// The NB Buffer Allocation/request parameters
+typedef struct {
+ IN UINTN BufferLength; ///< Buffer length
+ IN UINT32 BufferHandle; ///< Buffer handle
+ OUT VOID* BufferPtr; ///< Pointer to the buffer
+} NB_BUFFER_PARAMS;
+
+
+/// The IOMMU exclusion range
+typedef struct {
+ UINT64 Start; ///< Range Start address
+ UINT64 Length; ///< Range length
+} IOMMU_EXCLUSIONRANGE;
+
+//#pragma warning (push)
+//#pragma warning (disable: 4200)
+
+/// The IOMMU exclusion table
+typedef struct {
+ UINTN TableLength; ///< Exclusion table length
+ IOMMU_EXCLUSIONRANGE ExclusionRange[]; ///< Array of exclusion range entries.
+} IOMMU_EXCLUSIONTABLE;
+//#pragma warning (pop)
+
+/// The HT configuration structure
+typedef struct {
+ AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header
+ UINT8 LSx; /**< HT link LS state enable
+ * @li <b>0</b> - LS0
+ * @li <b>1</b> - LS1
+ * @li <b>2</b> - LS2
+ * @li <b>3</b> - LS3
+ * @li <b>4</b> - Same as CPU (use CPU setting setup by AGESA)
+ * @li <b>0x8x</b> - Skip Setting
+
+ * @FilledByInitializer
+ */
+ UINT8 Reserved; ///< Reserved for internal use.
+ UINT8 LinkBufferOptimization; /**< CPU - NB HT link optimization.
+ * @li <b>0</b> - Disabled
+ * @li <b>1</b> - Enable
+ * @li <b>2..7</b> - Reserved
+ */
+ UINT8 HtExtendedAddressSupport; /**<Extended HT Address Support
+ * @li <b>0</b> - Disable
+ * @li <b>1</b> - Enable
+ * @li <b>0x8x</b> - Skip setting
+
+ * @FilledByInitializer
+ */
+ UINT8 HtLinkTriState; /**< HT Link tristate control
+ * @li <b>1</b> - Disable
+ * @li <b>2</b> - CAD/CTL
+ * @li <b>3</b> - CAD/CTL/CLK
+ * @li <b>0x8x</b> - Skip setting
+
+ * @FilledByInitializer
+ */
+ UINT8 NbTransmitterDeemphasis; /**< NB deemphasis level
+ * @li <b>0</b> - Disabled
+ * @li <b>1</b> - 1.32dB (0 to 4.5" trace length)
+ * @li <b>2</b> - 2.08dB (4.5" to 8" trace length)
+ * @li <b>3</b> - 3.10dB (8" to 11" trace length)
+ * @li <b>4</b> - 4.22dB (11" to 14" trace length)
+ * @li <b>5</b> - 5.50dB (14" to 18" trace length)
+ * @li <b>6</b> - 7.05dB (18+" trace length)
+
+ * @PlatformDependant
+ */
+ UINT16 HtReferenceClock; /**< HT Reference clock.
+ *
+ * @FilledByInitializer
+ */
+ UINT32 Reserved1[10]; ///< Reserved
+} HT_CONFIG;
+
+
+/// The NB configuration structure
+struct _AMD_NB_CONFIG_BLOCK;
+typedef struct _AMD_NB_CONFIG_BLOCK AMD_NB_CONFIG_BLOCK;
+
+/// The NB configuration structure
+typedef struct {
+ AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header
+ PCI_ADDR NbPciAddress; /**<PCI address of NB
+ * PCI Address to Access NB. Depends on HT topology and configuration for multi NB platform.
+ * Always 0:0:0 on single NB platform.
+ * @PlatformDependant
+ */
+ HT_PATH NbHtPath; /**< HT path to NB.
+ * Path to NB CPU->Ht Link Number->NB
+ * @PlatformDependant
+ */
+ UINT16 Reserved21; ///< Reserved for internal use.
+ NB_CONFIG *pNbConfig; ///< Pointer to NB configuration structure
+ HT_CONFIG *pHtConfig; ///< Pointer to HT configuration structure
+ PCIE_CONFIG *pPcieConfig; ///< Pointer to PCIE configuration structure
+ AMD_NB_CONFIG_BLOCK **ConfigPtr; ///< Pointer to main config block structure
+ VOID *ReservedPtr; ///< Reserved for internal use.
+} AMD_NB_CONFIG;
+
+
+/// The configuration block for all NB in system.
+struct _AMD_NB_CONFIG_BLOCK {
+ AMD_CONFIG_PARAMS StandardHeader; ///< Standard structure header
+ UINT8 NumberOfNorthbridges; /**< Number of AMD_NB_CONFIG configuration structures
+ * @li <b>0</b> - One NB.
+ * @li <b>1</b> - Two NB.
+ * @li <b>2</b> - Three NB.
+ * @li <b>3</b> - Four NB.
+
+ * @PlatformDependant
+ */
+ UINT8 Scratch; /**< Variable for internal use
+ * @li <b>Bit[0]</b> = 0 Enable DebugOut, = 1 Disable DebugOut(only applicable for DebugOut enabled binaries).
+ */
+ UINT8 PlatformType; /**< Platform Type (Server/Desktop).
+ * @li<b>0</b> - Unknown
+ * @li<b>1</b> - Desktop
+ * @li<b>2</b> - Server
+
+ * @PlatformDependant
+ */
+ UINT8 CurrentNorthbridge; /**< Northbridge ID which currently being initialized.
+ * Variable filled by CIMx and can be used during callback
+ * to identify to which NB callback belongs.
+ */
+ AMD_NB_CONFIG Northbridges[MAX_NB_COUNT]; ///< Array of configuration structures for one or more NB in system
+};
+
+/// The IO APIC Interrupt Mapping Info
+typedef struct {
+ UINT8 Group; /**< Group mapping for slot or endpoint device (connected to PCIE port) interrupts .
+ @li <b>0</b> - mapped to Grp 0 (pin 0..3 of IO APIC)
+ @li <b>1</b> - mapped to Grp 1 (pin 4..7 of IO APIC)
+ @li ...
+ @li <b>7</b> - mapped to Grp 7 (pin 28..31 of IO APIC)
+ */
+ UINT8 Swizzle; /**< Swizzle interrupt in the Group.
+ @li <b>0</b> - ABCD
+ @li <b>1</b> - BCDA
+ @li <b>2</b> - CDAB
+ @li <b>3</b> - DABC
+ */
+ UINT8 Pin; /**<Interrupt pin for PCIE bridge
+ @li <b>0</b> - Pin 0 of IO APIC
+ @li <b>1</b> - Pin 1 of IO APIC
+ @li ...
+ @li <b>31</b> - Pin 31 of IO APIC
+ */
+} APIC_DEVICE_INFO;
+
+typedef AGESA_STATUS (*SYSTEM_API) (AMD_NB_CONFIG_BLOCK *ConfigPtr);
+typedef AGESA_STATUS (*NB_API) (AMD_NB_CONFIG *NbConfigPtr);
+
+/// Northbridge info
+typedef struct {
+ UINT8 Type; ///< NB Model (RS780/RD790/RD890...)
+ UINT8 Revision; ///< NB Revision ID
+} NB_INFO;
+
+/// API workspace
+typedef struct {
+ AMD_NB_CONFIG_BLOCK *ConfigPtr; ///< NB congiguration
+ AGESA_STATUS Status; ///< return status
+} API_WORKSPACE;
+
+/// Indirect register entry
+typedef struct {
+ UINT32 Register; ///< register
+ UINT32 Mask; ///< AND mask
+ UINT32 Data; ///< data
+} INDIRECT_REG_ENTRY;
+
+/// Register entry
+typedef struct {
+ UINT8 Register; ///< register
+ UINT8 Mask; ///< AND mask
+ UINT8 Data; ///< data
+} REGISTER_ENTRY;
+
+/// Scratchpad
+typedef struct {
+ UINT32 ResetCount :4; ///< PCIe reset count
+ UINT32 PortGen2Disable :12; ///< PCIe Gen 2 disable
+ UINT32 MaskMemoryInit :1; ///< Mask memory init complete
+} SCRATCH_1;
+
+/// Scratchpad
+typedef struct {
+ UINT32 GlobalInterruptBase :8; ///< TBD
+} SCRATCH_4;
+
+
+/*--------------------------- Documentation Pages ---------------------------*/
+/**
+ * @page LegacyInterfaceCalls Legacy Interface Calls
+ * <TD>@subpage PH_Initializer_Page "PH_Initializer"</TD><TD></TD>
+ * <TD>@subpage PH_AmdPowerOnResetInit_Page "PH_AmdPowerOnResetInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdNbHtInit_Page "PH_AmdNbHtInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdPcieEarlyInit_Page "PH_AmdPcieEarlyInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdEarlyPostInit_Page "PH_AmdEarlyPostInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdMidPostInit_Page "PH_AmdMidPostInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdLatePostInit_Page "PH_AmdLatePostInit"</TD><TD></TD>
+ * <TD>@subpage PH_AmdS3Init_Page "PH_AmdS3Init"</TD><TD></TD>
+ *
+*/
+
+/*--------------------------- Documentation Pages ---------------------------*/
+/**
+ * @page PH_Initializer_Page PH_AmdNbInitializer
+ * @section PH_Initializer PH_AmdNbInitializer Interface Call
+ * Initialize structure referenced by AMD_NB_CONFIG::pHtConfig, AMD_NB_CONFIG::pPcieConfig and AMD_NB_CONFIG::pNbConfig to default recommended value.(Except platform dependant parameters See @ref PlatformDependParam "Platform Dependant Parameters" )
+ * @subsection PH_Initializer_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_Initializer_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_Initializer_Page_Initializer Initializer
+ * @par
+ * Not Applicable
+ * @subsection PH_Initializer_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdInitializer 0x100
+
+/*--------------------------- Documentation Pages ---------------------------*/
+/**
+ * @page PH_AmdPowerOnResetInit_Page PH_AmdPowerOnResetInit
+ * @section PH_AmdPowerOnResetInit PH_AmdPowerOnResetInit Interface Call
+ * Initialize Northbridge registers on power-on reset.
+ * @subsection PH_AmdPowerOnResetInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdPowerOnResetInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdPowerOnResetInit_Initializer Initializer
+ * @par
+ * Not Required
+ * @subsection PH_AmdPowerOnResetInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdPowerOnResetInit 0x00
+/**
+ * @page PH_AmdNbHtInit_Page PH_AmdNbHtInit
+ * @section PH_AmdNbHtInit PH_AmdNbHtInit Interface Call
+ * Initialize NB HT subsystem.
+ * @subsection PH_AmdNbHtInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdNbHtInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdNbHtInit_Initializer Initializer
+ * @par
+ * Required (see @ref PH_Initializer_Page "PH_Initializer")
+ * @subsection PH_AmdNbHtInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbHtPath </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pHtConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdNbHtInit 0x10
+/**
+ * @page PH_AmdEarlyPostInit_Page PH_AmdEarlyPostInit
+ * @section PH_AmdEarlyPostInit PH_AmdEarlyPostInit Interface Call
+ * Initialize misc Northbridge feature at Early Post.
+ * @subsection PH_AmdEarlyPostInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdEarlyPostInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdEarlyPostInit_Initializer Initializer
+ * @par
+ * Required. (see @ref PH_Initializer_Page)
+ * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init
+ * must use same copy of AMD_NB_CONFIG_BLOCK
+ * @subsection PH_AmdEarlyPostInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbHtPath </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pNbConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pPcieConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> NB_CONFIG::SysMemoryTomBelow4G </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> NB_CONFIG::SysMemoryTomAbove4G </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdEarlyPostInit 0x30
+/**
+ * @page PH_AmdMidPostInit_Page PH_AmdMidPostInit
+ * @section PH_AmdMidPostInit PH_AmdMidPostInit Interface Call
+ * Initialize misc Northbridge feature at Mid Post.
+ * @subsection PH_AmdMidPostInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdMidPostInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdUpdateApicInterruptMapping_Page "PHCB_AmdUpdateApicInterruptMapping"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdAllocateBuffer_Page "PHCB_AmdAllocateBuffer "</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdGetExclusionTable_Page "PHCB_AmdGetExclusionTable "</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdMidPostInit_Initializer Initializer
+ * @par
+ * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure.
+ * @subsection PH_AmdMidPostInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> NB_CONFIG::IommuBaseAddress </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> NB_CONFIG::IoApicBaseAddress </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdMidPostInit 0x40
+/**
+ * @page PH_AmdLatePostInit_Page PH_AmdLatePostInit
+ * @section PH_AmdLatePostInit PH_AmdLatePostInit Interface Call
+ * Initialize misc Northbridge feature at Late Post.
+ * @subsection PH_AmdLatePostInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdLatePostInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPcieAsmpInfo "PHCB_AmdPcieAsmpInfo"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdLatePostInit_Initializer Initializer
+ * @par
+ * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure.
+ * @subsection PH_AmdLatePostInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader</TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdLatePostInit 0x50
+
+ /**
+ * @page PH_AmdPcieEarlyInit_Page PH_AmdPcieEarlyInit
+ * @section PH_AmdPcieEarlyInit PH_AmdPcieEarlyInit Interface Call
+ * Init PCI Express Subsystem. Train link on all enabled Ports. Initialize hotplug.
+ * @subsection PH_AmdPcieEarlyInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdPcieEarlyInit_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortTrainingCompleted_Page "PHCB_AmdPortTrainingCompleted"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetSupported_Page "PHCB_AmdPortResetSupported"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetAssert_Page "PHCB_AmdPortResetAssert"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetDeassert_Page "PHCB_AmdPortResetDeassert"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdPcieEarlyInit_Initializer Initializer
+ * @par
+ * Required.
+ * @subsection PH_AmdPcieEarlyInit_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pPcieConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdPcieEarlyInit 0x20
+/**
+ * @page PH_AmdS3Init_Page PH_AmdS3Init
+ * @section PH_AmdS3Init PH_AmdS3Init Interface Call
+ * Init misc. feature PCI Express Subsystem. Enable power management feature. Power off unused lanes/PLL etc.
+ * @subsection PH_AmdPcieLateInit_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdS3Init_Callback Callback`s
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdUpdateApicInterruptMapping_Page "PHCB_AmdUpdateApicInterruptMapping"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR>
+ * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPcieAsmpInfo "PHCB_AmdPcieAsmpInfo"</TD></TR>
+ * </TABLE>
+ * @subsection PH_AmdS3Init_Initializer Initializer
+ * @par
+ * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure.
+ * @subsection PH_AmdS3Init_Data Configuration Data.
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR>
+ * </TABLE>
+ *
+ */
+#define PH_AmdS3Init 0x60
+
+/*
+ Secondary level interface function
+*/
+#define PH_AmdPcieS3Init 0x61
+#define PH_AmdNbS3Init 0x62
+#define PH_AmdPcieLateInit 0x51
+#define PH_AmdNbLateInit 0x52
+
+/**
+ *This function PH_AmdPcieValidatePortState must be called
+ * after the PH_AmdPcieEarlyInit and before PH_AmdLatePostInit
+ */
+#define PH_AmdPcieValidatePortState 0x70
+
+
+/**
+ * @page PHCB_AmdPortTrainingCompleted_Page PHCB_AmdPortTrainingCompleted
+ * @section PHCB_AmdPortTrainingCompleted PHCB_AmdPortTrainingCompleted Callback
+ * PCIE Port Initialization Completed endpoint detected.
+ * @subsection PHCB_AmdPortTrainingCompleted_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortId, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PH_AmdS3Init_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8000</TD></TR>
+ * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500>PCI Express Port Id</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdPortTrainingCompleted_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_ERROR</TD><TD class="indexvalue" width=500>Disable Port</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdPortTrainingCompleted 0x8000
+/**
+ * @page PHCB_AmdPortResetDeassert_Page PHCB_AmdPortResetDeassert
+ * @section PHCB_AmdPortResetDeassert PHCB_AmdPortResetDeassert Callback
+ * Deassert reset for device or slot connected to PCIE Port.
+ * @subsection PHCB_AmdPortResetDeassert_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortIdBitMap, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdPortTrainingCompleted_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500> 0x8001</TD></TR>
+ * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500>bitmap of port id to deassert reset (0x4 - PortId 2, 0x8 PortId 3, ...)</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdPortTrainingCompleted_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Reset successfully deasserted</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdPortResetDeassert 0x8001
+/**
+ * @page PHCB_AmdPortResetAssert_Page PHCB_AmdPortResetAssert
+ * @section PHCB_AmdPortResetAssert PHCB_AmdPortResetAssert Callback
+ * Assert reset for device connected to PCIE Port.
+ * @subsection PHCB_AmdPortResetDeassert_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortIdBitMap, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdPortResetAssert_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8002</TD></TR>
+ * <TR><TD class="indexkey" width=160>PortIdBitMap</TD><TD class="indexvalue" width=500>Bitmap of port id to assert reset (0x4 - PortId 2, 0x8 PortId 3, ...)</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdPortResetAssert_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Reset successfully asserted</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdPortResetAssert 0x8002
+/**
+ * @page PHCB_AmdPortResetSupported_Page PHCB_AmdPortResetSupported
+ * @section PHCB_AmdPortResetSupported PHCB_AmdPortResetSupported Callback
+ * Test if controllable reset logic present for PCIE Port.
+ * @subsection PHCB_AmdPortResetSupported_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortId, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdPortResetSupported_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8003</TD></TR>
+ * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500> Port ID to check GPIO controlled reset logic present for slot or endpoint connected to this port</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdPortResetSupported_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Slot/Device connected to port has GPIO controlled reset logic</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdPortResetSupported 0x8003
+
+
+/**
+ * @page PHCB_AmdGeneratePciReset_Page PHCB_AmdGeneratePciReset
+ * @section PHCB_AmdPortResetSupported PHCB_AmdGeneratePciReset Callback
+ * Request PCI reset generation.
+ * @subsection PHCB_AmdGeneratePciReset_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN ResetType, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdGeneratePciReset_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8004</TD></TR>
+ * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500> Reset type. 0x01 - Warm Reset, 0x02 - Cold Reset</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdGeneratePciReset_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>"Any"</TD><TD class="indexvalue" width=500>CIMx will generate reset by writing port 0xCF9</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Debug feature to completely avoid reset generation</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdGeneratePciReset 0x8004
+
+/**
+ * @page PHCB_AmdGetExclusionTable_Page PHCB_AmdGetExclusionTable
+ * @section PHCB_AmdGetExclusionTable PHCB_AmdGetExclusionTable Callback
+ * Return the IOMMU exclusion table related to the current configuration block
+ * @subsection PHCB_AmdGetExclusionTable_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, IOMMU_EXCLUSIONTABLE *ExclusionTable, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdGetExclusionTable_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8005</TD></TR>
+ * <TR><TD class="indexkey" width=160>ExclusionTable</TD><TD class="indexvalue" width=500>Pointer to IOMMU exclusion table</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdGetExclusionTable_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Valid table returned</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdGetExclusionTable 0x8005
+
+/**
+ * @page PHCB_AmdAllocateBuffer_Page PHCB_AmdAllocateBuffer
+ * @section PHCB_AmdAllocateBuffer PHCB_AmdAllocateBuffer Callback
+ * Return the address of a memory buffer (size in bytes).
+ *
+ * ACPI handles used:
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>'SRVI'</TD><TD class="indexvalue" width=500>IO virtualization table</TD></TR>
+ * </TABLE>
+ * @par
+ * Usage: Buffer can be be allocated via PMM function 0 with handle and size specified in BufferParamsPtr, and
+ * the address must be returned in BufferParamsPtr.
+ * @par
+ * <b>Important Note:</b> Allocation for ACPI table will be requested during AmdEarlyPostInit or AmdMidPostInit and must be linked to
+ * ACPI table structure prior AmdLatePostInit interface call.
+ * @subsection PHCB_AmdAllocateBuffer_Callin Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdAllocateBuffer_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8006</TD></TR>
+ * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdAllocateBuffer_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer returned</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdAllocateBuffer 0x8006
+
+/**
+ * @page PHCB_AmdUpdateApicInterruptMapping_Page PHCB_AmdUpdateApicInterruptMapping
+ * @section PHCB_AmdUpdateApicInterruptMapping PHCB_AmdUpdateApicInterruptMapping Callback
+ * Provide pointer to default IOAPIC interrupt mapping table
+ * @subsection PHCB_AmdUpdateApicInterruptMapping_Callin Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, APIC_DEVICE_INFO *pApicPortInfo, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdUpdateApicInterruptMapping_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8007</TD></TR>
+ * <TR><TD class="indexkey" width=160>pApicPortInfo</TD><TD class="indexvalue" width=500>Pointer to array of structures containing default IO APIC interrupt mapping info. For default interrupt mapping info see \ref gDefaultApicDeviceInfoTable</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdUpdateApicInterruptMapping_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Interrupt mapping configuration completed</TD></TR>
+ * </TABLE>
+ *
+ */
+
+#define PHCB_AmdUpdateApicInterruptMapping 0x8007
+
+/**
+ * @page PHCB_AmdFreeBuffer_Page PHCB_AmdFreeBuffer
+ * @section PHCB_AmdFreeBuffer PHCB_AmdFreeBuffer Callback
+ * Free a specific memory buffer by handle.
+ *
+ * ACPI handles used:
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>'SRVI'</TD><TD class="indexvalue" width=500>IO virtualization table</TD></TR>
+ * </TABLE>
+ * @par
+ * <b>Important Note:</b> ACPI tables as listed above will not be explicitly freed and must be linked into the system ACPI table structure.
+ *
+ * @subsection PHCB_AmdFreeBuffer_Callin Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdFreeBuffer_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8008</TD></TR>
+ * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdFreeBuffer_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer freed</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdFreeBuffer 0x8008
+
+/**
+ * @page PHCB_AmdLocateBuffer_Page PHCB_AmdLocateBuffer
+ * @section PHCB_AmdLocateBuffer PHCB_AmdLocateBuffer Callback
+ * Locate a specific memory buffer by handle (See also @ref PHCB_AmdAllocateBuffer_Page "PHCB_AmdAllocateBuffer").
+ *
+ * @subsection PHCB_AmdLocateBuffer_Callin Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdLocateBuffer_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8009</TD></TR>
+ * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdLocateBuffer_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer Located</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdLocateBuffer 0x8009
+
+/**
+ * @page PHCB_AmdReportEvent_Page PHCB_AmdReportEvent
+ * @section PHCB_AmdReportEvent PHCB_AmdReportEvent Callback
+ * Report event to platform firmware
+ * To exclude an entry, set the value of DeviceId to 0xFFFF
+ *
+ * @subsection PHCB_AmdReportEvent_Callin Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, AGESA_EVENT *Event, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdReportEvent_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160> CallBackId</TD><TD class="indexvalue" width=500>0x8010</TD></TR>
+ * <TR><TD class="indexkey" width=160> Event</TD><TD class="indexvalue" width=500>pointer to event structure</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdReportEvent_Events Events
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160> Event Class</TD><TD class="indexkey">Event Info </TD><TD class="indexkey">Description</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010100</TD><TD class="indexvalue" >Hotplug controller firmware initialization fail</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010200</TD><TD class="indexvalue">Link training fail</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010300</TD><TD class="indexvalue">Incorrect PCIE Core COnfiguration requested</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010400</TD><TD class="indexvalue">Link width downgraded </TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010500</TD><TD class="indexvalue">Link speed forced to Gen1.</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010600</TD><TD class="indexvalue">VCO negotiation fail.</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010700</TD><TD class="indexvalue">Incorrect port device number remapping configuration</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_FATAL</TD><TD class="indexvalue">0x20000100</TD><TD class="indexvalue" >Invalid configuration structure</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_WARRNING</TD><TD class="indexvalue">0x20000200</TD><TD class="indexvalue">NB not present</TD></TR>
+ * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20000300</TD><TD class="indexvalue">Can not locate ACPI table</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdReportEvent_Return Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR>
+ * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Event successfully logged</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdReportEvent 0x8010
+/**
+ * @page PHCB_AmdPcieAsmpInfo_Page PHCB_AmdPcieAsmpInfo
+ * @section PHCB_AmdPcieAsmpInfo PHCB_AmdPcieAsmpInfo Callback
+ * Give platform chance to update PCIe link ASPM setting.
+ * @subsection PHCB_AmdPcieAsmpInfo_CallIn Call Prototype
+ * @par
+ * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, ASPM_LINK_INFO *AspmLinkInfoPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr)
+ * @subsection PHCB_AmdPcieAsmpInfo_Parameters Parameters
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8011</TD></TR>
+ * <TR><TD class="indexkey" width=160>AspmLinkInfoPtr</TD><TD class="indexvalue" width=500> ASPM link info see ASPM_LINK_INFO for details.</TD></TR>
+ * </TABLE>
+ * @subsection PHCB_AmdPcieAsmpInfo_Retrun Return Value
+ * @par
+ * <TABLE border="0">
+ * <TR><TD class="indexkey" width=160>"Any"</TD><TD class="indexvalue" width=500>CIMx will use content on ASPM_LINK_INFO to enable ASPM</TD></TR>
+ * </TABLE>
+ *
+ */
+#define PHCB_AmdPcieAsmpInfo 0x8011
+
+
+#define CB_AmdSetNbPorConfig 0x9000
+#define CB_AmdSetHtConfig 0x9001
+#define CB_AmdSetPcieEarlyConfig 0x9002
+#define CB_AmdSetEarlyPostConfig 0x9003
+#define CB_AmdSetMidPostConfig 0x9004
+#define CB_AmdSetLatePostConfig 0x9005
+#define CB_AmdSetRecoveryConfig 0x9006
+
+#define ON 0x1
+#define OFF 0x0
+
+#define NB_RD890TV 0x00
+#define NB_RD780 0x01
+#define NB_RX780 0x02
+#define NB_SR5690 0x10
+#define NB_SR5670 0x15
+#define NB_SR5650 0x20
+#define NB_RD890 0x25
+#define NB_990FX 0x25 //990FX= RD890
+#define NB_990X 0x30 //990X= SR5650
+#define NB_970 0x35
+
+#define NB_UNKNOWN 0xff
+
+#define NB_REV_A11 0x00
+#define NB_REV_A12 0x02
+
+#define DEV3_CLUMPING 1
+#define DEV12_CLUMPING 2
+
+#define INITIALIZED_BY_INITIALIZER 0xAA
+
+#define CPU_FAMILY_NPT 0x00000000
+#define CPU_FAMILY_GH 0x00100000
+
+#define GET_NB_CONFIG_PTR(x) x->pNbConfig
+#define GET_HT_CONFIG_PTR(x) x->pHtConfig
+#define GET_PCIE_CONFIG_PTR(x) x->pPcieConfig
+#define GET_BLOCK_CONFIG_PTR(x) (*(x->ConfigPtr))
+#define NB_SBDFO pConfig->NbPciAddress.AddressValue
+
+#define ABCD 0
+#define BCDA 1
+#define CDAB 2
+#define DABC 3
+
+/// Platform Type
+typedef enum {
+ DetectPlatform, ///< Autodetect platform type based on NB skew
+ DesktopPlatform, ///< Desktop platform
+ ServerPlatform ///< Server platform
+} PLATFORM_TYPE;
+
+/// APIC register info
+typedef struct {
+ UINT8 EpRoutingOffset; ///< Ep routing offset
+ UINT8 EpRoutingRegister; ///< Ep routing reg
+ UINT8 RcRoutingOffset; ///< Rc routing offset
+ UINT8 RcRoutingRegister; ///< Rc routing reg
+} APIC_REGISTER_INFO;
+
+
+#define PortInterruptPinMap(Pin, Port) (Pin << Port)
+
+#define HtPinMapOffset 0
+#define IommuPinMapOffset 8
+
+
+#define CIMX_MIN(x, y) (((x) > (y)) ? (y) : (x))
+#define CIMX_MAX(x, y) (((x) > (y)) ? (x) : (y))
+//#pragma pack(pop)
+
+#endif