X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fplatform-powerpc.c;h=46f81d201a403bec565bb735d728aa1e661fbcc1;hp=d45cced422917076e3743917a948fc6beefca170;hb=d974c3c39237c8e94bb3a51d3511d18dea01043e;hpb=5acb43464206348b7cced9508852fdd2989aea58 diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index d45cced..46f81d2 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -14,7 +14,9 @@ #include #include #include +#include +#include "hostboot.h" #include "platform.h" #include "ipmi.h" #include "dt.h" @@ -22,7 +24,7 @@ static const char *partition = "common"; static const char *sysparams_dir = "/sys/firmware/opal/sysparams/"; static const char *devtree_dir = "/proc/device-tree/"; -static const int ipmi_timeout = 500; /* milliseconds */ +static const int ipmi_timeout = 5000; /* milliseconds. */ struct param { char *name; @@ -43,6 +45,7 @@ struct platform_powerpc { bool persistent); int (*set_os_boot_sensor)( struct platform_powerpc *platform); + void (*get_platform_versions)(struct system_info *info); }; static const char *known_params[] = { @@ -179,7 +182,7 @@ static int write_nvram(struct platform_powerpc *platform) struct process *process; struct param *param; const char *argv[6]; - int rc; + int rc = 0; argv[0] = "nvram"; argv[1] = "--update-config"; @@ -310,7 +313,7 @@ static int parse_one_interface_config(struct config *config, } else if (!strcmp(tok, "static")) { ifconf->method = CONFIG_METHOD_STATIC; - /* ip/mask, [optional] gateway */ + /* ip/mask, [optional] gateway, [optional] url */ tok = strtok_r(NULL, ",", &saveptr); if (!tok) goto out_err; @@ -323,6 +326,12 @@ static int parse_one_interface_config(struct config *config, talloc_strdup(ifconf, tok); } + tok = strtok_r(NULL, ",", &saveptr); + if (tok) { + ifconf->static_config.url = + talloc_strdup(ifconf, tok); + } + } else { pb_log("Unknown network configuration method %s\n", tok); goto out_err; @@ -438,7 +447,6 @@ static void populate_bootdev_config(struct platform_powerpc *platform, { struct autoboot_option *opt, *new = NULL; char *pos, *end, *old_dev = NULL; - const char delim = ' '; unsigned int n_new = 0; const char *val; bool conflict; @@ -469,11 +477,9 @@ static void populate_bootdev_config(struct platform_powerpc *platform, if (read_bootdev(config, &pos, opt)) { pb_log("bootdev config is in an unknown format " - "(expected uuid:... or mac:...)"); + "(expected uuid:... or mac:...)\n"); talloc_free(opt); - if (strchr(pos, delim)) - continue; - return; + continue; } new = talloc_realloc(config, new, struct autoboot_option, @@ -578,10 +584,12 @@ static char *iface_config_str(void *ctx, struct interface_config *config) str = talloc_asprintf_append(str, "dhcp"); } else if (config->method == CONFIG_METHOD_STATIC) { - str = talloc_asprintf_append(str, "static,%s%s%s", + str = talloc_asprintf_append(str, "static,%s%s%s%s%s", config->static_config.address, config->static_config.gateway ? "," : "", - config->static_config.gateway ?: ""); + config->static_config.gateway ?: "", + config->static_config.url ? "," : "", + config->static_config.url ?: ""); } return str; } @@ -759,9 +767,8 @@ static int read_bootdev_sysparam(const char *name, uint8_t *val) char path[50]; int fd, rc; - strcpy(path, sysparams_dir); - assert(strlen(name) < sizeof(path) - strlen(path)); - strcat(path, name); + assert(strlen(sysparams_dir) + strlen(name) < sizeof(path)); + snprintf(path, sizeof(path), "%s%s", sysparams_dir, name); fd = open(path, O_RDONLY); if (fd < 0) { @@ -795,9 +802,8 @@ static int write_bootdev_sysparam(const char *name, uint8_t val) char path[50]; int fd, rc; - strcpy(path, sysparams_dir); - assert(strlen(name) < sizeof(path) - strlen(path)); - strcat(path, name); + assert(strlen(sysparams_dir) + strlen(name) < sizeof(path)); + snprintf(path, sizeof(path), "%s%s", sysparams_dir, name); fd = open(path, O_WRONLY); if (fd < 0) { @@ -920,6 +926,11 @@ static int get_ipmi_bootdev_ipmi(struct platform_powerpc *platform, return -1; } + pb_debug("IPMI get_bootdev response:\n"); + for (int i = 0; i < resp_len; i++) + pb_debug("%x ", resp[i]); + pb_debug("\n"); + if (resp[0] != 0) { pb_log("platform: non-zero completion code %d from IPMI req\n", resp[0]); @@ -989,6 +1000,31 @@ static int set_ipmi_os_boot_sensor(struct platform_powerpc *platform) return 0; } +static void get_ipmi_bmc_mac(struct platform *p, uint8_t *buf) +{ + struct platform_powerpc *platform = p->platform_data; + uint16_t resp_len = 8; + uint8_t resp[8]; + uint8_t req[] = { 0x1, 0x5, 0x0, 0x0 }; + int i, rc; + + rc = ipmi_transaction(platform->ipmi, IPMI_NETFN_TRANSPORT, + IPMI_CMD_TRANSPORT_GET_LAN_PARAMS, + req, sizeof(req), + resp, &resp_len, + ipmi_timeout); + + pb_debug("BMC MAC resp [%d][%d]:\n", rc, resp_len); + + if (rc == 0 && resp_len > 0) { + for (i = 2; i < resp_len; i++) { + pb_debug(" %x", resp[i]); + buf[i - 2] = resp[i]; + } + pb_debug("\n"); + } +} + static int load_config(struct platform *p, struct config *config) { struct platform_powerpc *platform = to_platform_powerpc(p); @@ -1057,6 +1093,13 @@ static int get_sysinfo(struct platform *p, struct system_info *sysinfo) sysinfo->identifier = talloc_steal(sysinfo, buf); talloc_free(filename); + sysinfo->bmc_mac = talloc_zero_size(sysinfo, HWADDR_SIZE); + if (platform->ipmi) + get_ipmi_bmc_mac(p, sysinfo->bmc_mac); + + if (platform->get_platform_versions) + platform->get_platform_versions(sysinfo); + return 0; } @@ -1085,7 +1128,6 @@ static bool probe(struct platform *p, void *ctx) platform->get_ipmi_bootdev = get_ipmi_bootdev_ipmi; platform->clear_ipmi_bootdev = clear_ipmi_bootdev_ipmi; platform->set_os_boot_sensor = set_ipmi_os_boot_sensor; - } else if (!stat(sysparams_dir, &statbuf)) { pb_debug("platform: using sysparams for IPMI paramters\n"); platform->get_ipmi_bootdev = get_ipmi_bootdev_sysparams; @@ -1095,6 +1137,10 @@ static bool probe(struct platform *p, void *ctx) pb_log("platform: no IPMI parameter support\n"); } + rc = stat("/proc/device-tree/bmc", &statbuf); + if (!rc) + platform->get_platform_versions = hostboot_load_versions; + return true; }