summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorLee Leahy <leroy.p.leahy@intel.com>2014-08-29 13:38:59 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-04-04 12:40:29 +0200
commit9f5a5c532343fe72753fc507b0f2ef1a26afabd3 (patch)
treebe1f1b955ce316f24871ec2da4785a2d6e988e9b /src/lib
parenta19a4e1d64ab0dbf531a3fbeb7cdda331a3ed6ca (diff)
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>
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/reg_script.c87
1 files changed, 73 insertions, 14 deletions
diff --git a/src/lib/reg_script.c b/src/lib/reg_script.c
index 2fd943e3a1..3f7ddaf3da 100644
--- a/src/lib/reg_script.c
+++ b/src/lib/reg_script.c
@@ -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;
}
}