summaryrefslogtreecommitdiffstats
path: root/discover/platform-powerpc.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2014-12-11 16:38:21 +0800
committerJeremy Kerr <jk@ozlabs.org>2014-12-15 15:47:40 +0800
commitd3e95283e69d3099fe9f36e56be1f645f565c843 (patch)
tree42e2f2c71ede42c9922a327b26340b5909f65b5a /discover/platform-powerpc.c
parentf69fabee4a120cebaeff2359350e62bd960088f4 (diff)
downloadtalos-petitboot-d3e95283e69d3099fe9f36e56be1f645f565c843.tar.gz
talos-petitboot-d3e95283e69d3099fe9f36e56be1f645f565c843.zip
discover: Integrate ipmi bootdev settings into the priority system
Currently, we expose the boot device priorities through an array in struct config, which will either be the default (network -> disk), or a single device type specified by the IPMI code. Rather than hide the implementation details in this array, we'd like to expose the details of the machine configuration instead. This allows user visibility of the real boot configuration (for example, if an IPMI boot preference is set). This change removes the priority array, and replaces it with the ipmi_bootdev data (and a persistent flag). We update the default-conflict-resolution code to reflect the priorities between IPMI and UUID preferences. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/platform-powerpc.c')
-rw-r--r--discover/platform-powerpc.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c
index 6ae28f4..5f6772f 100644
--- a/discover/platform-powerpc.c
+++ b/discover/platform-powerpc.c
@@ -30,7 +30,12 @@ struct param {
};
struct platform_powerpc {
- struct list params;
+ struct list params;
+ int (*get_ipmi_bootdev)(
+ struct platform_powerpc *platform,
+ uint8_t *bootdev, bool *persistent);
+ int (*clear_ipmi_bootdev)(
+ struct platform_powerpc *platform);
};
static const char *known_params[] = {
@@ -570,32 +575,17 @@ static int update_config(struct platform_powerpc *platform,
return write_nvram(platform);
}
-static void set_exclusive_devtype(struct config *config,
- enum device_type devtype)
+static void set_ipmi_bootdev(struct config *config, enum ipmi_bootdev bootdev,
+ bool persistent)
{
- config->n_boot_priorities = 2;
- config->boot_priorities = talloc_realloc(config,
- config->boot_priorities, struct boot_priority,
- config->n_boot_priorities);
- config->boot_priorities[0].type = devtype;
- config->boot_priorities[0].priority = 0;
- config->boot_priorities[1].type = DEVICE_TYPE_ANY;
- config->boot_priorities[1].priority = -1;
-}
+ config->ipmi_bootdev = bootdev;
+ config->ipmi_bootdev_persistent = persistent;
-static void set_ipmi_bootdev(struct config *config, enum ipmi_bootdev bootdev)
-{
switch (bootdev) {
case IPMI_BOOTDEV_NONE:
- break;
case IPMI_BOOTDEV_DISK:
- set_exclusive_devtype(config, DEVICE_TYPE_DISK);
- break;
case IPMI_BOOTDEV_NETWORK:
- set_exclusive_devtype(config, DEVICE_TYPE_NETWORK);
- break;
case IPMI_BOOTDEV_CDROM:
- set_exclusive_devtype(config, DEVICE_TYPE_OPTICAL);
break;
case IPMI_BOOTDEV_SETUP:
config->autoboot_enabled = false;
@@ -684,7 +674,17 @@ static int write_bootdev_sysparam(const char *name, uint8_t val)
return rc;
}
-static void parse_opal_sysparams(struct config *config)
+static int clear_ipmi_bootdev_sysparams(
+ struct platform_powerpc *platform __attribute__((unused)))
+{
+ /* invalidate next-boot-device setting */
+ write_bootdev_sysparam("next-boot-device", 0xff);
+ return 0;
+}
+
+static int get_ipmi_bootdev_sysparams(
+ struct platform_powerpc *platform __attribute__((unused)),
+ uint8_t *bootdev, bool *persistent)
{
uint8_t next_bootdev, default_bootdev;
bool next_valid, default_valid;
@@ -698,12 +698,11 @@ static void parse_opal_sysparams(struct config *config)
/* nothing valid? no need to change the config */
if (!next_valid && !default_valid)
- return;
-
- if (!next_valid)
- next_bootdev = default_bootdev;
+ return -1;
- set_ipmi_bootdev(config, next_bootdev);
+ *persistent = !next_valid;
+ *bootdev = next_valid ? next_bootdev : default_bootdev;
+ return 0;
}
static int load_config(struct platform *p, struct config *config)
@@ -717,7 +716,15 @@ static int load_config(struct platform *p, struct config *config)
populate_config(platform, config);
- parse_opal_sysparams(config);
+ if (platform->get_ipmi_bootdev) {
+ bool bootdev_persistent;
+ uint8_t bootdev;
+ rc = platform->get_ipmi_bootdev(platform, &bootdev,
+ &bootdev_persistent);
+ if (!rc && ipmi_bootdev_is_valid(bootdev)) {
+ set_ipmi_bootdev(config, bootdev, bootdev_persistent);
+ }
+ }
return 0;
}
@@ -737,10 +744,12 @@ static int save_config(struct platform *p, struct config *config)
return rc;
}
-static void finalise_config(struct platform *platform __attribute__((unused)))
+static void finalise_config(struct platform *p, const struct config *config)
{
- /* invalidate next-boot-device setting */
- write_bootdev_sysparam("next-boot-device", 0xff);
+ struct platform_powerpc *platform = to_platform_powerpc(p);
+
+ if (config->ipmi_bootdev_persistent && platform->clear_ipmi_bootdev)
+ platform->clear_ipmi_bootdev(platform);
}
static int get_sysinfo(struct platform *p, struct system_info *sysinfo)
@@ -782,6 +791,15 @@ static bool probe(struct platform *p, void *ctx)
list_init(&platform->params);
p->platform_data = platform;
+
+ if (!stat(sysparams_dir, &statbuf)) {
+ pb_debug("platform: using sysparams for IPMI paramters\n");
+ platform->get_ipmi_bootdev = get_ipmi_bootdev_sysparams;
+ platform->clear_ipmi_bootdev = clear_ipmi_bootdev_sysparams;
+
+ } else {
+ pb_log("platform: no IPMI parameter support\n");
+ }
return true;
}
OpenPOWER on IntegriCloud