]> git.ozlabs.org Git - petitboot/blobdiff - discover/platform-powerpc.c
discover: Add petitboot,tty and track available consoles
[petitboot] / discover / platform-powerpc.c
index 98deea557b920ab4ae215366fed7398a35ac671c..eb54c6dddf231d73a5f1f1965f76703f7967d471 100644 (file)
@@ -59,6 +59,7 @@ static const char *known_params[] = {
        "petitboot,debug?",
        "petitboot,write?",
        "petitboot,snapshots?",
+       "petitboot,tty",
        NULL,
 };
 
@@ -565,6 +566,10 @@ 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,tty");
+       if (val)
+               config->boot_tty = talloc_strdup(config, val);
 }
 
 static char *iface_config_str(void *ctx, struct interface_config *config)
@@ -732,6 +737,9 @@ static int update_config(struct platform_powerpc *platform,
                val = config->allow_writes ? "true" : "false";
        update_string_config(platform, "petitboot,write?", val);
 
+       val = config->boot_tty ?: "";
+       update_string_config(platform, "petitboot,tty", val);
+
        update_network_config(platform, config);
 
        update_bootdev_config(platform, config);
@@ -956,7 +964,7 @@ static int get_ipmi_bootdev_ipmi(struct platform_powerpc *platform,
        /* 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;
@@ -1066,7 +1074,7 @@ static void get_ipmi_bmc_versions(struct platform *p, struct system_info *info)
                bcd += 10 * (resp[4] >> 4);
                memcpy(&aux_version, &resp[12], sizeof(aux_version));
                info->bmc_current[2] = talloc_asprintf(info,
-                                               "Firmware version: %u.%u.%u",
+                                               "Firmware version: %u.%02u.%05u",
                                                resp[3], bcd, aux_version);
                bcd = resp[5] & 0x0f;
                bcd += 10 * (resp[5] >> 4);
@@ -1104,7 +1112,7 @@ static void get_ipmi_bmc_versions(struct platform *p, struct system_info *info)
                bcd += 10 * (resp[4] >> 4);
                memcpy(&aux_version, &resp[12], sizeof(aux_version));
                info->bmc_golden[2] = talloc_asprintf(info,
-                                               "Firmware version: %u.%u.%u",
+                                               "Firmware version: %u.%02u.%u",
                                                resp[3], bcd, aux_version);
                bcd = resp[5] & 0x0f;
                bcd += 10 * (resp[5] >> 4);
@@ -1121,6 +1129,7 @@ static void get_ipmi_network_override(struct platform_powerpc *platform,
        const uint32_t magic_value = 0x21706221;
        uint8_t resp[resp_len];
        uint32_t cookie;
+       bool persistent;
        int i, rc;
        uint8_t req[] = {
                0x61, /* parameter selector: OEM section (network) */
@@ -1169,18 +1178,21 @@ static void get_ipmi_network_override(struct platform_powerpc *platform,
                return;
        }
 
-       /* Check for valid parameters. For now ignore the persistent flag */
+       /* Check that the parameters are valid */
        if (resp[2] & 0x80) {
                pb_debug("platform: network override is invalid/locked\n");
                return;
        }
 
-       /* Check for valid parameters in the boot flags section, ignoring the
-        * persistent bit */
+       /* Check for valid parameters in the boot flags section */
        if (!(resp[3] & 0x80)) {
                pb_debug("platform: network override valid flag not set\n");
                return;
        }
+       /* Read the persistent flag; if it is set we need to save this config */
+       persistent = resp[3] & 0x40;
+       if (persistent)
+               pb_debug("platform: network override is persistent\n");
 
        /* Check 4-byte cookie value */
        i = 4;
@@ -1202,7 +1214,48 @@ static void get_ipmi_network_override(struct platform_powerpc *platform,
        }
 
        /* Interpret the rest of the interface config */
-       parse_ipmi_interface_override(config, &resp[i], resp_len - i);
+       rc = parse_ipmi_interface_override(config, &resp[i], resp_len - i);
+
+       if (!rc && persistent) {
+               /* Write this new config to NVRAM */
+               update_network_config(platform, config);
+               rc = write_nvram(platform);
+               if (rc)
+                       pb_log("platform: Failed to save persistent interface override\n");
+       }
+}
+
+static void get_active_consoles(struct config *config)
+{
+       struct stat sbuf;
+       char *fsp_prop = NULL;
+
+       config->n_tty = 2;
+       config->tty_list = talloc_array(config, char *, config->n_tty);
+       if (!config->tty_list)
+               goto err;
+
+       config->tty_list[0] = talloc_asprintf(config->tty_list,
+                                       "/dev/hvc0 [IPMI / Serial]");
+       config->tty_list[1] = talloc_asprintf(config->tty_list,
+                                       "/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->tty_list = talloc_realloc(config, config->tty_list,
+                                               char *, config->n_tty + 1);
+               if (!config->tty_list)
+                       goto err;
+               config->tty_list[config->n_tty++] = talloc_asprintf(
+                                               config->tty_list,
+                                               "/dev/hvc1 [Serial]");
+       }
+
+       return;
+err:
+       config->n_tty = 0;
+       pb_log("Failed to allocate memory for tty_list\n");
 }
 
 static int load_config(struct platform *p, struct config *config)
@@ -1218,7 +1271,7 @@ static int load_config(struct platform *p, struct config *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)) {
@@ -1229,6 +1282,8 @@ static int load_config(struct platform *p, struct config *config)
        if (platform->ipmi)
                get_ipmi_network_override(platform, config);
 
+       get_active_consoles(config);
+
        return 0;
 }