"auto-boot?",
"petitboot,network",
"petitboot,timeout",
- "petitboot,bootdev",
"petitboot,bootdevs",
"petitboot,language",
"petitboot,debug?",
"petitboot,write?",
"petitboot,snapshots?",
+ "petitboot,console",
+ "petitboot,http_proxy",
+ "petitboot,https_proxy",
NULL,
};
#define to_platform_powerpc(p) \
(struct platform_powerpc *)(p->platform_data)
-/* a partition max a max size of 64k * 16bytes = 1M */
-static const int max_partition_size = 64 * 1024 * 16;
-
static bool param_is_known(const char *param, unsigned int len)
{
const char *known_param;
if (!strncmp(*pos, "uuid:", strlen("uuid:"))) {
prefix = strlen("uuid:");
opt->boot_type = BOOT_DEVICE_UUID;
- rc = 0;
} else if (!strncmp(*pos, "mac:", strlen("mac:"))) {
prefix = strlen("mac:");
opt->boot_type = BOOT_DEVICE_UUID;
- rc = 0;
} else {
type = find_device_type(*pos);
if (type != DEVICE_TYPE_UNKNOWN) {
if (delim)
len = (int)(delim - *pos) - prefix;
else
- len = strlen(*pos);
+ len = strlen(*pos) - prefix;
- opt->uuid = talloc_strndup(ctx, *pos + prefix, len);
+ if (len) {
+ opt->uuid = talloc_strndup(ctx, *pos + prefix, len);
+ rc = 0;
+ }
}
/* Always advance pointer to next option or end */
struct config *config)
{
struct autoboot_option *opt, *new = NULL;
- char *pos, *end, *old_dev = NULL;
+ char *pos, *end;
unsigned int n_new = 0;
const char *val;
- bool conflict;
-
- /* Check for old-style bootdev */
- val = get_param(platform, "petitboot,bootdev");
- if (val && strlen(val)) {
- pos = talloc_strdup(config, val);
- if (!strncmp(val, "uuid:", strlen("uuid:")))
- old_dev = talloc_strdup(config,
- val + strlen("uuid:"));
- else if (!strncmp(val, "mac:", strlen("mac:")))
- old_dev = talloc_strdup(config,
- val + strlen("mac:"));
- }
/* Check for ordered bootdevs */
val = get_param(platform, "petitboot,bootdevs");
}
- if (!n_new && !old_dev) {
+ if (!n_new) {
/* If autoboot has been disabled, clear the default options */
if (!config->autoboot_enabled) {
talloc_free(config->autoboot_opts);
return;
}
- conflict = old_dev && (!n_new ||
- new[0].boot_type == BOOT_DEVICE_TYPE ||
- /* Canonical UUIDs are 36 characters long */
- strncmp(new[0].uuid, old_dev, 36));
-
- if (!conflict) {
- talloc_free(config->autoboot_opts);
- config->autoboot_opts = new;
- config->n_autoboot_opts = n_new;
- return;
- }
-
- /*
- * Difference detected, defer to old format in case it has been updated
- * recently
- */
- pb_debug("Old autoboot bootdev detected\n");
talloc_free(config->autoboot_opts);
- config->autoboot_opts = talloc(config, struct autoboot_option);
- config->autoboot_opts[0].boot_type = BOOT_DEVICE_UUID;
- config->autoboot_opts[0].uuid = talloc_strdup(config, old_dev);
- config->n_autoboot_opts = 1;
+ config->autoboot_opts = new;
+ config->n_autoboot_opts = n_new;
}
static void populate_config(struct platform_powerpc *platform,
val = get_param(platform, "petitboot,snapshots?");
if (val)
config->disable_snapshots = !strcmp(val, "false");
+
+ val = get_param(platform, "petitboot,console");
+ if (val)
+ config->boot_console = talloc_strdup(config, val);
+ /* If a full path is already set we don't want to override it */
+ config->manual_console = config->boot_console &&
+ !strchr(config->boot_console, '[');
+
+ val = get_param(platform, "petitboot,http_proxy");
+ if (val)
+ config->http_proxy = talloc_strdup(config, val);
+ val = get_param(platform, "petitboot,https_proxy");
+ if (val)
+ config->https_proxy = talloc_strdup(config, val);
}
static char *iface_config_str(void *ctx, struct interface_config *config)
unsigned int i;
char *val;
+ /*
+ * Don't store IPMI overrides to NVRAM. If this was a persistent
+ * override it was already stored in NVRAM by
+ * get_ipmi_network_override()
+ */
+ if (config->network.n_interfaces &&
+ config->network.interfaces[0]->override)
+ return;
+
val = talloc_strdup(platform, "");
for (i = 0; i < config->network.n_interfaces; i++) {
static void update_bootdev_config(struct platform_powerpc *platform,
struct config *config)
{
- char *val = NULL, *boot_str = NULL, *tmp = NULL, *first = NULL;
+ char *val = NULL, *boot_str = NULL, *tmp = NULL;
struct autoboot_option *opt;
const char delim = ' ';
unsigned int i;
if (!config->n_autoboot_opts)
- first = val = "";
- else if (config->autoboot_opts[0].boot_type == BOOT_DEVICE_UUID)
- first = talloc_asprintf(config, "uuid:%s",
- config->autoboot_opts[0].uuid);
- else
- first = "";
+ val = "";
for (i = 0; i < config->n_autoboot_opts; i++) {
opt = &config->autoboot_opts[i];
}
update_string_config(platform, "petitboot,bootdevs", val);
- update_string_config(platform, "petitboot,bootdev", first);
talloc_free(tmp);
if (boot_str)
talloc_free(boot_str);
val = config->allow_writes ? "true" : "false";
update_string_config(platform, "petitboot,write?", val);
+ if (!config->manual_console) {
+ val = config->boot_console ?: "";
+ update_string_config(platform, "petitboot,console", val);
+ }
+
+ val = config->http_proxy ?: "";
+ update_string_config(platform, "petitboot,http_proxy", val);
+ val = config->https_proxy ?: "";
+ update_string_config(platform, "petitboot,https_proxy", val);
+
update_network_config(platform, config);
update_bootdev_config(platform, config);
config->ipmi_bootdev = bootdev;
config->ipmi_bootdev_persistent = persistent;
- switch (bootdev) {
- case IPMI_BOOTDEV_NONE:
- case IPMI_BOOTDEV_DISK:
- case IPMI_BOOTDEV_NETWORK:
- case IPMI_BOOTDEV_CDROM:
- default:
- break;
- case IPMI_BOOTDEV_SETUP:
- config->autoboot_enabled = false;
- break;
- case IPMI_BOOTDEV_SAFE:
- config->autoboot_enabled = false;
+ if (bootdev == IPMI_BOOTDEV_SAFE)
config->safe_mode = true;
- break;
- }
}
static int read_bootdev_sysparam(const char *name, uint8_t *val)
/* check for valid flags */
if (!(resp[3] & 0x80)) {
pb_debug("platform: boot flags are invalid, ignoring\n");
- return 0;
+ return -1;
}
*persistent = resp[3] & 0x40;
struct platform_powerpc *platform = p->platform_data;
uint16_t resp_len = 16;
uint8_t resp[16], bcd;
- uint32_t aux_version;
int i, rc;
/* Retrieve info from current side */
pb_debug("\n");
}
- if (rc == 0 && resp_len == 16) {
+ if (rc == 0 && (resp_len == 12 || resp_len == 16)) {
info->bmc_current = talloc_array(info, char *, 4);
info->n_bmc_current = 4;
resp[2]);
bcd = resp[4] & 0x0f;
bcd += 10 * (resp[4] >> 4);
- memcpy(&aux_version, &resp[12], sizeof(aux_version));
+ /* rev1.rev2.aux_revision */
info->bmc_current[2] = talloc_asprintf(info,
- "Firmware version: %u.%02u.%u",
- resp[3], bcd, aux_version);
+ "Firmware version: %u.%02u",
+ resp[3], bcd);
+ if (resp_len == 16) {
+ info->bmc_current[2] = talloc_asprintf_append(
+ info->bmc_current[2],
+ ".%02x%02x%02x%02x",
+ resp[12], resp[13], resp[14], resp[15]);
+ }
bcd = resp[5] & 0x0f;
bcd += 10 * (resp[5] >> 4);
info->bmc_current[3] = talloc_asprintf(info, "IPMI version: %u",
pb_debug("\n");
}
- if (rc == 0 && resp_len == 16) {
+ if (rc == 0 && (resp_len == 12 || resp_len == 16)) {
info->bmc_golden = talloc_array(info, char *, 4);
info->n_bmc_golden = 4;
resp[2]);
bcd = resp[4] & 0x0f;
bcd += 10 * (resp[4] >> 4);
- memcpy(&aux_version, &resp[12], sizeof(aux_version));
+ /* rev1.rev2.aux_revision */
info->bmc_golden[2] = talloc_asprintf(info,
- "Firmware version: %u.%02u.%u",
- resp[3], bcd, aux_version);
+ "Firmware version: %u.%02u",
+ resp[3], bcd);
+ if (resp_len == 16) {
+ info->bmc_golden[2] = talloc_asprintf_append(
+ info->bmc_golden[2],
+ ".%02x%02x%02x%02x",
+ resp[12], resp[13], resp[14], resp[15]);
+ }
bcd = resp[5] & 0x0f;
bcd += 10 * (resp[5] >> 4);
info->bmc_golden[3] = talloc_asprintf(info, "IPMI version: %u",
}
}
+static void get_active_consoles(struct config *config)
+{
+ struct stat sbuf;
+ char *fsp_prop = NULL;
+
+ config->n_consoles = 2;
+ config->consoles = talloc_array(config, char *, config->n_consoles);
+ if (!config->consoles)
+ goto err;
+
+ config->consoles[0] = talloc_asprintf(config->consoles,
+ "/dev/hvc0 [IPMI / Serial]");
+ config->consoles[1] = talloc_asprintf(config->consoles,
+ "/dev/tty1 [VGA]");
+
+ fsp_prop = talloc_asprintf(config, "%sfsps", devtree_dir);
+ if (stat(fsp_prop, &sbuf) == 0) {
+ /* FSP based machines also have a separate serial console */
+ config->consoles = talloc_realloc(config, config->consoles,
+ char *, config->n_consoles + 1);
+ if (!config->consoles)
+ goto err;
+ config->consoles[config->n_consoles++] = talloc_asprintf(
+ config->consoles,
+ "/dev/hvc1 [Serial]");
+ }
+
+ return;
+err:
+ config->n_consoles = 0;
+ pb_log("Failed to allocate memory for consoles\n");
+}
+
static int load_config(struct platform *p, struct config *config)
{
struct platform_powerpc *platform = to_platform_powerpc(p);
rc = parse_nvram(platform);
if (rc)
- return rc;
+ pb_log("%s: Failed to parse nvram\n", __func__);
populate_config(platform, config);
if (platform->get_ipmi_bootdev) {
bool bootdev_persistent;
- uint8_t bootdev;
+ uint8_t bootdev = IPMI_BOOTDEV_INVALID;
rc = platform->get_ipmi_bootdev(platform, &bootdev,
&bootdev_persistent);
if (!rc && ipmi_bootdev_is_valid(bootdev)) {
if (platform->ipmi)
get_ipmi_network_override(platform, config);
+ get_active_consoles(config);
+
return 0;
}
{
struct platform_powerpc *platform;
struct stat statbuf;
+ bool bmc_present;
int rc;
/* we need a device tree */
p->platform_data = platform;
- if (ipmi_present()) {
+ bmc_present = stat("/proc/device-tree/bmc", &statbuf) == 0;
+
+ if (ipmi_present() && bmc_present) {
pb_debug("platform: using direct IPMI for IPMI paramters\n");
platform->ipmi = ipmi_open(platform);
platform->get_ipmi_bootdev = get_ipmi_bootdev_ipmi;
pb_log("platform: no IPMI parameter support\n");
}
- rc = stat("/proc/device-tree/bmc", &statbuf);
- if (!rc)
+ if (bmc_present)
platform->get_platform_versions = hostboot_load_versions;
return true;