Add table driven way to add platform specific reg_script routines

Extend lib/reg_script.c to use a platform table to declare
additional platform specific register access routine functions.
REG_SCRIPT_TYPE_PLATFORM_BASE is the starting value for platform
specific register types.  Additional register access types may be
defined above this value.  The type and access routines are placed
into reg_script_type_table.

The Baytrail type value for IOSF was left the enumeration since it
was already defined and is being used for Braswell.

BRANCH=none
BUG=None
TEST=Use the following steps to test:
1.  Build for a Baytrail platform
2.  Build for the Samus platform
3.  Add a platform_bus_table routine to a platform which returns the
    address of an array of reg_script_bus_entry structures and the
    number of entries in the array.

Change-Id: Ic99d345c4b067c52b4e9c47e59ed4472a05bc1a5
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
Original-Commit-Id: 2d9fecf4287dff6311a81d818603212248f1a248
Original-Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/215645
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Original-Change-Id: I7cd37abc5a08cadb3166d4048f65b919b86ab5db
Original-Reviewed-on: https://chromium-review.googlesource.com/229612
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/9279
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Lee Leahy
2014-08-29 13:38:59 -07:00
committed by Patrick Georgi
parent a19a4e1d64
commit 9f5a5c5323
2 changed files with 98 additions and 14 deletions

View File

@ -41,12 +41,6 @@
#define EMPTY_DEV NULL
#endif
struct reg_script_context {
device_t dev;
struct resource *res;
const struct reg_script *step;
};
static inline void reg_script_set_dev(struct reg_script_context *ctx,
device_t dev)
{
@ -243,9 +237,9 @@ static void reg_script_write_res(struct reg_script_context *ctx)
reg_script_set_step(ctx, step);
}
#if CONFIG_SOC_INTEL_BAYTRAIL
static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
{
#if CONFIG_SOC_INTEL_BAYTRAIL
const struct reg_script *step = reg_script_get_step(ctx);
switch (step->id) {
@ -296,13 +290,11 @@ static uint32_t reg_script_read_iosf(struct reg_script_context *ctx)
step->id);
break;
}
#endif
return 0;
}
static void reg_script_write_iosf(struct reg_script_context *ctx)
{
#if CONFIG_SOC_INTEL_BAYTRAIL
const struct reg_script *step = reg_script_get_step(ctx);
switch (step->id) {
@ -374,8 +366,9 @@ static void reg_script_write_iosf(struct reg_script_context *ctx)
step->id);
break;
}
#endif
}
#endif
static uint64_t reg_script_read_msr(struct reg_script_context *ctx)
{
@ -401,6 +394,36 @@ static void reg_script_write_msr(struct reg_script_context *ctx)
#endif
}
#ifndef __PRE_RAM__
/* Default routine provided for systems without platform specific busses */
const struct reg_script_bus_entry *__attribute__((weak))
platform_bus_table(size_t *table_entries)
{
/* No platform bus type table supplied */
*table_entries = 0;
return NULL;
}
/* Locate the structure containing the platform specific bus access routines */
static const struct reg_script_bus_entry
*find_bus(const struct reg_script *step)
{
const struct reg_script_bus_entry *bus;
size_t table_entries;
size_t i;
/* Locate the platform specific bus */
bus = platform_bus_table(&table_entries);
for (i = 0; i < table_entries; i++) {
if (bus[i].type == step->type)
return &bus[i];
}
/* Bus not found */
return NULL;
}
#endif
static uint64_t reg_script_read(struct reg_script_context *ctx)
{
const struct reg_script *step = reg_script_get_step(ctx);
@ -414,10 +437,27 @@ static uint64_t reg_script_read(struct reg_script_context *ctx)
return reg_script_read_mmio(ctx);
case REG_SCRIPT_TYPE_RES:
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);
#if CONFIG_SOC_INTEL_BAYTRAIL
case REG_SCRIPT_TYPE_IOSF:
return reg_script_read_iosf(ctx);
#endif
default:
#ifndef __PRE_RAM__
{
const struct reg_script_bus_entry *bus;
/* Read from the platform specific bus */
bus = find_bus(step);
if (NULL != bus)
return bus->reg_script_read(ctx);
}
#endif
printk(BIOS_ERR,
"Unsupported read type (0x%x) for this device!\n",
step->type);
break;
}
return 0;
}
@ -439,11 +479,30 @@ static void reg_script_write(struct reg_script_context *ctx)
case REG_SCRIPT_TYPE_RES:
reg_script_write_res(ctx);
break;
case REG_SCRIPT_TYPE_MSR:
reg_script_write_msr(ctx);
break;
#if CONFIG_SOC_INTEL_BAYTRAIL
case REG_SCRIPT_TYPE_IOSF:
reg_script_write_iosf(ctx);
break;
case REG_SCRIPT_TYPE_MSR:
reg_script_write_msr(ctx);
#endif
default:
#ifndef __PRE_RAM__
{
const struct reg_script_bus_entry *bus;
/* Write to the platform specific bus */
bus = find_bus(step);
if (NULL != bus) {
bus->reg_script_write(ctx);
return;
}
}
#endif
printk(BIOS_ERR,
"Unsupported write type (0x%x) for this device!\n",
step->type);
break;
}
}