diff --git a/MAINTAINERS b/MAINTAINERS index 2d267aeff2..20092cb367 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1171,6 +1171,18 @@ F: common/lcd*.c F: include/lcd*.h F: include/video*.h +VirtIO +M: Bin Meng +S: Maintained +F: drivers/virtio/ +F: cmd/virtio.c +F: include/config/virtio/ +F: include/config/virtio.h +F: include/config/cmd/virtio.h +F: include/virtio*.h +F: test/dm/virtio.c +F: doc/develop/driver-model/virtio.rst + X86 M: Simon Glass M: Bin Meng diff --git a/Makefile b/Makefile index 404977efa5..77d55735a4 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION = 2021 PATCHLEVEL = 07 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = # *DOCUMENTATION* diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 85592f5bee..296e458db4 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -140,3 +140,14 @@ int arch_early_init_r(void) { return riscv_cpu_probe(); } + +/** + * harts_early_init() - A callback function called by start.S to configure + * feature settings of each hart. + * + * In a multi-core system, memory access shall be careful here, it shall + * take care of race conditions. + */ +__weak void harts_early_init(void) +{ +} diff --git a/arch/riscv/cpu/fu540/spl.c b/arch/riscv/cpu/fu540/spl.c index 45657b7909..1740ef98b6 100644 --- a/arch/riscv/cpu/fu540/spl.c +++ b/arch/riscv/cpu/fu540/spl.c @@ -6,6 +6,9 @@ #include #include +#include + +#define CSR_U74_FEATURE_DISABLE 0x7c1 int spl_soc_init(void) { @@ -21,3 +24,15 @@ int spl_soc_init(void) return 0; } + +void harts_early_init(void) +{ + /* + * Feature Disable CSR + * + * Clear feature disable CSR to '0' to turn on all features for + * each core. This operation must be in M-mode. + */ + if (CONFIG_IS_ENABLED(RISCV_MMODE)) + csr_write(CSR_U74_FEATURE_DISABLE, 0); +} diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 8589509e01..308b0a97a5 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -117,6 +117,10 @@ call_board_init_f_0: mv sp, a0 #endif + /* Configure proprietary settings and customized CSRs of harts */ +call_harts_early_init: + jal harts_early_init + #ifndef CONFIG_XIP /* * Pick hart to initialize global data and run U-Boot. The other harts diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 4fde923e9a..fe26ced31d 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -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>; diff --git a/cmd/gpt.c b/cmd/gpt.c index 76a95ade6c..17f2b839d7 100644 --- a/cmd/gpt.c +++ b/cmd/gpt.c @@ -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 \n" + " gpt read []\n" " - read GPT into a data structure for manipulation\n" + " - read GPT partitions into environment variable\n" " gpt swap \n" " - change all partitions named name1 to name2\n" " and vice-versa\n" diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c index 9687cec812..7a08061d12 100644 --- a/cmd/riscv/exception.c +++ b/cmd/riscv/exception.c @@ -8,6 +8,13 @@ #include #include +static int do_ebreak(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + asm volatile ("ebreak\n"); + return CMD_RET_FAILURE; +} + static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -28,6 +35,8 @@ static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc, } static struct cmd_tbl cmd_sub[] = { + U_BOOT_CMD_MKENT(ebreak, CONFIG_SYS_MAXARGS, 1, do_ebreak, + "", ""), U_BOOT_CMD_MKENT(unaligned, CONFIG_SYS_MAXARGS, 1, do_unaligned, "", ""), U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined, @@ -37,6 +46,7 @@ static struct cmd_tbl cmd_sub[] = { static char exception_help_text[] = "\n" " The following exceptions are available:\n" + " ebreak - breakpoint\n" " undefined - illegal instruction\n" " unaligned - load address misaligned\n" ; diff --git a/cmd/x86/cbsysinfo.c b/cmd/x86/cbsysinfo.c index a0db0ad364..34fdaf5b1b 100644 --- a/cmd/x86/cbsysinfo.c +++ b/cmd/x86/cbsysinfo.c @@ -205,7 +205,7 @@ static void show_table(struct sysinfo_t *info, bool verbose) print_hex(">type", ser->type); print_addr(">base", ser->baseaddr); print_dec(">baud", ser->baud); - print_hex(">baud", ser->regwidth); + print_hex(">regwidth", ser->regwidth); print_dec(">input_hz", ser->input_hertz); print_addr(">PCI addr", ser->uart_pci_addr); } diff --git a/common/board_r.c b/common/board_r.c index c835ff8e26..3f82404772 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -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)); diff --git a/common/fdt_support.c b/common/fdt_support.c index e624bbdf40..7eb5ba3bb2 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -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); diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 4288f571fc..caddf51196 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -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) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 8a7e519847..9a373bab6f 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -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 diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 00befc8b40..bdbf714e2b 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -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 diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 97ac46d21f..853c9440ea 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -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 diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 2e7b138558..c7fc98b556 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -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 diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index a71349432e..87223a54d8 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -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 diff --git a/doc/README.gpt b/doc/README.gpt index ac975f66b8..91e397d06f 100644 --- a/doc/README.gpt +++ b/doc/README.gpt @@ -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: ==================== diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst index fd4575db9b..10a76256b0 100644 --- a/doc/develop/driver-model/index.rst +++ b/doc/develop/driver-model/index.rst @@ -27,3 +27,4 @@ subsystems soc-framework spi-howto usb-info + virtio diff --git a/doc/README.virtio b/doc/develop/driver-model/virtio.rst similarity index 86% rename from doc/README.virtio rename to doc/develop/driver-model/virtio.rst index d3652f2e2f..8ac9c94caf 100644 --- a/doc/README.virtio +++ b/doc/develop/driver-model/virtio.rst @@ -1,11 +1,10 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright (C) 2018, Bin Meng +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Bin Meng VirtIO Support ============== -This document describes the information about U-Boot support for VirtIO [1] +This document describes the information about U-Boot support for VirtIO_ devices, including supported boards, build instructions, driver details etc. What's VirtIO? @@ -15,7 +14,7 @@ just the guest's device driver "knows" it is running in a virtual environment, and cooperates with the hypervisor. This enables guests to get high performance network and disk operations, and gives most of the performance benefits of paravirtualization. In the U-Boot case, the guest is U-Boot itself, while the -virtual environment are normally QEMU [2] targets like ARM, RISC-V and x86. +virtual environment are normally QEMU_ targets like ARM, RISC-V and x86. Status ------ @@ -49,6 +48,8 @@ Building U-Boot for pre-configured QEMU targets is no different from others. For example, we can do the following with the CROSS_COMPILE environment variable being properly set to a working toolchain for ARM: +.. code-block:: bash + $ make qemu_arm_defconfig $ make @@ -56,11 +57,13 @@ You can even create a QEMU ARM target with VirtIO devices showing up on both MMIO and PCI buses. In this case, you can enable the PCI transport driver from 'make menuconfig': -Device Drivers ---> - ... - VirtIO Drivers ---> - ... - [*] PCI driver for virtio devices +.. code-block:: none + + Device Drivers ---> + ... + VirtIO Drivers ---> + ... + [*] PCI driver for virtio devices Other drivers are at the same location and can be tuned to suit the needs. @@ -74,6 +77,8 @@ Testing The following QEMU command line is used to get U-Boot up and running with VirtIO net and block devices on ARM. +.. code-block:: bash + $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \ -netdev tap,ifname=tap0,id=net0 \ -device virtio-net-device,netdev=net0 \ @@ -82,6 +87,8 @@ VirtIO net and block devices on ARM. On x86, command is slightly different to create PCI VirtIO devices. +.. code-block:: bash + $ qemu-system-i386 -nographic -bios u-boot.rom \ -netdev tap,ifname=tap0,id=net0 \ -device virtio-net-pci,netdev=net0 \ @@ -93,6 +100,8 @@ parameters. It is also possible to specify both MMIO and PCI VirtIO devices. For example, the following commnad creates 3 VirtIO devices, with 1 on MMIO and 2 on PCI bus. +.. code-block:: bash + $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \ -netdev tap,ifname=tap0,id=net0 \ -device virtio-net-pci,netdev=net0 \ @@ -104,6 +113,8 @@ and 2 on PCI bus. By default QEMU creates VirtIO legacy devices by default. To create non-legacy (aka modern) devices, pass additional device property/value pairs like below: +.. code-block:: bash + $ qemu-system-i386 -nographic -bios u-boot.rom \ -netdev tap,ifname=tap0,id=net0 \ -device virtio-net-pci,netdev=net0,disable-legacy=true,disable-modern=false \ @@ -112,6 +123,8 @@ By default QEMU creates VirtIO legacy devices by default. To create non-legacy A 'virtio' command is provided in U-Boot shell. +.. code-block:: none + => virtio virtio - virtio block devices sub-system @@ -127,10 +140,14 @@ A 'virtio' command is provided in U-Boot shell. To probe all the VirtIO devices, type: +.. code-block:: none + => virtio scan Then we can show the connected block device details by: +.. code-block:: none + => virtio info Device 0: QEMU VirtIO Block Device Type: Hard Disk @@ -138,6 +155,8 @@ Then we can show the connected block device details by: And list the directories and files on the disk by: +.. code-block:: none + => ls virtio 0 / 4096 . 4096 .. @@ -167,6 +186,8 @@ Driver Internals ---------------- There are 3 level of drivers in the VirtIO driver family. +.. code-block:: none + +---------------------------------------+ | virtio device drivers | | +-------------+ +------------+ | @@ -199,20 +220,26 @@ The transport drivers provide a set of ops (struct dm_virtio_ops) for the real virtio device driver to call. These ops APIs's parameter is designed to remind the caller to pass the correct 'struct udevice' id of the virtio device, eg: -int virtio_get_status(struct udevice *vdev, u8 *status) +.. code-block:: C + + int virtio_get_status(struct udevice *vdev, u8 *status) So the parameter 'vdev' indicates the device should be the real virtio device. But we also have an API like: -struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num, - unsigned int vring_align, - struct udevice *udev) +.. code-block:: C + + struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num, + unsigned int vring_align, + struct udevice *udev) Here the parameter 'udev' indicates the device should be the transport device. Similar naming is applied in other functions that are even not APIs, eg: -static int virtio_uclass_post_probe(struct udevice *udev) -static int virtio_uclass_child_pre_probe(struct udevice *vdev) +.. code-block:: C + + static int virtio_uclass_post_probe(struct udevice *udev) + static int virtio_uclass_child_pre_probe(struct udevice *vdev) So it's easy to tell which device these functions are operating on. @@ -223,20 +250,29 @@ ID 2) are supported. If you want to develop new driver for new devices, please follow the guideline below. 1. add new device ID in virtio.h -#define VIRTIO_ID_XXX X + +.. code-block:: C + + #define VIRTIO_ID_XXX X 2. update VIRTIO_ID_MAX_NUM to be the largest device ID plus 1 3. add new driver name string in virtio.h -#define VIRTIO_XXX_DRV_NAME "virtio-xxx" + +.. code-block:: C + + #define VIRTIO_XXX_DRV_NAME "virtio-xxx" 4. create a new driver with name set to the name string above -U_BOOT_DRIVER(virtio_xxx) = { - .name = VIRTIO_XXX_DRV_NAME, - ... - .remove = virtio_reset, - .flags = DM_FLAG_ACTIVE_DMA, -} + +.. code-block:: C + + U_BOOT_DRIVER(virtio_xxx) = { + .name = VIRTIO_XXX_DRV_NAME, + ... + .remove = virtio_reset, + .flags = DM_FLAG_ACTIVE_DMA, + } Note the driver needs to provide the remove method and normally this can be hooked to virtio_reset(). The driver flags should contain DM_FLAG_ACTIVE_DMA @@ -247,7 +283,5 @@ for the remove method to be called before jumping to OS. 6. do funny stuff with the driver -References ----------- -[1] http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf -[2] https://www.qemu.org +.. _VirtIO: http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf +.. _QEMU: https://www.qemu.org diff --git a/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt b/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt new file mode 100644 index 0000000000..b5739d94e9 --- /dev/null +++ b/doc/device-tree-bindings/sysinfo/gpio-sysinfo.txt @@ -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"; +}; diff --git a/doc/usage/exception.rst b/doc/usage/exception.rst index db1490f005..27df88bd5c 100644 --- a/doc/usage/exception.rst +++ b/doc/usage/exception.rst @@ -31,6 +31,9 @@ type **RISC-V:** + ebreak + breakpoint exception + unaligned load address misaligned diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index e4e7f58c39..131099cc17 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -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); } diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c index 634cd56561..775b9ffc25 100644 --- a/drivers/spi/atcspi200_spi.c +++ b/drivers/spi/atcspi200_spi.c @@ -201,7 +201,7 @@ static int __atcspi200_spi_xfer(struct nds_spi_slave *ns, size_t cmd_len = ns->cmd_len; unsigned long data_len = bitlen / 8; int rf_cnt; - int ret = 0; + int ret = 0, timeout = 0; max_tran_len = ns->max_transfer_length; switch (flags) { @@ -243,11 +243,12 @@ static int __atcspi200_spi_xfer(struct nds_spi_slave *ns, ns->tran_len = tran_len; num_blks = DIV_ROUND_UP(tran_len , CHUNK_SIZE); num_bytes = (tran_len) % CHUNK_SIZE; + timeout = SPI_TIMEOUT; if(num_bytes == 0) num_bytes = CHUNK_SIZE; __atcspi200_spi_start(ns); - while (num_blks) { + while (num_blks && (timeout--)) { event = in_le32(&ns->regs->status); if ((event & TXEPTY) && (data_out)) { __nspi_espi_tx(ns, dout); @@ -269,6 +270,11 @@ static int __atcspi200_spi_xfer(struct nds_spi_slave *ns, din = (unsigned char *)din + rx_bytes; } } + + if (!timeout) { + debug("spi_xfer: %s() timeout\n", __func__); + break; + } } data_len -= tran_len; diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig index 85c1e81e41..381dcd8844 100644 --- a/drivers/sysinfo/Kconfig +++ b/drivers/sysinfo/Kconfig @@ -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 diff --git a/drivers/sysinfo/Makefile b/drivers/sysinfo/Makefile index 6d04fcba1d..d9f708b7ea 100644 --- a/drivers/sysinfo/Makefile +++ b/drivers/sysinfo/Makefile @@ -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 diff --git a/drivers/sysinfo/gazerbeam.h b/drivers/sysinfo/gazerbeam.h index 171729d203..6bf3c0098d 100644 --- a/drivers/sysinfo/gazerbeam.h +++ b/drivers/sysinfo/gazerbeam.h @@ -5,10 +5,12 @@ * */ +#include + enum { - BOARD_MULTICHANNEL, - BOARD_VARIANT, - BOARD_HWVERSION, + BOARD_HWVERSION = SYSINFO_ID_BOARD_MODEL, + BOARD_MULTICHANNEL = SYSINFO_ID_USER, + BOARD_VARIANT }; enum { diff --git a/drivers/sysinfo/gpio.c b/drivers/sysinfo/gpio.c new file mode 100644 index 0000000000..1d7f050998 --- /dev/null +++ b/drivers/sysinfo/gpio.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Sean Anderson + */ + +#include +#include +#include +#include +#include +#include + +/** + * 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, +}; diff --git a/drivers/sysinfo/sandbox.h b/drivers/sysinfo/sandbox.h index 2cff494f56..d9c5804c26 100644 --- a/drivers/sysinfo/sandbox.h +++ b/drivers/sysinfo/sandbox.h @@ -5,7 +5,7 @@ */ enum { - BOOL_CALLED_DETECT, + BOOL_CALLED_DETECT = SYSINFO_ID_USER, INT_TEST1, INT_TEST2, STR_VACATIONSPOT, diff --git a/drivers/sysinfo/sysinfo-uclass.c b/drivers/sysinfo/sysinfo-uclass.c index 6df58fe160..4a660dfd15 100644 --- a/drivers/sysinfo/sysinfo-uclass.c +++ b/drivers/sysinfo/sysinfo-uclass.c @@ -8,6 +8,10 @@ #include #include +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), }; diff --git a/env/Kconfig b/env/Kconfig index 1b7906cf72..1411f9e815 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -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 diff --git a/env/common.c b/env/common.c index 49bbb05eec..81e9e0b2aa 100644 --- a/env/common.c +++ b/env/common.c @@ -20,6 +20,7 @@ #include #include #include +#include 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 diff --git a/include/env.h b/include/env.h index b5731e4b9a..d5e2bcb530 100644 --- a/include/env.h +++ b/include/env.h @@ -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 diff --git a/include/env_default.h b/include/env_default.h index ea31a8eddf..1ddd64ba8f 100644 --- a/include/env_default.h +++ b/include/env_default.h @@ -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" diff --git a/include/fdt_support.h b/include/fdt_support.h index 46eb1dbbb2..e2a4689cd8 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -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 diff --git a/include/sysinfo.h b/include/sysinfo.h index 8054d4d4a1..b140d742e9 100644 --- a/include/sysinfo.h +++ b/include/sysinfo.h @@ -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); diff --git a/test/dm/Makefile b/test/dm/Makefile index e7cb1eec96..c9644617a1 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -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 diff --git a/test/dm/sysinfo-gpio.c b/test/dm/sysinfo-gpio.c new file mode 100644 index 0000000000..2e494b3f34 --- /dev/null +++ b/test/dm/sysinfo-gpio.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Sean Anderson + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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); diff --git a/test/dm/sysinfo.c b/test/dm/sysinfo.c index 4aaa9e85bc..96b3a8ebab 100644 --- a/test/dm/sysinfo.c +++ b/test/dm/sysinfo.c @@ -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; diff --git a/test/env/Makefile b/test/env/Makefile index 5c8eae31b0..9a98fd4796 100644 --- a/test/env/Makefile +++ b/test/env/Makefile @@ -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 diff --git a/test/env/fdt.c b/test/env/fdt.c new file mode 100644 index 0000000000..30bfa88c35 --- /dev/null +++ b/test/env/fdt.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +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);