Merge branch '2021-05-06-misc-updates'

- Allow for boards to update bootargs before booting the OS (helpful in
  some forms of secure boot).
- Enhance GPT write support.
- gpio-sysinfo updates
- Allow env to be appended from dtb
This commit is contained in:
Tom Rini 2021-05-06 11:00:07 -04:00
commit 1b8ad819ce
30 changed files with 516 additions and 36 deletions

View file

@ -53,6 +53,13 @@
osd0 = "/osd";
};
config {
environment {
from_fdt = "yes";
fdt_env_path = "";
};
};
audio: audio-codec {
compatible = "sandbox,audio-codec";
#sound-dai-cells = <1>;
@ -1526,6 +1533,13 @@
compatible = "sandbox,sysinfo-sandbox";
};
sysinfo-gpio {
compatible = "gpio-sysinfo";
gpios = <&gpio_a 15>, <&gpio_a 16>, <&gpio_a 17>;
revisions = <19>, <5>;
names = "rev_a", "foo";
};
some_regmapped-bus {
#address-cells = <0x1>;
#size-cells = <0x1>;

View file

@ -350,17 +350,46 @@ static int get_gpt_info(struct blk_desc *dev_desc)
}
/* a wrapper to test get_gpt_info */
static int do_get_gpt_info(struct blk_desc *dev_desc)
static int do_get_gpt_info(struct blk_desc *dev_desc, char * const namestr)
{
int ret;
int numparts;
ret = get_gpt_info(dev_desc);
if (ret > 0) {
print_gpt_info();
numparts = get_gpt_info(dev_desc);
if (numparts > 0) {
if (namestr) {
char disk_guid[UUID_STR_LEN + 1];
char *partitions_list;
int partlistlen;
int ret = -1;
ret = get_disk_guid(dev_desc, disk_guid);
if (ret < 0)
return ret;
partlistlen = calc_parts_list_len(numparts);
partitions_list = malloc(partlistlen);
if (!partitions_list) {
del_gpt_info();
return -ENOMEM;
}
memset(partitions_list, '\0', partlistlen);
ret = create_gpt_partitions_list(numparts, disk_guid,
partitions_list);
if (ret < 0)
printf("Error: Could not create partition list string!\n");
else
env_set(namestr, partitions_list);
free(partitions_list);
} else {
print_gpt_info();
}
del_gpt_info();
return 0;
}
return ret;
return numparts;
}
#endif
@ -982,7 +1011,7 @@ static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
ret = do_disk_guid(blk_dev_desc, argv[4]);
#ifdef CONFIG_CMD_GPT_RENAME
} else if (strcmp(argv[1], "read") == 0) {
ret = do_get_gpt_info(blk_dev_desc);
ret = do_get_gpt_info(blk_dev_desc, (argc == 5) ? argv[4] : NULL);
} else if ((strcmp(argv[1], "swap") == 0) ||
(strcmp(argv[1], "rename") == 0)) {
ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]);
@ -1028,8 +1057,9 @@ U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
" gpt guid mmc 0 varname\n"
#ifdef CONFIG_CMD_GPT_RENAME
"gpt partition renaming commands:\n"
" gpt read <interface> <dev>\n"
" gpt read <interface> <dev> [<varname>]\n"
" - read GPT into a data structure for manipulation\n"
" - read GPT partitions into environment variable\n"
" gpt swap <interface> <dev> <name1> <name2>\n"
" - change all partitions named name1 to name2\n"
" and vice-versa\n"

View file

@ -459,6 +459,8 @@ static int initr_env(void)
else
env_set_default(NULL, 0);
env_import_fdt();
if (IS_ENABLED(CONFIG_OF_CONTROL))
env_set_hex("fdtcontroladdr",
(unsigned long)map_to_sysmem(gd->fdt_blob));

View file

@ -269,6 +269,15 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
return 0;
}
/**
* board_fdt_chosen_bootargs - boards may override this function to use
* alternative kernel command line arguments
*/
__weak char *board_fdt_chosen_bootargs(void)
{
return env_get("bootargs");
}
int fdt_chosen(void *fdt)
{
int nodeoffset;
@ -286,7 +295,8 @@ int fdt_chosen(void *fdt)
if (nodeoffset < 0)
return nodeoffset;
str = env_get("bootargs");
str = board_fdt_chosen_bootargs();
if (str) {
err = fdt_setprop(fdt, nodeoffset, "bootargs", str,
strlen(str) + 1);

View file

@ -110,6 +110,10 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
* no string in the property for this index. Check if the
* sysinfo-level code can supply one.
*/
rc = sysinfo_detect(sysinfo);
if (rc)
return rc;
rc = sysinfo_get_fit_loadable(sysinfo, index - i - 1, type,
&str);
if (rc && rc != -ENOENT)

View file

@ -91,6 +91,7 @@ CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_EXT4=y
CONFIG_ENV_EXT4_INTERFACE="host"
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
CONFIG_ENV_IMPORT_FDT=y
CONFIG_BOOTP_SEND_HOSTNAME=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
@ -204,6 +205,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SANDBOX=y
CONFIG_SYSINFO_GPIO=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
CONFIG_TIMER_EARLY=y

View file

@ -106,6 +106,7 @@ CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_EXT4=y
CONFIG_ENV_EXT4_INTERFACE="host"
CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
CONFIG_ENV_IMPORT_FDT=y
CONFIG_BOOTP_SEND_HOSTNAME=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
@ -245,6 +246,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SANDBOX=y
CONFIG_SYSINFO_GPIO=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
CONFIG_TIMER_EARLY=y

View file

@ -178,6 +178,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SANDBOX=y
CONFIG_SYSINFO_GPIO=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
CONFIG_TIMER_EARLY=y

View file

@ -197,6 +197,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SANDBOX=y
CONFIG_SYSINFO_GPIO=y
CONFIG_SYSRESET=y
CONFIG_SPL_SYSRESET=y
CONFIG_TIMER=y

View file

@ -199,6 +199,7 @@ CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SANDBOX=y
CONFIG_SYSINFO_GPIO=y
CONFIG_SYSRESET=y
CONFIG_SPL_SYSRESET=y
CONFIG_TIMER=y

View file

@ -237,6 +237,23 @@ doc/arch/index.rst:
=> gpt swap host 0 name othername
[ . . . ]
Modifying GPT partition layout from U-Boot:
===========================================
The entire GPT partition layout can be exported to an environment
variable and then modified enmasse. Users can change the partition
numbers, offsets, names and sizes. The resulting variable can used to
reformat the device. Here is an example of reading the GPT partitions
into a variable and then modifying them:
U-BOOT> gpt read mmc 0 current_partitions
U-BOOT> env edit current_partitions
edit: uuid_disk=[...];name=part1,start=0x4000,size=0x4000,uuid=[...];
name=part2,start=0xc000,size=0xc000,uuid=[...];[ . . . ]
U-BOOT> gpt write mmc 0 $current_partitions
U-BOOT> gpt verify mmc 0 $current_partitions
Partition type GUID:
====================

View file

@ -0,0 +1,37 @@
GPIO-based Sysinfo device
This binding describes several GPIOs which specify a board revision. Each GPIO
forms a digit in a ternary revision number. This revision is then mapped to a
name using the revisions and names properties.
Each GPIO may be floating, pulled-up, or pulled-down, mapping to digits 2, 1,
and 0, respectively. The first GPIO forms the least-significant digit of the
revision. For example, consider the property
gpios = <&gpio 0>, <&gpio 1>, <&gpio 2>;
If GPIO 0 is pulled-up, GPIO 1 is pulled-down, and GPIO 2 is floating, then the
revision would be
0t201 = 2*9 + 0*3 + 1*3 = 19
If instead GPIO 0 is floating, GPIO 1 is pulled-up, and GPIO 2 is pulled-down,
then the revision would be
0t012 = 0*9 + 1*3 + 2*1 = 5
Required properties:
- compatible: should be "gpio-sysinfo".
- gpios: should be a list of gpios forming the revision number,
least-significant-digit first
- revisions: a list of known revisions; any revisions not present will have the
name "unknown"
- names: the name of each revision in revisions
Example:
sysinfo {
compatible = "gpio-sysinfo";
gpios = <&gpio_a 15>, <&gpio_a 16>, <&gpio_a 17>;
revisions = <19>, <5>;
names = "rev_a", "foo";
};

View file

@ -1215,9 +1215,9 @@ int gpio_get_list_count(struct udevice *dev, const char *list_name)
{
int ret;
ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0, -1,
NULL);
if (ret) {
ret = dev_count_phandle_with_args(dev, list_name, "#gpio-cells",
-ENOENT);
if (ret < 0) {
debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
__func__, dev->name, list_name, ret);
}

View file

@ -30,4 +30,12 @@ config SYSINFO_SMBIOS
one which provides a way to specify this SMBIOS information in the
devicetree, without needing any board-specific functionality.
config SYSINFO_GPIO
bool "Enable gpio sysinfo driver"
help
Support querying gpios to determine board revision. This uses gpios to
form a ternary number (when they are pulled-up, -down, or floating).
This ternary number is then mapped to a board revision name using
device tree properties.
endif

View file

@ -4,5 +4,6 @@
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
obj-y += sysinfo-uclass.o
obj-$(CONFIG_SYSINFO_GAZERBEAM) += gazerbeam.o
obj-$(CONFIG_SYSINFO_GPIO) += gpio.o
obj-$(CONFIG_SYSINFO_SANDBOX) += sandbox.o
obj-$(CONFIG_SYSINFO_SMBIOS) += smbios.o

View file

@ -5,10 +5,12 @@
*
*/
#include <sysinfo.h>
enum {
BOARD_MULTICHANNEL,
BOARD_VARIANT,
BOARD_HWVERSION,
BOARD_HWVERSION = SYSINFO_ID_BOARD_MODEL,
BOARD_MULTICHANNEL = SYSINFO_ID_USER,
BOARD_VARIANT
};
enum {

141
drivers/sysinfo/gpio.c Normal file
View file

@ -0,0 +1,141 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2021 Sean Anderson <sean.anderson@seco.com>
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <sysinfo.h>
#include <asm/gpio.h>
#include <dm/device_compat.h>
/**
* struct sysinfo_gpio_priv - GPIO sysinfo private data
* @gpios: List of GPIOs used to detect the revision
* @gpio_num: The number of GPIOs in @gpios
* @revision: The revision as detected from the GPIOs.
*/
struct sysinfo_gpio_priv {
struct gpio_desc *gpios;
int gpio_num, revision;
};
static int sysinfo_gpio_detect(struct udevice *dev)
{
int ret;
struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
ret = dm_gpio_get_values_as_int_base3(priv->gpios, priv->gpio_num);
if (ret < 0)
return ret;
priv->revision = ret;
return 0;
}
static int sysinfo_gpio_get_int(struct udevice *dev, int id, int *val)
{
struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
switch (id) {
case SYSINFO_ID_BOARD_MODEL:
*val = priv->revision;
return 0;
default:
return -EINVAL;
};
}
static int sysinfo_gpio_get_str(struct udevice *dev, int id, size_t size, char *val)
{
struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
switch (id) {
case SYSINFO_ID_BOARD_MODEL: {
const char *name = NULL;
int i, ret;
u32 revision;
for (i = 0; i < priv->gpio_num; i++) {
ret = dev_read_u32_index(dev, "revisions", i,
&revision);
if (ret) {
if (ret != -EOVERFLOW)
return ret;
break;
}
if (revision == priv->revision) {
ret = dev_read_string_index(dev, "names", i,
&name);
if (ret < 0)
return ret;
break;
}
}
if (!name)
name = "unknown";
strncpy(val, name, size);
val[size - 1] = '\0';
return 0;
} default:
return -EINVAL;
};
}
static const struct sysinfo_ops sysinfo_gpio_ops = {
.detect = sysinfo_gpio_detect,
.get_int = sysinfo_gpio_get_int,
.get_str = sysinfo_gpio_get_str,
};
static int sysinfo_gpio_probe(struct udevice *dev)
{
int ret;
struct sysinfo_gpio_priv *priv = dev_get_priv(dev);
priv->gpio_num = gpio_get_list_count(dev, "gpios");
if (priv->gpio_num < 0) {
dev_err(dev, "could not get gpios length (err = %d)\n",
priv->gpio_num);
return priv->gpio_num;
}
priv->gpios = calloc(priv->gpio_num, sizeof(*priv->gpios));
if (!priv->gpios) {
dev_err(dev, "could not allocate memory for %d gpios\n",
priv->gpio_num);
return -ENOMEM;
}
ret = gpio_request_list_by_name(dev, "gpios", priv->gpios,
priv->gpio_num, GPIOD_IS_IN);
if (ret != priv->gpio_num) {
dev_err(dev, "could not get gpios (err = %d)\n",
priv->gpio_num);
return ret;
}
if (!dev_read_bool(dev, "revisions") || !dev_read_bool(dev, "names")) {
dev_err(dev, "revisions or names properties missing\n");
return -ENOENT;
}
return 0;
}
static const struct udevice_id sysinfo_gpio_ids[] = {
{ .compatible = "gpio-sysinfo" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(sysinfo_gpio) = {
.name = "sysinfo_gpio",
.id = UCLASS_SYSINFO,
.of_match = sysinfo_gpio_ids,
.ops = &sysinfo_gpio_ops,
.priv_auto = sizeof(struct sysinfo_gpio_priv),
.probe = sysinfo_gpio_probe,
};

View file

@ -5,7 +5,7 @@
*/
enum {
BOOL_CALLED_DETECT,
BOOL_CALLED_DETECT = SYSINFO_ID_USER,
INT_TEST1,
INT_TEST2,
STR_VACATIONSPOT,

View file

@ -8,6 +8,10 @@
#include <dm.h>
#include <sysinfo.h>
struct sysinfo_priv {
bool detected;
};
int sysinfo_get(struct udevice **devp)
{
return uclass_first_device_err(UCLASS_SYSINFO, devp);
@ -15,19 +19,29 @@ int sysinfo_get(struct udevice **devp)
int sysinfo_detect(struct udevice *dev)
{
int ret;
struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
struct sysinfo_ops *ops = sysinfo_get_ops(dev);
if (!ops->detect)
return -ENOSYS;
return ops->detect(dev);
ret = ops->detect(dev);
if (!ret)
priv->detected = true;
return ret;
}
int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
const char **strp)
{
struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
struct sysinfo_ops *ops = sysinfo_get_ops(dev);
if (!priv->detected)
return -EPERM;
if (!ops->get_fit_loadable)
return -ENOSYS;
@ -36,8 +50,12 @@ int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
{
struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
struct sysinfo_ops *ops = sysinfo_get_ops(dev);
if (!priv->detected)
return -EPERM;
if (!ops->get_bool)
return -ENOSYS;
@ -46,8 +64,12 @@ int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
int sysinfo_get_int(struct udevice *dev, int id, int *val)
{
struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
struct sysinfo_ops *ops = sysinfo_get_ops(dev);
if (!priv->detected)
return -EPERM;
if (!ops->get_int)
return -ENOSYS;
@ -56,8 +78,12 @@ int sysinfo_get_int(struct udevice *dev, int id, int *val)
int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val)
{
struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
struct sysinfo_ops *ops = sysinfo_get_ops(dev);
if (!priv->detected)
return -EPERM;
if (!ops->get_str)
return -ENOSYS;
@ -68,4 +94,5 @@ UCLASS_DRIVER(sysinfo) = {
.id = UCLASS_SYSINFO,
.name = "sysinfo",
.post_bind = dm_scan_fdt_dev,
.per_device_auto = sizeof(bool),
};

18
env/Kconfig vendored
View file

@ -670,6 +670,24 @@ config DELAY_ENVIRONMENT
later by U-Boot code. With CONFIG_OF_CONTROL this is instead
controlled by the value of /config/load-environment.
config ENV_IMPORT_FDT
bool "Amend environment by FDT properties"
depends on OF_CONTROL
help
If selected, after the environment has been loaded from its
persistent location, the "env_fdt_path" variable is looked
up and used as a path to a node in the control DTB. The
property/value pairs in that node is then used to update the
run-time environment. This can be useful to use the same
U-Boot binary with different board variants.
config ENV_FDT_PATH
string "Default value for env_fdt_path variable"
depends on ENV_IMPORT_FDT
default "/config/environment"
help
The initial value of the env_fdt_path variable.
config ENV_APPEND
bool "Always append the environment with new data"
default n

30
env/common.c vendored
View file

@ -20,6 +20,7 @@
#include <errno.h>
#include <malloc.h>
#include <u-boot/crc.h>
#include <dm/ofnode.h>
DECLARE_GLOBAL_DATA_PTR;
@ -334,3 +335,32 @@ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf,
return found;
}
#endif
#ifdef CONFIG_ENV_IMPORT_FDT
void env_import_fdt(void)
{
const char *path;
struct ofprop prop;
ofnode node;
int res;
path = env_get("env_fdt_path");
if (!path || !path[0])
return;
node = ofnode_path(path);
if (!ofnode_valid(node)) {
printf("Warning: device tree node '%s' not found\n", path);
return;
}
for (res = ofnode_get_first_property(node, &prop);
!res;
res = ofnode_get_next_property(&prop)) {
const char *name, *val;
val = ofnode_get_property_by_prop(&prop, &name, NULL);
env_set(name, val);
}
}
#endif

View file

@ -375,4 +375,19 @@ int env_get_char(int index);
* This is used for those unfortunate archs with crappy toolchains
*/
void env_reloc(void);
/**
* env_import_fdt() - Import environment values from device tree blob
*
* This uses the value of the environment variable "env_fdt_path" as a
* path to an fdt node, whose property/value pairs are added to the
* environment.
*/
#ifdef CONFIG_ENV_IMPORT_FDT
void env_import_fdt(void);
#else
static inline void env_import_fdt(void) {}
#endif
#endif

View file

@ -103,6 +103,9 @@ const uchar default_environment[] = {
#ifdef CONFIG_SYS_SOC
"soc=" CONFIG_SYS_SOC "\0"
#endif
#ifdef CONFIG_ENV_IMPORT_FDT
"env_fdt_path=" CONFIG_ENV_FDT_PATH "\0"
#endif
#endif
#if defined(CONFIG_BOOTCOUNT_BOOTLIMIT) && (CONFIG_BOOTCOUNT_BOOTLIMIT > 0)
"bootlimit=" __stringify(CONFIG_BOOTCOUNT_BOOTLIMIT)"\0"

View file

@ -185,6 +185,16 @@ int fdt_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
*/
int ft_board_setup(void *blob, struct bd_info *bd);
/**
* board_fdt_chosen_bootargs() - Arbitrarily amend fdt kernel command line
*
* This is used for late modification of kernel command line arguments just
* before they are added into the /chosen node in flat device tree.
*
* @return: pointer to kernel command line arguments in memory
*/
char *board_fdt_chosen_bootargs(void);
/*
* The keystone2 SOC requires all 32 bit aliased addresses to be converted
* to their 36 physical format. This has to happen after all fdt nodes

View file

@ -60,7 +60,8 @@ struct sysinfo_ops {
* This operation might take a long time (e.g. read from EEPROM,
* check the presence of a device on a bus etc.), hence this is not
* done in the probe() method, but later during operation in this
* dedicated method.
* dedicated method. This method will be called before any other
* methods.
*
* Return: 0 if OK, -ve on error.
*/
@ -104,7 +105,7 @@ struct sysinfo_ops {
* get_fit_loadable - Get the name of an image to load from FIT
* This function can be used to provide the image names based on runtime
* detection. A classic use-case would when DTBOs are used to describe
* additionnal daughter cards.
* additional daughter cards.
*
* @dev: The sysinfo instance to gather the data.
* @index: Index of the image. Starts at 0 and gets incremented
@ -127,6 +128,9 @@ struct sysinfo_ops {
*
* @dev: The device containing the information
*
* This function must be called before any other accessor function for this
* device.
*
* Return: 0 if OK, -ve on error.
*/
int sysinfo_detect(struct udevice *dev);
@ -138,7 +142,8 @@ int sysinfo_detect(struct udevice *dev);
* @id: A unique identifier for the bool value to be read.
* @val: Pointer to a buffer that receives the value read.
*
* Return: 0 if OK, -ve on error.
* Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
* error.
*/
int sysinfo_get_bool(struct udevice *dev, int id, bool *val);
@ -149,7 +154,8 @@ int sysinfo_get_bool(struct udevice *dev, int id, bool *val);
* @id: A unique identifier for the int value to be read.
* @val: Pointer to a buffer that receives the value read.
*
* Return: 0 if OK, -ve on error.
* Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
* error.
*/
int sysinfo_get_int(struct udevice *dev, int id, int *val);
@ -161,7 +167,8 @@ int sysinfo_get_int(struct udevice *dev, int id, int *val);
* @size: The size of the buffer to receive the string data.
* @val: Pointer to a buffer that receives the value read.
*
* Return: 0 if OK, -ve on error.
* Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
* error.
*/
int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val);
@ -173,7 +180,8 @@ int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val);
* function that returns the unique device. This is especially useful for use
* in sysinfo files.
*
* Return: 0 if OK, -ve on error.
* Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
* error.
*/
int sysinfo_get(struct udevice **devp);
@ -181,7 +189,7 @@ int sysinfo_get(struct udevice **devp);
* sysinfo_get_fit_loadable - Get the name of an image to load from FIT
* This function can be used to provide the image names based on runtime
* detection. A classic use-case would when DTBOs are used to describe
* additionnal daughter cards.
* additional daughter cards.
*
* @dev: The sysinfo instance to gather the data.
* @index: Index of the image. Starts at 0 and gets incremented
@ -190,8 +198,8 @@ int sysinfo_get(struct udevice **devp);
* @strp: A pointer to string. Untouched if the function fails
*
*
* Return: 0 if OK, -ENOENT if no loadable is available else -ve on
* error.
* Return: 0 if OK, -EPERM if called before sysinfo_detect(), -ENOENT if no
* loadable is available else -ve on error.
*/
int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
const char **strp);

View file

@ -96,6 +96,7 @@ obj-$(CONFIG_SPMI) += spmi.o
obj-y += syscon.o
obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o
obj-$(CONFIG_SYSINFO) += sysinfo.o
obj-$(CONFIG_SYSINFO_GPIO) += sysinfo-gpio.o
obj-$(CONFIG_TEE) += tee.o
obj-$(CONFIG_TIMER) += timer.o
obj-$(CONFIG_DM_USB) += usb.o

69
test/dm/sysinfo-gpio.c Normal file
View file

@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2021 Sean Anderson <sean.anderson@seco.com>
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <sysinfo.h>
#include <asm/gpio.h>
#include <dm/test.h>
#include <test/test.h>
#include <test/ut.h>
static int dm_test_sysinfo_gpio(struct unit_test_state *uts)
{
char buf[64];
int val;
struct udevice *sysinfo, *gpio;
ut_assertok(uclass_get_device_by_name(UCLASS_SYSINFO, "sysinfo-gpio",
&sysinfo));
ut_assertok(uclass_get_device_by_name(UCLASS_GPIO, "base-gpios", &gpio));
/*
* Set up pins: pull-up (1), pull-down (0) and floating (2). This should
* result in digits 2 0 1, i.e. 2 * 9 + 1 * 3 = 19
*/
sandbox_gpio_set_flags(gpio, 15, GPIOD_EXT_PULL_UP);
sandbox_gpio_set_flags(gpio, 16, GPIOD_EXT_PULL_DOWN);
sandbox_gpio_set_flags(gpio, 17, 0);
ut_assertok(sysinfo_detect(sysinfo));
ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
ut_asserteq(19, val);
ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
buf));
ut_asserteq_str("rev_a", buf);
/*
* Set up pins: floating (2), pull-up (1) and pull-down (0). This should
* result in digits 0 1 2, i.e. 1 * 3 + 2 = 5
*/
sandbox_gpio_set_flags(gpio, 15, 0);
sandbox_gpio_set_flags(gpio, 16, GPIOD_EXT_PULL_UP);
sandbox_gpio_set_flags(gpio, 17, GPIOD_EXT_PULL_DOWN);
ut_assertok(sysinfo_detect(sysinfo));
ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
ut_asserteq(5, val);
ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
buf));
ut_asserteq_str("foo", buf);
/*
* Set up pins: floating (2), pull-up (1) and pull-down (0). This should
* result in digits 1 2 0, i.e. 1 * 9 + 2 * 3 = 15
*/
sandbox_gpio_set_flags(gpio, 15, GPIOD_EXT_PULL_DOWN);
sandbox_gpio_set_flags(gpio, 16, 0);
sandbox_gpio_set_flags(gpio, 17, GPIOD_EXT_PULL_UP);
ut_assertok(sysinfo_detect(sysinfo));
ut_assertok(sysinfo_get_int(sysinfo, SYSINFO_ID_BOARD_MODEL, &val));
ut_asserteq(15, val);
ut_assertok(sysinfo_get_str(sysinfo, SYSINFO_ID_BOARD_MODEL, sizeof(buf),
buf));
ut_asserteq_str("unknown", buf);
return 0;
}
DM_TEST(dm_test_sysinfo_gpio, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

View file

@ -17,40 +17,45 @@
static int dm_test_sysinfo(struct unit_test_state *uts)
{
struct udevice *sysinfo;
bool called_detect;
bool called_detect = false;
char str[64];
int i;
ut_assertok(sysinfo_get(&sysinfo));
ut_assert(sysinfo);
sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT, &called_detect);
ut_asserteq(-EPERM, sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT,
&called_detect));
ut_assert(!called_detect);
sysinfo_detect(sysinfo);
sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT, &called_detect);
ut_assertok(sysinfo_get_bool(sysinfo, BOOL_CALLED_DETECT,
&called_detect));
ut_assert(called_detect);
sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
str));
ut_assertok(strcmp(str, "R'lyeh"));
sysinfo_get_int(sysinfo, INT_TEST1, &i);
ut_assertok(sysinfo_get_int(sysinfo, INT_TEST1, &i));
ut_asserteq(0, i);
sysinfo_get_int(sysinfo, INT_TEST2, &i);
ut_assertok(sysinfo_get_int(sysinfo, INT_TEST2, &i));
ut_asserteq(100, i);
sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
str));
ut_assertok(strcmp(str, "Carcosa"));
sysinfo_get_int(sysinfo, INT_TEST1, &i);
ut_assertok(sysinfo_get_int(sysinfo, INT_TEST1, &i));
ut_asserteq(1, i);
sysinfo_get_int(sysinfo, INT_TEST2, &i);
ut_assertok(sysinfo_get_int(sysinfo, INT_TEST2, &i));
ut_asserteq(99, i);
sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str), str);
ut_assertok(sysinfo_get_str(sysinfo, STR_VACATIONSPOT, sizeof(str),
str));
ut_assertok(strcmp(str, "Yuggoth"));
return 0;

1
test/env/Makefile vendored
View file

@ -5,3 +5,4 @@
obj-y += cmd_ut_env.o
obj-y += attr.o
obj-y += hashtable.o
obj-$(CONFIG_ENV_IMPORT_FDT) += fdt.o

20
test/env/fdt.c vendored Normal file
View file

@ -0,0 +1,20 @@
#include <common.h>
#include <command.h>
#include <env_attr.h>
#include <test/env.h>
#include <test/ut.h>
static int env_test_fdt_import(struct unit_test_state *uts)
{
const char *val;
val = env_get("from_fdt");
ut_assertnonnull(val);
ut_asserteq_str("yes", val);
val = env_get("fdt_env_path");
ut_assertnull(val);
return 0;
}
ENV_TEST(env_test_fdt_import, 0);