[PATCH v4 1/2] Platform: Add a platform file which is suitable for arm64 Platform.

Samuel Mendoza-Jonas sam at mendozajonas.com
Wed May 30 10:33:44 AEST 2018


On Sat, 2018-05-26 at 11:53 +0800, Ge Song wrote:
> On arm64 servers, plenty of devices(especially for those bootable devices)
> cannot be supported from efi firmware. In this situation, linux&petitboot
> is the wonderful way to address the issue.
> 
> Since efi is the primary firmware on arm64 servers, most of the management
> related works can be completed under that enviroment. Therefore some similar
> functions implemented in petitboot have been removed.
> 
> Signed-off-by: Ge Song <ge.song at hxt-semitech.com>
> ---
> Since V4:
> * Platform-arm64.c: Revise code to remove the warning complained by compiler.
>                     Adjust to v4 lib efi to set efivarfs path in probe();
> * Platform.c: Remove one redundant line in config_set_defaults()(exist in
>               master branch)
>  
>  discover/Makefile.am      |   3 +-
>  discover/platform-arm64.c | 746 ++++++++++++++++++++
>  discover/platform.c       |   1 -
>  3 files changed, 748 insertions(+), 2 deletions(-)
> 
> diff --git a/discover/Makefile.am b/discover/Makefile.am
> index ef4c6027d128..3681caac586b 100644
> --- a/discover/Makefile.am
> +++ b/discover/Makefile.am
> @@ -82,7 +82,8 @@ discover_platform_ro_SOURCES = \
>  	discover/dt.c \
>  	discover/dt.h \
>  	discover/hostboot.h \
> -	discover/platform-powerpc.c
> +	discover/platform-powerpc.c \
> +	discover/platform-arm64.c
>  
>  discover_platform_ro_CPPFLAGS = \
>  	$(AM_CPPFLAGS)
> diff --git a/discover/platform-arm64.c b/discover/platform-arm64.c
> new file mode 100644
> index 000000000000..24bf505fe2e3
> --- /dev/null
> +++ b/discover/platform-arm64.c
> @@ -0,0 +1,746 @@
> +/*
> + *  Defines an arm64 platform, based on the powerpc platform.
> + *
> + *  Actually, this is apply to platforms that adopt efi as its underlying
> + *  firmware(x86/x64/arm64).
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; version 2 of the License.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + *  Copyright (C) 2018 Huaxintong Semiconductor Technology Co.,Ltd. All rights
> + *  reserved.
> + *  Author: Ge Song <ge.song at hxt-semitech.com>
> + */
> +#include <errno.h>
> +#include <file/file.h>
> +#include <limits.h>
> +#include <list/list.h>
> +#include <log/log.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/fcntl.h>
> +#include <sys/statfs.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <types/types.h>
> +
> +#include "efi/efivar.h"
> +#include "ipmi.h"
> +#include "platform.h"
> +#include "talloc/talloc.h"
> +
> +#define DEF_ATTR	(EFI_VARIABLE_NON_VOLATILE | \
> +	EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)
> +static const char *pb_vars_guid = "fb78ab4b-bd43-41a0-99a2-4e74bef9169b";
> +static const int ipmi_timeout = 10000; /* milliseconds. */
> +
> +struct param {
> +	char *name;
> +	char *value;
> +	bool modified;
> +	struct list_item list;
> +};
> +
> +struct platform_arm64 {
> +	struct list params;
> +	struct ipmi *ipmi;
> +};
> +
> +static const char *known_params[] = {
> +	"auto-boot?",
> +	"network",
> +	"timeout",
> +	"bootdevs",
> +	"language",
> +	"debug?",
> +	"write?",
> +	"snapshots?",
> +	"console",
> +	"http_proxy",
> +	"https_proxy",
> +	NULL,
> +};

Along with what Geoff said, we may as well keep these parameter names the
same as found in platform-powerpc.c. Eg, "petitboot,snapshots?" rather
than just "snapshots?".

> +
> +static inline struct platform_arm64 *to_platform_arm64(struct platform *p)
> +{
> +	return (struct platform_arm64 *)(p->platform_data);
> +}
> +
> +static void parse_nvram(struct platform_arm64 *platform)
> +{
> +	int i, rc;
> +	size_t size;
> +	uint32_t attr;
> +	uint8_t *data;
> +	const char *pb_guid = pb_vars_guid;
> +	const char *known_param;
> +	struct param *param;
> +
> +	for (i = 0; known_params[i]; i++) {
> +		known_param = known_params[i];
> +		rc = efi_get_variable(platform, pb_guid, known_param,
> +				&data, &size, &attr);
> +		if (!rc) {
> +			param = talloc(platform, struct param);
> +			param->modified = false;
> +			param->name = talloc_strdup(platform, known_param);
> +			param->value = talloc_strdup(platform, (char *)data);
> +			list_add(&platform->params, &param->list);
> +		}
> +	}
> +}
> +
> +static void write_nvram(struct platform_arm64 *platform)
> +{
> +	struct param *param;
> +	const char *pb_guid = pb_vars_guid;
> +	uint32_t attr = DEF_ATTR;
> +	size_t data_size;
> +
> +	list_for_each_entry(&platform->params, param, list) {
> +		if (param->modified) {
> +			data_size = strlen(param->value) + 1;
> +			efi_set_variable(platform, pb_guid, param->name,
> +				(uint8_t *)param->value, data_size, attr);
> +		}
> +	}
> +}
> +
> +static const char *get_param(struct platform_arm64 *platform,
> +		const char *name)
> +{
> +	struct param *param;
> +
> +	list_for_each_entry(&platform->params, param, list)
> +		if (!strcmp(param->name, name))
> +			return param->value;
> +	return NULL;
> +}
> +
> +static void set_param(struct platform_arm64 *platform, const char *name,
> +		const char *value)
> +{
> +	struct param *param;
> +
> +	list_for_each_entry(&platform->params, param, list) {
> +		if (strcmp(param->name, name))
> +			continue;
> +
> +		if (!strcmp(param->value, value))
> +			return;
> +
> +		talloc_free(param->value);
> +		param->value = talloc_strdup(param, value);
> +		param->modified = true;
> +		return;
> +	}
> +
> +	param = talloc(platform, struct param);
> +	param->modified = true;
> +	param->name = talloc_strdup(platform, name);
> +	param->value = talloc_strdup(platform, value);
> +	list_add(&platform->params, &param->list);
> +}
> +
> +static int parse_hwaddr(struct interface_config *ifconf, char *str)
> +{
> +	int i;
> +
> +	if (strlen(str) != strlen("00:00:00:00:00:00"))
> +		return -1;
> +
> +	for (i = 0; i < HWADDR_SIZE; i++) {
> +		char byte[3], *endp;
> +		unsigned long x;
> +
> +		byte[0] = str[i * 3 + 0];
> +		byte[1] = str[i * 3 + 1];
> +		byte[2] = '\0';
> +
> +		x = strtoul(byte, &endp, 16);
> +		if (endp != byte + 2)
> +			return -1;
> +
> +		ifconf->hwaddr[i] = x & 0xff;
> +	}
> +
> +	return 0;
> +}
> +
> +static int parse_one_interface_config(struct config *config,
> +		char *confstr)
> +{
> +	struct interface_config *ifconf;
> +	char *tok, *saveptr;
> +
> +	ifconf = talloc_zero(config, struct interface_config);
> +
> +	if (!confstr || !strlen(confstr))
> +		goto out_err;
> +
> +	/* first token should be the mac address */
> +	tok = strtok_r(confstr, ",", &saveptr);
> +	if (!tok)
> +		goto out_err;
> +
> +	if (parse_hwaddr(ifconf, tok))
> +		goto out_err;
> +
> +	/* second token is the method */
> +	tok = strtok_r(NULL, ",", &saveptr);
> +	if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
> +		ifconf->ignore = true;
> +
> +	} else if (!strcmp(tok, "dhcp")) {
> +		ifconf->method = CONFIG_METHOD_DHCP;
> +
> +	} else if (!strcmp(tok, "static")) {
> +		ifconf->method = CONFIG_METHOD_STATIC;
> +
> +		/* ip/mask, [optional] gateway, [optional] url */
> +		tok = strtok_r(NULL, ",", &saveptr);
> +		if (!tok)
> +			goto out_err;
> +		ifconf->static_config.address =
> +			talloc_strdup(ifconf, tok);
> +
> +		tok = strtok_r(NULL, ",", &saveptr);
> +		if (tok) {
> +			ifconf->static_config.gateway =
> +				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;
> +	}
> +
> +	config->network.interfaces = talloc_realloc(config,
> +			config->network.interfaces,
> +			struct interface_config *,
> +			++config->network.n_interfaces);
> +
> +	config->network.interfaces[config->network.n_interfaces - 1] = ifconf;
> +
> +	return 0;
> +out_err:
> +	talloc_free(ifconf);
> +	return -1;
> +}
> +
> +static int parse_one_dns_config(struct config *config,
> +		char *confstr)
> +{
> +	char *tok, *saveptr = NULL;
> +
> +	for (tok = strtok_r(confstr, ",", &saveptr); tok;
> +			tok = strtok_r(NULL, ",", &saveptr)) {
> +
> +		char *server = talloc_strdup(config, tok);
> +
> +		config->network.dns_servers = talloc_realloc(config,
> +				config->network.dns_servers, const char *,
> +				++config->network.n_dns_servers);
> +
> +		config->network.dns_servers[config->network.n_dns_servers - 1]
> +				= server;
> +	}
> +
> +	return 0;
> +}
> +
> +static void populate_network_config(struct platform_arm64 *platform,
> +		struct config *config)
> +{
> +	char *val, *saveptr = NULL;
> +	const char *cval;
> +	int i;
> +
> +	cval = get_param(platform, "network");
> +	if (!cval || !strlen(cval))
> +		return;
> +
> +	val = talloc_strdup(config, cval);
> +
> +	for (i = 0; ; i++) {
> +		char *tok;
> +
> +		tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
> +		if (!tok)
> +			break;
> +
> +		if (!strncasecmp(tok, "dns,", strlen("dns,")))
> +			parse_one_dns_config(config, tok + strlen("dns,"));
> +		else
> +			parse_one_interface_config(config, tok);
> +
> +	}
> +
> +	talloc_free(val);
> +}
> +
> +static int read_bootdev(void *ctx, char **pos, struct autoboot_option *opt)
> +{
> +	char *delim = strchr(*pos, ' ');
> +	int len, prefix = 0, rc = -1;
> +	enum device_type type;
> +
> +	if (!strncmp(*pos, "uuid:", strlen("uuid:"))) {
> +		prefix = strlen("uuid:");
> +		opt->boot_type = BOOT_DEVICE_UUID;
> +	} else if (!strncmp(*pos, "mac:", strlen("mac:"))) {
> +		prefix = strlen("mac:");
> +		opt->boot_type = BOOT_DEVICE_UUID;
> +	} else {
> +		type = find_device_type(*pos);
> +		if (type != DEVICE_TYPE_UNKNOWN) {
> +			opt->type = type;
> +			opt->boot_type = BOOT_DEVICE_TYPE;
> +			rc = 0;
> +		}
> +	}
> +
> +	if (opt->boot_type == BOOT_DEVICE_UUID) {
> +		if (delim)
> +			len = (int)(delim - *pos) - prefix;
> +		else
> +			len = strlen(*pos) - prefix;
> +
> +		if (len) {
> +			opt->uuid = talloc_strndup(ctx, *pos + prefix, len);
> +			rc = 0;
> +		}
> +	}
> +
> +	/* Always advance pointer to next option or end */
> +	if (delim)
> +		*pos = delim + 1;
> +	else
> +		*pos += strlen(*pos);
> +
> +	return rc;
> +}
> +
> +static void populate_bootdev_config(struct platform_arm64 *platform,
> +		struct config *config)
> +{
> +	struct autoboot_option *opt, *new = NULL;
> +	char *pos, *end;
> +	unsigned int n_new = 0;
> +	const char *val;
> +
> +	/* Check for ordered bootdevs */
> +	val = get_param(platform, "bootdevs");
> +	if (!val || !strlen(val)) {
> +		pos = end = NULL;
> +	} else {
> +		pos = talloc_strdup(config, val);
> +		end = strchr(pos, '\0');
> +	}
> +
> +	while (pos && pos < end) {
> +		opt = talloc(config, struct autoboot_option);
> +
> +		if (read_bootdev(config, &pos, opt)) {
> +			pb_log("bootdev config is in an unknown format "
> +			       "(expected uuid:... or mac:...)\n");
> +			talloc_free(opt);
> +			continue;
> +		}
> +
> +		new = talloc_realloc(config, new, struct autoboot_option,
> +				     n_new + 1);
> +		new[n_new] = *opt;
> +		n_new++;
> +		talloc_free(opt);
> +
> +	}
> +
> +	if (!n_new) {
> +		/* If autoboot has been disabled, clear the default options */
> +		if (!config->autoboot_enabled) {
> +			talloc_free(config->autoboot_opts);
> +			config->n_autoboot_opts = 0;
> +		}
> +		return;
> +	}
> +
> +	talloc_free(config->autoboot_opts);
> +	config->autoboot_opts = new;
> +	config->n_autoboot_opts = n_new;
> +}
> +
> +static void populate_config(struct platform_arm64 *platform,
> +		struct config *config)
> +{
> +	const char *val;
> +	char *end;
> +	unsigned long timeout;
> +
> +	/* if the "auto-boot?' property is present and "false", disable auto
> +	 * boot */
> +	val = get_param(platform, "auto-boot?");
> +	config->autoboot_enabled = !val || strcmp(val, "false");
> +
> +	val = get_param(platform, "timeout");
> +	if (val) {
> +		timeout = strtoul(val, &end, 10);
> +		if (end != val) {
> +			if (timeout >= INT_MAX)
> +				timeout = INT_MAX;
> +			config->autoboot_timeout_sec = (int)timeout;
> +		}
> +	}
> +
> +	val = get_param(platform, "language");
> +	config->lang = val ? talloc_strdup(config, val) : NULL;
> +
> +	populate_network_config(platform, config);
> +
> +	populate_bootdev_config(platform, config);
> +
> +	if (!config->debug) {
> +		val = get_param(platform, "debug?");
> +		config->debug = val && !strcmp(val, "true");
> +	}
> +
> +	val = get_param(platform, "write?");
> +	if (val)
> +		config->allow_writes = !strcmp(val, "true");
> +
> +	val = get_param(platform, "snapshots?");
> +	if (val)
> +		config->disable_snapshots = !strcmp(val, "false");
> +
> +	val = get_param(platform, "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, "http_proxy");
> +	if (val)
> +		config->http_proxy = talloc_strdup(config, val);
> +	val = get_param(platform, "https_proxy");
> +	if (val)
> +		config->https_proxy = talloc_strdup(config, val);
> +}
> +
> +static char *iface_config_str(void *ctx, struct interface_config *config)
> +{
> +	char *str;
> +
> +	/* todo: HWADDR size is hardcoded as 6, but we may need to handle
> +	 * different hardware address formats */
> +	str = talloc_asprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x,",
> +			config->hwaddr[0], config->hwaddr[1],
> +			config->hwaddr[2], config->hwaddr[3],
> +			config->hwaddr[4], config->hwaddr[5]);
> +
> +	if (config->ignore) {
> +		str = talloc_asprintf_append(str, "ignore");
> +
> +	} else if (config->method == CONFIG_METHOD_DHCP) {
> +		str = talloc_asprintf_append(str, "dhcp");
> +
> +	} else if (config->method == CONFIG_METHOD_STATIC) {
> +		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.url ? "," : "",
> +				config->static_config.url ?: "");
> +	}
> +	return str;
> +}
> +
> +static char *dns_config_str(void *ctx, const char **dns_servers, int n)
> +{
> +	char *str;
> +	int i;
> +
> +	str = talloc_strdup(ctx, "dns,");
> +	for (i = 0; i < n; i++) {
> +		str = talloc_asprintf_append(str, "%s%s",
> +				i == 0 ? "" : ",",
> +				dns_servers[i]);
> +	}
> +
> +	return str;
> +}
> +
> +static void update_string_config(struct platform_arm64 *platform,
> +		const char *name, const char *value)
> +{
> +	const char *cur;
> +
> +	cur = get_param(platform, name);
> +
> +	/* don't set an empty parameter if it doesn't already exist */
> +	if (!cur && !strlen(value))
> +		return;
> +
> +	set_param(platform, name, value);
> +}
> +
> +static void update_network_config(struct platform_arm64 *platform,
> +	struct 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++) {
> +		char *iface_str = iface_config_str(platform,
> +					config->network.interfaces[i]);
> +		val = talloc_asprintf_append(val, "%s%s",
> +				*val == '\0' ? "" : " ", iface_str);
> +		talloc_free(iface_str);
> +	}
> +
> +	if (config->network.n_dns_servers) {
> +		char *dns_str = dns_config_str(platform,
> +						config->network.dns_servers,
> +						config->network.n_dns_servers);
> +		val = talloc_asprintf_append(val, "%s%s",
> +				*val == '\0' ? "" : " ", dns_str);
> +		talloc_free(dns_str);
> +	}
> +
> +	update_string_config(platform, "network", val);
> +
> +	talloc_free(val);
> +}
> +
> +static void update_bootdev_config(struct platform_arm64 *platform,
> +		struct config *config)
> +{
> +	char *val = NULL, *boot_str = NULL, *tmp = NULL;
> +	struct autoboot_option *opt;
> +	const char delim = ' ';
> +	unsigned int i;
> +
> +	if (!config->n_autoboot_opts)
> +		val = "";
> +
> +	for (i = 0; i < config->n_autoboot_opts; i++) {
> +		opt = &config->autoboot_opts[i];
> +		switch (opt->boot_type) {
> +			case BOOT_DEVICE_TYPE:
> +				boot_str = talloc_asprintf(config, "%s%c",
> +						device_type_name(opt->type),
> +						delim);
> +				break;
> +			case BOOT_DEVICE_UUID:
> +				boot_str = talloc_asprintf(config, "uuid:%s%c",
> +						opt->uuid, delim);
> +				break;
> +			}
> +			tmp = val = talloc_asprintf_append(val, "%s", boot_str);
> +	}
> +
> +	update_string_config(platform, "bootdevs", val);
> +	talloc_free(tmp);
> +	if (boot_str)
> +		talloc_free(boot_str);
> +}
> +
> +static void update_config(struct platform_arm64 *platform,
> +		struct config *config, struct config *defaults)
> +{
> +	char *tmp = NULL;
> +	const char *val;
> +
> +	if (config->autoboot_enabled == defaults->autoboot_enabled)
> +		val = "";
> +	else
> +		val = config->autoboot_enabled ? "true" : "false";
> +	update_string_config(platform, "auto-boot?", val);
> +
> +	if (config->autoboot_timeout_sec == defaults->autoboot_timeout_sec)
> +		val = "";
> +	else
> +		val = tmp = talloc_asprintf(platform, "%d",
> +				config->autoboot_timeout_sec);
> +
> +	update_string_config(platform, "timeout", val);
> +	if (tmp)
> +		talloc_free(tmp);
> +
> +	val = config->lang ?: "";
> +	update_string_config(platform, "language", val);
> +
> +	if (config->allow_writes == defaults->allow_writes)
> +		val = "";
> +	else
> +		val = config->allow_writes ? "true" : "false";
> +	update_string_config(platform, "write?", val);
> +
> +	if (!config->manual_console) {
> +		val = config->boot_console ?: "";
> +		update_string_config(platform, "console", val);
> +	}
> +
> +	val = config->http_proxy ?: "";
> +	update_string_config(platform, "http_proxy", val);
> +	val = config->https_proxy ?: "";
> +	update_string_config(platform, "https_proxy", val);
> +
> +	update_network_config(platform, config);
> +
> +	update_bootdev_config(platform, config);
> +
> +	write_nvram(platform);
> +}
> +
> +static void get_ipmi_bmc_mac(struct platform *p, uint8_t *buf)
> +{
> +	struct platform_arm64 *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 void get_active_consoles(struct config *config)
> +{
> +	config->n_consoles = 3;
> +	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/ttyAMA0 [Serial]");
> +	config->consoles[2] = talloc_asprintf(config->consoles,
> +					"/dev/tty1 [VGA]");
> +
> +	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_arm64 *platform = to_platform_arm64(p);
> +
> +	parse_nvram(platform);
> +
> +	populate_config(platform, config);
> +
> +	get_active_consoles(config);
> +
> +	return 0;
> +}
> +
> +static int save_config(struct platform *p, struct config *config)
> +{
> +	struct platform_arm64 *platform = to_platform_arm64(p);
> +	struct config *defaults;
> +
> +	defaults = talloc_zero(platform, struct config);
> +	config_set_defaults(defaults);
> +
> +	update_config(platform, config, defaults);
> +
> +	talloc_free(defaults);
> +
> +	return 0;
> +}
> +
> +static int get_sysinfo(struct platform *p, struct system_info *sysinfo)
> +{
> +	struct platform_arm64 *platform = p->platform_data;
> +
> +	sysinfo->bmc_mac = talloc_zero_size(sysinfo, HWADDR_SIZE);
> +
> +	if (platform->ipmi)
> +		get_ipmi_bmc_mac(p, sysinfo->bmc_mac);
> +
> +	return 0;
> +}
> +
> +static bool probe(struct platform *p, void *ctx)
> +{
> +	struct platform_arm64 *platform;
> +	const char *path = "/sys/firmware/efi/efivars/";
> +	int rc = 0;
> +	struct statfs buf;
> +
> +	if (access(path, F_OK))
> +		return false;
> +
> +	memset(&buf, '\0', sizeof(buf));
> +	rc = statfs(path, &buf);
> +	if (rc)
> +		return false;
> +
> +	typeof(buf.f_type) magic = EFIVARFS_MAGIC;
> +	if (!memcmp(&buf.f_type, &magic, sizeof (magic))) {
> +		platform = talloc_zero(ctx, struct platform_arm64);
> +		list_init(&platform->params);
> +		p->platform_data = platform;
> +
> +		set_efivarfs_path(path);
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +static struct platform platform_arm64 = {
> +	.name			= "arm64",
> +	.dhcp_arch_id		= 0x000d,
> +	.probe			= probe,
> +	.load_config		= load_config,
> +	.save_config		= save_config,
> +	.get_sysinfo		= get_sysinfo,
> +};
> +
> +register_platform(platform_arm64);
> diff --git a/discover/platform.c b/discover/platform.c
> index cc6306f035b9..bcf6b1141c7a 100644
> --- a/discover/platform.c
> +++ b/discover/platform.c
> @@ -121,7 +121,6 @@ void config_set_defaults(struct config *config)
>  
>  	config->autoboot_enabled = true;
>  	config->autoboot_timeout_sec = 10;
> -	config->autoboot_enabled = true;
>  	config->network.interfaces = NULL;
>  	config->network.n_interfaces = 0;
>  	config->network.dns_servers = NULL;



More information about the Petitboot mailing list