[coreboot-gerrit] Patch set updated for coreboot: c8938ab regscript: Add support for MSR type

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue May 6 01:02:06 CEST 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4951

-gerrit

commit c8938abe7009eab73560c2d7c8d14b1ec9d0b641
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Fri Nov 8 23:00:24 2013 -0800

    regscript: Add support for MSR type
    
    This required changing value/mask types to uint64_t.
    
    Another option would be to use id field to select low or high
    32 bits of the MSR and set them independently.
    
    BUG=chrome-os-partner:23505
    BRANCH=none
    TEST=build and boot on rambi
    
    Change-Id: Ied9998058a8035bf3f003185236f3be3e0df7fc9
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/176304
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Commit-Queue: Aaron Durbin <adurbin at chromium.org>
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/reg_script.h |  26 ++++++++++-
 src/lib/reg_script.c     | 116 +++++++++++++++++++++++++++++++----------------
 2 files changed, 102 insertions(+), 40 deletions(-)

diff --git a/src/include/reg_script.h b/src/include/reg_script.h
index 18eda0c..81a4648 100644
--- a/src/include/reg_script.h
+++ b/src/include/reg_script.h
@@ -59,12 +59,14 @@ enum {
 	REG_SCRIPT_TYPE_MMIO,
 	REG_SCRIPT_TYPE_RES,
 	REG_SCRIPT_TYPE_IOSF,
+	REG_SCRIPT_TYPE_MSR,
 };
 
 enum {
 	REG_SCRIPT_SIZE_8,
 	REG_SCRIPT_SIZE_16,
 	REG_SCRIPT_SIZE_32,
+	REG_SCRIPT_SIZE_64,
 };
 
 struct reg_script {
@@ -72,8 +74,8 @@ struct reg_script {
 	uint32_t type;
 	uint32_t size;
 	uint32_t reg;
-	uint32_t mask;
-	uint32_t value;
+	uint64_t mask;
+	uint64_t value;
 	uint32_t timeout;
 	union {
 		uint32_t id;
@@ -290,6 +292,26 @@ struct reg_script {
 	REG_SCRIPT_IOSF(POLL, unit_, reg_, mask_, value_, timeout_)
 
 /*
+ * CPU Model Specific Register
+ */
+
+#define REG_SCRIPT_MSR(cmd_, reg_, mask_, value_, timeout_) \
+	_REG_SCRIPT_ENCODE_RAW(REG_SCRIPT_COMMAND_##cmd_,   \
+			       REG_SCRIPT_TYPE_MSR,         \
+			       REG_SCRIPT_SIZE_64,          \
+			       reg_, mask_, value_, timeout_, 0)
+#define REG_MSR_READ(reg_) \
+	REG_SCRIPT_MSR(READ, reg_, 0, 0, 0)
+#define REG_MSR_WRITE(reg_, value_) \
+	REG_SCRIPT_MSR(WRITE, reg_, 0, value_, 0)
+#define REG_MSR_RMW(reg_, mask_, value_) \
+	REG_SCRIPT_MSR(RMW, reg_, mask_, value_, 0)
+#define REG_MSR_OR(reg_, value_) \
+	REG_MSR_RMW(reg_, -1ULL, value_)
+#define REG_MSR_POLL(reg_, mask_, value_, timeout_) \
+	REG_SCRIPT_MSR(POLL, reg_, mask_, value_, timeout_)
+
+/*
  * Chain to another table.
  */
 #define REG_SCRIPT_NEXT(next_)                \
diff --git a/src/lib/reg_script.c b/src/lib/reg_script.c
index 252aa12..3ca0b4a 100644
--- a/src/lib/reg_script.c
+++ b/src/lib/reg_script.c
@@ -26,6 +26,10 @@
 #include <stdint.h>
 #include <reg_script.h>
 
+#if CONFIG_ARCH_X86
+#include <cpu/x86/msr.h>
+#endif
+
 #if CONFIG_SOC_INTEL_BAYTRAIL
 #include <baytrail/iosf.h>
 #endif
@@ -285,7 +289,31 @@ static void reg_script_write_iosf(struct reg_script_context *ctx)
 #endif
 }
 
-static uint32_t reg_script_read(struct reg_script_context *ctx)
+static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
+{
+#if CONFIG_ARCH_X86
+	const struct reg_script *step = reg_script_get_step(ctx);
+	msr_t msr = rdmsr(step->reg);
+	uint64_t value = msr.hi;
+	value = msr.hi;
+	value <<= 32;
+	value |= msr.lo;
+	return value;
+#endif
+}
+
+static void reg_script_write_msr(struct reg_script_context *ctx)
+{
+#if CONFIG_ARCH_X86
+	const struct reg_script *step = reg_script_get_step(ctx);
+	msr_t msr;
+	msr.hi = step->value >> 32;
+	msr.lo = step->value & 0xffffffff;
+	wrmsr(step->reg, msr);
+#endif
+}
+
+static uint64_t reg_script_read(struct reg_script_context *ctx)
 {
 	const struct reg_script *step = reg_script_get_step(ctx);
 
@@ -300,6 +328,8 @@ static uint32_t reg_script_read(struct reg_script_context *ctx)
 		return reg_script_read_res(ctx);
 	case REG_SCRIPT_TYPE_IOSF:
 		return reg_script_read_iosf(ctx);
+	case REG_SCRIPT_TYPE_MSR:
+		return reg_script_read_msr(ctx);
 	}
 	return 0;
 }
@@ -324,12 +354,15 @@ static void reg_script_write(struct reg_script_context *ctx)
 	case REG_SCRIPT_TYPE_IOSF:
 		reg_script_write_iosf(ctx);
 		break;
+	case REG_SCRIPT_TYPE_MSR:
+		reg_script_write_msr(ctx);
+		break;
 	}
 }
 
 static void reg_script_rmw(struct reg_script_context *ctx)
 {
-	uint32_t value;
+	uint64_t value;
 	const struct reg_script *step = reg_script_get_step(ctx);
 	struct reg_script write_step = *step;
 
@@ -349,50 +382,57 @@ static void reg_script_rmw(struct reg_script_context *ctx)
 static void reg_script_run_next(struct reg_script_context *ctx,
                                 const struct reg_script *step);
 
-static void reg_script_run_with_context(struct reg_script_context *ctx)
+
+static void reg_script_run_step(struct reg_script_context *ctx,
+				const struct reg_script *step)
 {
-	uint32_t value = 0, try;
+	uint64_t value = 0, try;
 
+	switch (step->command) {
+	case REG_SCRIPT_COMMAND_READ:
+		(void)reg_script_read(ctx);
+		break;
+	case REG_SCRIPT_COMMAND_WRITE:
+		reg_script_write(ctx);
+		break;
+	case REG_SCRIPT_COMMAND_RMW:
+		reg_script_rmw(ctx);
+		break;
+	case REG_SCRIPT_COMMAND_POLL:
+		for (try = 0; try < step->timeout; try += POLL_DELAY) {
+			value = reg_script_read(ctx) & step->mask;
+			if (value == step->value)
+				break;
+			udelay(POLL_DELAY);
+		}
+		if (try >= step->timeout)
+			printk(BIOS_WARNING, "%s: POLL timeout waiting for "
+			       "0x%x to be 0x%lx, got 0x%lx\n", __func__,
+			       step->reg, (unsigned long)step->value,
+			       (unsigned long)value);
+		break;
+	case REG_SCRIPT_COMMAND_SET_DEV:
+		reg_script_set_dev(ctx, step->dev);
+		break;
+	case REG_SCRIPT_COMMAND_NEXT:
+		reg_script_run_next(ctx, step->next);
+		break;
+	default:
+		printk(BIOS_WARNING, "Invalid command: %08x\n",
+		       step->command);
+		break;
+	}
+}
+
+static void reg_script_run_with_context(struct reg_script_context *ctx)
+{
 	while (1) {
 		const struct reg_script *step = reg_script_get_step(ctx);
 
 		if (step->command == REG_SCRIPT_COMMAND_END)
 			break;
 
-		switch (step->command) {
-		case REG_SCRIPT_COMMAND_READ:
-			(void)reg_script_read(ctx);
-			break;
-		case REG_SCRIPT_COMMAND_WRITE:
-			reg_script_write(ctx);
-			break;
-		case REG_SCRIPT_COMMAND_RMW:
-			reg_script_rmw(ctx);
-			break;
-		case REG_SCRIPT_COMMAND_POLL:
-			for (try = 0; try < step->timeout; try += POLL_DELAY) {
-				value = reg_script_read(ctx) & step->mask;
-				if (value == step->value)
-					break;
-				udelay(POLL_DELAY);
-			}
-			if (try >= step->timeout)
-				printk(BIOS_WARNING, "%s: POLL timeout waiting "
-				       "for 0x%08x to be 0x%08x, got 0x%08x\n",
-				       __func__, step->reg, step->value, value);
-			break;
-		case REG_SCRIPT_COMMAND_SET_DEV:
-			reg_script_set_dev(ctx, step->dev);
-			break;
-		case REG_SCRIPT_COMMAND_NEXT:
-			reg_script_run_next(ctx, step->next);
-			break;
-		default:
-			printk(BIOS_WARNING, "Invalid command: %08x\n",
-			       step->command);
-			break;
-		}
-
+		reg_script_run_step(ctx, step);
 		reg_script_set_step(ctx, step + 1);
 	}
 }



More information about the coreboot-gerrit mailing list