Hi,

attached patches implement two errata fixes.


Patrick
Fix for Erratum 343 for AMD Fam10h CPUs.

Signed-off-by: Marco Schmidt <[email protected]>
Acked-by: Patrick Georgi <[email protected]>
Index: coreboot/src/cpu/amd/car/cache_as_ram.inc
===================================================================
--- coreboot.orig/src/cpu/amd/car/cache_as_ram.inc
+++ coreboot/src/cpu/amd/car/cache_as_ram.inc
@@ -27,6 +27,8 @@
 /* for CAR_FAM10 */
 #define CacheSizeAPStack 0x400 /* 1K */
 
+#define MSR_FAM10      0xC001102A
+
 #define jmp_if_k8(x)	comisd	%xmm2, %xmm1; jb x
 
 #define CPUID_MASK		0x0ff00f00
@@ -122,6 +124,22 @@ CAR_FAM10_out:
 	bts	$15, %eax
 	wrmsr
 
+	/* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
+
+	/* read-address has to be stored in the ecx register */
+	movl    $MSR_FAM10, %ecx
+
+	/* execute special read command for msr-register. Result is then in the EDX:EAX-registers (MSBs in EDX) */
+	rdmsr
+
+	/* Set bit 35 to 1 in EAX */
+	bts     $35, %eax
+
+	/* write back the modified register EDX:EAX to the MSR specified in ECX */
+	wrmsr
+
+	/* Erratum 343 end */
+
 CAR_FAM10_out_post_errata:
 
 	/* Set MtrrFixDramModEn for clear fixed mtrr */
Index: coreboot/src/cpu/amd/car/post_cache_as_ram.c
===================================================================
--- coreboot.orig/src/cpu/amd/car/post_cache_as_ram.c
+++ coreboot/src/cpu/amd/car/post_cache_as_ram.c
@@ -23,7 +23,19 @@ static void inline __attribute__((always
                 : "S" (src), "D" (dest), "c" ((bytes)>>2)
                 );
 }
+/* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33 */
 
+static void vErrata343(void)
+{
+    msr_t msr;
+    unsigned int uiMask = 0xFFFFFFF7;
+
+#ifdef BU_CFG2_MSR
+    msr = rdmsr(BU_CFG2_MSR);
+    msr.hi &= uiMask; // set bit 35 to 0
+    wrmsr(BU_CFG2_MSR, msr);
+#endif
+}
 
 static void post_cache_as_ram(void)
 {
@@ -56,6 +68,8 @@ static void post_cache_as_ram(void)
 	print_debug("Copying data from cache to RAM -- switching to use RAM as stack... ");
 
 	/* from here don't store more data in CAR */
+	vErrata343();
+
 #if 0
         __asm__ volatile (
         	"pushl  %eax\n\t"
Index: coreboot/src/include/cpu/amd/model_10xxx_msr.h
===================================================================
--- coreboot.orig/src/include/cpu/amd/model_10xxx_msr.h
+++ coreboot/src/include/cpu/amd/model_10xxx_msr.h
@@ -26,6 +26,7 @@
 #define IC_CFG_MSR			0xC0011021
 #define DC_CFG_MSR			0xC0011022
 #define BU_CFG_MSR			0xC0011023
+#define BU_CFG2_MSR			0xC001102A
 
 #define CPU_ID_FEATURES_MSR		0xC0011004
 #define CPU_ID_HYPER_EXT_FEATURES	0xC001100d
Fix for Erratum 350 for AMD Fam10h CPUs.

Signed-off-by: Marco Schmidt <[email protected]>
Acked-by: Patrick Georgi <[email protected]>
Index: coreboot/src/northbridge/amd/amdmct/mct/mct_d.c
===================================================================
--- coreboot.orig/src/northbridge/amd/amdmct/mct/mct_d.c
+++ coreboot/src/northbridge/amd/amdmct/mct/mct_d.c
@@ -356,7 +356,7 @@ static void DQSTiming_D(struct MCTStatSt
 	phyAssistedMemFnceTraining(pMCTstat, pDCTstatA);
 
 	if (nv_DQSTrainCTL) {
-		mctHookBeforeAnyTraining();
+		mctHookBeforeAnyTraining(pMCTstat, pDCTstatA);
 
 		print_t("DQSTiming_D: TrainReceiverEn_D FirstPass:\n");
 		TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass);
Index: coreboot/src/northbridge/amd/amdmct/wrappers/mcti_d.c
===================================================================
--- coreboot.orig/src/northbridge/amd/amdmct/wrappers/mcti_d.c
+++ coreboot/src/northbridge/amd/amdmct/wrappers/mcti_d.c
@@ -18,7 +18,7 @@
  */
 
 /* Call-backs */
-
+#include <delay.h>
 u16 mctGet_NVbits(u8 index)
 {
 	u16 val = 0;
@@ -326,9 +326,79 @@ void mctHookAfterDramInit(void)
 {
 }
 
+static void coreDelay (void);
+
+
+/* Erratum 350 */
+void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
+{
+    u8 u8Channel;
+    u8 u8Receiver;
+    u32 u32Addr;
+	u8 u8Valid;
+    u32 u32DctDev;
+
+	// 1. dummy read for each installed DIMM ----------------------------------------------
+	for (u8Channel = 0; u8Channel < 2; u8Channel++)
+    {
+        // This will be 0 for vaild DIMMS, eles 8
+        u8Receiver = mct_InitReceiver_D(pDCTstat, u8Channel);
+
+		for (; u8Receiver < 8; u8Receiver += 2)
+        {
+			u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
+
+			if(!u8Valid) {	/* Address not supported on current CS */
+				print_t("vErrara350: Address not supported on current CS\n");
+				continue;
+			}
+            print_t("vErrara350: dummy read \n");
+            read32_fs(u32Addr);
+        }
+    }
+
+    print_t("vErrara350: step 2a\n");
+
+    // 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. --------------------------------
+	u32DctDev = pDCTstat->dev_dct;
+    Set_NB32_index_wait(u32DctDev, 0x098, 0x0c, 0x00008000);
+    //                                                ^--- value
+    //                                      ^---F2x[1, 0]9C_x0C DRAM Phy Miscellaneous Register
+    //                               ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register
+
+    if(!pDCTstat->GangedMode)
+    {
+        print_t("vErrara350: step 2b\n");
+        Set_NB32_index_wait(u32DctDev, 0x198, 0x0c, 0x00008000);
+        //                                                ^--- value
+        //                                      ^---F2x[1, 0]9C_x0C DRAM Phy Miscellaneous Register
+        //                               ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register
+    }
+
+    print_t("vErrara350: step 3\n");
+    // 3. Wait at least 300 nanoseconds. ---------------------------------------------------
+    coreDelay();
+
+    print_t("vErrara350: step 4\n");
+    // 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. -------------------------------
+    Set_NB32_index_wait(u32DctDev, 0x098, 0x0c, 0x00000000);
+
+    if(!pDCTstat->GangedMode)
+    {
+        print_t("vErrara350: step 4b\n");
+        Set_NB32_index_wait(u32DctDev, 0x198, 0x0c, 0x00000000);
+    }
+
+    print_t("vErrara350: step 5\n");
+    // 5. Wait at least 2 microseconds. --------------------------------------------------
+    coreDelay();
+
+}
+
 
-void mctHookBeforeAnyTraining(void)
+void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
 {
+    vErrata350(pMCTstat, pDCTstatA);
 }
 
 void mctHookAfterAnyTraining(void)
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to