[coreboot-gerrit] Patch set updated for coreboot: f3968c1 cpu/amd/agesa/family15tn: Add udelay implementation for SMM

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Tue Apr 15 22:47:44 CEST 2014


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5501

-gerrit

commit f3968c11fc5ed9ce4cd6f9148e4b526fd2ca14ce
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Tue Apr 15 15:41:38 2014 -0500

    cpu/amd/agesa/family15tn: Add udelay implementation for SMM
    
    This is a small implementation which uses only MSRs and rdtsc, without
    relying on northbridge or other system hardware. It's SMM safe in that
    it only reads registers, and doesn't modify the state of the hardware.
    
    Change-Id: Ifa02ca73455b382f830c9b30b80b4f1bb18706b4
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/cpu/amd/agesa/family15tn/Makefile.inc |  2 ++
 src/cpu/amd/agesa/family15tn/udelay.c     | 49 +++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/src/cpu/amd/agesa/family15tn/Makefile.inc b/src/cpu/amd/agesa/family15tn/Makefile.inc
index 19a2f0f..a8f644d 100644
--- a/src/cpu/amd/agesa/family15tn/Makefile.inc
+++ b/src/cpu/amd/agesa/family15tn/Makefile.inc
@@ -20,6 +20,8 @@
 ramstage-y += chip_name.c
 ramstage-y += model_15_init.c
 
+smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
+
 subdirs-y += ../../mtrr
 subdirs-y += ../../smm
 subdirs-y += ../../../x86/tsc
diff --git a/src/cpu/amd/agesa/family15tn/udelay.c b/src/cpu/amd/agesa/family15tn/udelay.c
new file mode 100644
index 0000000..7278fad
--- /dev/null
+++ b/src/cpu/amd/agesa/family15tn/udelay.c
@@ -0,0 +1,49 @@
+/*
+ * udelay() impementation for SMI handlers
+ * This is neat in that it never writes to hardware registers, and thus does not
+ * modify the state of the hardware while servicing SMIs.
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include <delay.h>
+#include <stdint.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/x86/msr.h>
+#include <console/console.h>
+
+void udelay(uint32_t us)
+{
+	uint8_t fid, did, pstate_idx;
+	uint64_t tsc_clock, tsc_start, tsc_end, tsc_now;
+	msr_t msr;
+	const uint64_t tsc_base = 100000000;
+
+	/* Get initial timestamp before we do the math */
+	tsc_start = rdtscll();
+
+	/* Get the P-state. This determines which MSR to read */
+	msr = rdmsr(0xc0010063);
+	pstate_idx = msr.lo & 0x07;
+
+	/* Get FID and VID for current P-State */
+	msr = rdmsr(0xc0010064 + pstate_idx);
+
+	/* Extract the FID and VID values */
+	fid = msr.lo & 0x3f;
+	did = (msr.lo >> 6) & 0x7;
+
+	/* Calculate the CPU clock (from base freq of 100MHz) */
+	tsc_clock = tsc_base * (fid + 0x10) / (1 << did);
+
+	/*
+	 * No worries about overflow. Even at 10GHz, we have over 55 years
+	 * before the TSC overflows.
+	 */
+	tsc_end = tsc_start + ((tsc_clock / 1000000) * us);
+
+	do {
+		tsc_now = rdtscll();
+	} while (tsc_now < tsc_end);
+}



More information about the coreboot-gerrit mailing list