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@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/176304 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Commit-Queue: Aaron Durbin <adurbin@chromium.org> Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4951 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
parent
9e68fe68ff
commit
fd461e396b
|
@ -59,12 +59,14 @@ enum {
|
||||||
REG_SCRIPT_TYPE_MMIO,
|
REG_SCRIPT_TYPE_MMIO,
|
||||||
REG_SCRIPT_TYPE_RES,
|
REG_SCRIPT_TYPE_RES,
|
||||||
REG_SCRIPT_TYPE_IOSF,
|
REG_SCRIPT_TYPE_IOSF,
|
||||||
|
REG_SCRIPT_TYPE_MSR,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REG_SCRIPT_SIZE_8,
|
REG_SCRIPT_SIZE_8,
|
||||||
REG_SCRIPT_SIZE_16,
|
REG_SCRIPT_SIZE_16,
|
||||||
REG_SCRIPT_SIZE_32,
|
REG_SCRIPT_SIZE_32,
|
||||||
|
REG_SCRIPT_SIZE_64,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reg_script {
|
struct reg_script {
|
||||||
|
@ -72,8 +74,8 @@ struct reg_script {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
uint32_t mask;
|
uint64_t mask;
|
||||||
uint32_t value;
|
uint64_t value;
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
union {
|
union {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
@ -289,6 +291,26 @@ struct reg_script {
|
||||||
#define REG_IOSF_POLL(unit_, reg_, mask_, value_, timeout_) \
|
#define REG_IOSF_POLL(unit_, reg_, mask_, value_, timeout_) \
|
||||||
REG_SCRIPT_IOSF(POLL, unit_, reg_, mask_, value_, timeout_)
|
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.
|
* Chain to another table.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <reg_script.h>
|
#include <reg_script.h>
|
||||||
|
|
||||||
|
#if CONFIG_ARCH_X86
|
||||||
|
#include <cpu/x86/msr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SOC_INTEL_BAYTRAIL
|
#if CONFIG_SOC_INTEL_BAYTRAIL
|
||||||
#include <baytrail/iosf.h>
|
#include <baytrail/iosf.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -285,7 +289,31 @@ static void reg_script_write_iosf(struct reg_script_context *ctx)
|
||||||
#endif
|
#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);
|
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);
|
return reg_script_read_res(ctx);
|
||||||
case REG_SCRIPT_TYPE_IOSF:
|
case REG_SCRIPT_TYPE_IOSF:
|
||||||
return reg_script_read_iosf(ctx);
|
return reg_script_read_iosf(ctx);
|
||||||
|
case REG_SCRIPT_TYPE_MSR:
|
||||||
|
return reg_script_read_msr(ctx);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -324,12 +354,15 @@ static void reg_script_write(struct reg_script_context *ctx)
|
||||||
case REG_SCRIPT_TYPE_IOSF:
|
case REG_SCRIPT_TYPE_IOSF:
|
||||||
reg_script_write_iosf(ctx);
|
reg_script_write_iosf(ctx);
|
||||||
break;
|
break;
|
||||||
|
case REG_SCRIPT_TYPE_MSR:
|
||||||
|
reg_script_write_msr(ctx);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reg_script_rmw(struct reg_script_context *ctx)
|
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);
|
const struct reg_script *step = reg_script_get_step(ctx);
|
||||||
struct reg_script write_step = *step;
|
struct reg_script write_step = *step;
|
||||||
|
|
||||||
|
@ -349,15 +382,11 @@ static void reg_script_rmw(struct reg_script_context *ctx)
|
||||||
static void reg_script_run_next(struct reg_script_context *ctx,
|
static void reg_script_run_next(struct reg_script_context *ctx,
|
||||||
const struct reg_script *step);
|
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;
|
||||||
|
|
||||||
while (1) {
|
|
||||||
const struct reg_script *step = reg_script_get_step(ctx);
|
|
||||||
|
|
||||||
if (step->command == REG_SCRIPT_COMMAND_END)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (step->command) {
|
switch (step->command) {
|
||||||
case REG_SCRIPT_COMMAND_READ:
|
case REG_SCRIPT_COMMAND_READ:
|
||||||
|
@ -377,9 +406,10 @@ static void reg_script_run_with_context(struct reg_script_context *ctx)
|
||||||
udelay(POLL_DELAY);
|
udelay(POLL_DELAY);
|
||||||
}
|
}
|
||||||
if (try >= step->timeout)
|
if (try >= step->timeout)
|
||||||
printk(BIOS_WARNING, "%s: POLL timeout waiting "
|
printk(BIOS_WARNING, "%s: POLL timeout waiting for "
|
||||||
"for 0x%08x to be 0x%08x, got 0x%08x\n",
|
"0x%x to be 0x%lx, got 0x%lx\n", __func__,
|
||||||
__func__, step->reg, step->value, value);
|
step->reg, (unsigned long)step->value,
|
||||||
|
(unsigned long)value);
|
||||||
break;
|
break;
|
||||||
case REG_SCRIPT_COMMAND_SET_DEV:
|
case REG_SCRIPT_COMMAND_SET_DEV:
|
||||||
reg_script_set_dev(ctx, step->dev);
|
reg_script_set_dev(ctx, step->dev);
|
||||||
|
@ -392,7 +422,17 @@ static void reg_script_run_with_context(struct reg_script_context *ctx)
|
||||||
step->command);
|
step->command);
|
||||||
break;
|
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;
|
||||||
|
|
||||||
|
reg_script_run_step(ctx, step);
|
||||||
reg_script_set_step(ctx, step + 1);
|
reg_script_set_step(ctx, step + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue