summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-10-06 13:59:01 -0400
committerTom Rini <trini@konsulko.com>2020-10-06 13:59:01 -0400
commit42378e3cd2432e0353cdcc1789039293e4b46252 (patch)
tree0d7f41a9e50432c32aca3cd7e611cfea70f9efc4
parent5dcf7cc590b348f1e730ec38242df64c179f10a8 (diff)
parent175e8322bcee64127a24acdac12c54f5ddb95f82 (diff)
downloadu-boot-WIP/06Oct2020.tar.gz
Merge tag 'dm-pull-6oct20' of git://git.denx.de/u-boot-dmWIP/06Oct2020
bloblist enhancement for alignment Update ofnode/dev_read phandle function sandbox keyboard enhancements and fixes
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/sandbox/cpu/sdl.c156
-rw-r--r--arch/sandbox/dts/cros-ec-keyboard.dtsi20
-rw-r--r--arch/sandbox/dts/test.dts1
-rw-r--r--arch/x86/cpu/intel_common/acpi.c2
-rw-r--r--arch/x86/cpu/intel_common/intel_opregion.c2
-rw-r--r--board/st/stm32mp1/stm32mp1.c2
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bloblist.c37
-rw-r--r--common/bloblist.c120
-rw-r--r--doc/arch/sandbox.rst57
-rw-r--r--drivers/clk/clk-uclass.c4
-rw-r--r--drivers/core/of_access.c7
-rw-r--r--drivers/core/ofnode.c6
-rw-r--r--drivers/core/read.c5
-rw-r--r--drivers/net/designware.c3
-rw-r--r--drivers/phy/phy-uclass.c2
-rw-r--r--drivers/power/domain/power-domain-uclass.c2
-rw-r--r--drivers/reset/reset-uclass.c3
-rw-r--r--drivers/usb/host/ehci-generic.c4
-rw-r--r--drivers/usb/host/ohci-da8xx.c3
-rw-r--r--drivers/usb/host/ohci-generic.c6
-rw-r--r--include/bloblist.h42
-rw-r--r--include/dm/of_access.h4
-rw-r--r--include/dm/ofnode.h12
-rw-r--r--include/dm/read.h8
-rw-r--r--include/test/ut.h13
-rw-r--r--lib/fdtdec.c2
-rw-r--r--test/bloblist.c148
-rw-r--r--test/dm/ofnode.c91
-rw-r--r--test/dm/test-fdt.c65
32 files changed, 673 insertions, 165 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 85babd1908..ed5e354873 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -959,6 +959,7 @@ SANDBOX
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: arch/sandbox/
+F: doc/arch/sandbox.rst
SH
M: Marek Vasut <marek.vasut+renesas@gmail.com>
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index 6416cab96c..7dc3dab32e 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -172,33 +172,7 @@ int sandbox_sdl_sync(void *lcd_base)
}
static const unsigned short sdl_to_keycode[SDL_NUM_SCANCODES] = {
- [SDL_SCANCODE_A] = KEY_A,
- [SDL_SCANCODE_B] = KEY_B,
- [SDL_SCANCODE_C] = KEY_C,
- [SDL_SCANCODE_D] = KEY_D,
- [SDL_SCANCODE_E] = KEY_E,
- [SDL_SCANCODE_F] = KEY_F,
- [SDL_SCANCODE_G] = KEY_G,
- [SDL_SCANCODE_H] = KEY_H,
- [SDL_SCANCODE_I] = KEY_I,
- [SDL_SCANCODE_J] = KEY_J,
- [SDL_SCANCODE_K] = KEY_K,
- [SDL_SCANCODE_L] = KEY_L,
- [SDL_SCANCODE_M] = KEY_M,
- [SDL_SCANCODE_N] = KEY_N,
- [SDL_SCANCODE_O] = KEY_O,
- [SDL_SCANCODE_P] = KEY_P,
- [SDL_SCANCODE_Q] = KEY_Q,
- [SDL_SCANCODE_R] = KEY_R,
- [SDL_SCANCODE_S] = KEY_S,
- [SDL_SCANCODE_T] = KEY_T,
- [SDL_SCANCODE_U] = KEY_U,
- [SDL_SCANCODE_V] = KEY_V,
- [SDL_SCANCODE_W] = KEY_W,
- [SDL_SCANCODE_X] = KEY_X,
- [SDL_SCANCODE_Y] = KEY_Y,
- [SDL_SCANCODE_Z] = KEY_Z,
-
+ [SDL_SCANCODE_ESCAPE] = KEY_ESC,
[SDL_SCANCODE_1] = KEY_1,
[SDL_SCANCODE_2] = KEY_2,
[SDL_SCANCODE_3] = KEY_3,
@@ -209,25 +183,53 @@ static const unsigned short sdl_to_keycode[SDL_NUM_SCANCODES] = {
[SDL_SCANCODE_8] = KEY_8,
[SDL_SCANCODE_9] = KEY_9,
[SDL_SCANCODE_0] = KEY_0,
-
- [SDL_SCANCODE_RETURN] = KEY_ENTER,
- [SDL_SCANCODE_ESCAPE] = KEY_ESC,
- [SDL_SCANCODE_BACKSPACE] = KEY_BACKSPACE,
- [SDL_SCANCODE_TAB] = KEY_TAB,
- [SDL_SCANCODE_SPACE] = KEY_SPACE,
-
[SDL_SCANCODE_MINUS] = KEY_MINUS,
[SDL_SCANCODE_EQUALS] = KEY_EQUAL,
- [SDL_SCANCODE_BACKSLASH] = KEY_BACKSLASH,
+ [SDL_SCANCODE_BACKSPACE] = KEY_BACKSPACE,
+ [SDL_SCANCODE_TAB] = KEY_TAB,
+ [SDL_SCANCODE_Q] = KEY_Q,
+ [SDL_SCANCODE_W] = KEY_W,
+ [SDL_SCANCODE_E] = KEY_E,
+ [SDL_SCANCODE_R] = KEY_R,
+ [SDL_SCANCODE_T] = KEY_T,
+ [SDL_SCANCODE_Y] = KEY_Y,
+ [SDL_SCANCODE_U] = KEY_U,
+ [SDL_SCANCODE_I] = KEY_I,
+ [SDL_SCANCODE_O] = KEY_O,
+ [SDL_SCANCODE_P] = KEY_P,
+ [SDL_SCANCODE_LEFTBRACKET] = KEY_LEFTBRACE,
+ [SDL_SCANCODE_RIGHTBRACKET] = KEY_RIGHTBRACE,
+ [SDL_SCANCODE_RETURN] = KEY_ENTER,
+ [SDL_SCANCODE_LCTRL] = KEY_LEFTCTRL,
+ [SDL_SCANCODE_A] = KEY_A,
+ [SDL_SCANCODE_S] = KEY_S,
+ [SDL_SCANCODE_D] = KEY_D,
+ [SDL_SCANCODE_F] = KEY_F,
+ [SDL_SCANCODE_G] = KEY_G,
+ [SDL_SCANCODE_H] = KEY_H,
+ [SDL_SCANCODE_J] = KEY_J,
+ [SDL_SCANCODE_K] = KEY_K,
+ [SDL_SCANCODE_L] = KEY_L,
[SDL_SCANCODE_SEMICOLON] = KEY_SEMICOLON,
[SDL_SCANCODE_APOSTROPHE] = KEY_APOSTROPHE,
[SDL_SCANCODE_GRAVE] = KEY_GRAVE,
+ [SDL_SCANCODE_LSHIFT] = KEY_LEFTSHIFT,
+ [SDL_SCANCODE_BACKSLASH] = KEY_BACKSLASH,
+ [SDL_SCANCODE_Z] = KEY_Z,
+ [SDL_SCANCODE_X] = KEY_X,
+ [SDL_SCANCODE_C] = KEY_C,
+ [SDL_SCANCODE_V] = KEY_V,
+ [SDL_SCANCODE_B] = KEY_B,
+ [SDL_SCANCODE_N] = KEY_N,
+ [SDL_SCANCODE_M] = KEY_M,
[SDL_SCANCODE_COMMA] = KEY_COMMA,
[SDL_SCANCODE_PERIOD] = KEY_DOT,
[SDL_SCANCODE_SLASH] = KEY_SLASH,
-
+ [SDL_SCANCODE_RSHIFT] = KEY_RIGHTSHIFT,
+ [SDL_SCANCODE_KP_MULTIPLY] = KEY_KPASTERISK,
+ [SDL_SCANCODE_LALT] = KEY_LEFTALT,
+ [SDL_SCANCODE_SPACE] = KEY_SPACE,
[SDL_SCANCODE_CAPSLOCK] = KEY_CAPSLOCK,
-
[SDL_SCANCODE_F1] = KEY_F1,
[SDL_SCANCODE_F2] = KEY_F2,
[SDL_SCANCODE_F3] = KEY_F3,
@@ -238,45 +240,65 @@ static const unsigned short sdl_to_keycode[SDL_NUM_SCANCODES] = {
[SDL_SCANCODE_F8] = KEY_F8,
[SDL_SCANCODE_F9] = KEY_F9,
[SDL_SCANCODE_F10] = KEY_F10,
- [SDL_SCANCODE_F11] = KEY_F11,
- [SDL_SCANCODE_F12] = KEY_F12,
-
- [SDL_SCANCODE_PRINTSCREEN] = KEY_PRINT,
- [SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLLOCK,
- [SDL_SCANCODE_PAUSE] = KEY_PAUSE,
- [SDL_SCANCODE_INSERT] = KEY_INSERT,
- [SDL_SCANCODE_HOME] = KEY_HOME,
- [SDL_SCANCODE_PAGEUP] = KEY_PAGEUP,
- [SDL_SCANCODE_DELETE] = KEY_DELETE,
- [SDL_SCANCODE_END] = KEY_END,
- [SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN,
- [SDL_SCANCODE_RIGHT] = KEY_RIGHT,
- [SDL_SCANCODE_LEFT] = KEY_LEFT,
- [SDL_SCANCODE_DOWN] = KEY_DOWN,
- [SDL_SCANCODE_UP] = KEY_UP,
-
[SDL_SCANCODE_NUMLOCKCLEAR] = KEY_NUMLOCK,
- [SDL_SCANCODE_KP_DIVIDE] = KEY_KPSLASH,
- [SDL_SCANCODE_KP_MULTIPLY] = KEY_KPASTERISK,
+ [SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLLOCK,
+ [SDL_SCANCODE_KP_7] = KEY_KP7,
+ [SDL_SCANCODE_KP_8] = KEY_KP8,
+ [SDL_SCANCODE_KP_9] = KEY_KP9,
[SDL_SCANCODE_KP_MINUS] = KEY_KPMINUS,
+ [SDL_SCANCODE_KP_4] = KEY_KP4,
+ [SDL_SCANCODE_KP_5] = KEY_KP5,
+ [SDL_SCANCODE_KP_6] = KEY_KP6,
[SDL_SCANCODE_KP_PLUS] = KEY_KPPLUS,
- [SDL_SCANCODE_KP_ENTER] = KEY_KPENTER,
[SDL_SCANCODE_KP_1] = KEY_KP1,
[SDL_SCANCODE_KP_2] = KEY_KP2,
[SDL_SCANCODE_KP_3] = KEY_KP3,
- [SDL_SCANCODE_KP_4] = KEY_KP4,
- [SDL_SCANCODE_KP_5] = KEY_KP5,
- [SDL_SCANCODE_KP_6] = KEY_KP6,
- [SDL_SCANCODE_KP_7] = KEY_KP7,
- [SDL_SCANCODE_KP_8] = KEY_KP8,
- [SDL_SCANCODE_KP_9] = KEY_KP9,
[SDL_SCANCODE_KP_0] = KEY_KP0,
[SDL_SCANCODE_KP_PERIOD] = KEY_KPDOT,
-
- [SDL_SCANCODE_KP_EQUALS] = KEY_KPEQUAL,
- [SDL_SCANCODE_KP_COMMA] = KEY_KPCOMMA,
-
+ /* key 84 does not exist linux_input.h */
+ [SDL_SCANCODE_LANG5] = KEY_ZENKAKUHANKAKU,
+ [SDL_SCANCODE_NONUSBACKSLASH] = KEY_102ND,
+ [SDL_SCANCODE_F11] = KEY_F11,
+ [SDL_SCANCODE_F12] = KEY_F12,
+ [SDL_SCANCODE_INTERNATIONAL1] = KEY_RO,
+ [SDL_SCANCODE_LANG3] = KEY_KATAKANA,
+ [SDL_SCANCODE_LANG4] = KEY_HIRAGANA,
+ [SDL_SCANCODE_INTERNATIONAL4] = KEY_HENKAN,
+ [SDL_SCANCODE_INTERNATIONAL2] = KEY_KATAKANAHIRAGANA,
+ [SDL_SCANCODE_INTERNATIONAL5] = KEY_MUHENKAN,
+ /* [SDL_SCANCODE_INTERNATIONAL5] -> [KEY_KPJPCOMMA] */
+ [SDL_SCANCODE_KP_ENTER] = KEY_KPENTER,
+ [SDL_SCANCODE_RCTRL] = KEY_RIGHTCTRL,
+ [SDL_SCANCODE_KP_DIVIDE] = KEY_KPSLASH,
[SDL_SCANCODE_SYSREQ] = KEY_SYSRQ,
+ [SDL_SCANCODE_RALT] = KEY_RIGHTALT,
+ /* KEY_LINEFEED */
+ [SDL_SCANCODE_HOME] = KEY_HOME,
+ [SDL_SCANCODE_UP] = KEY_UP,
+ [SDL_SCANCODE_PAGEUP] = KEY_PAGEUP,
+ [SDL_SCANCODE_LEFT] = KEY_LEFT,
+ [SDL_SCANCODE_RIGHT] = KEY_RIGHT,
+ [SDL_SCANCODE_END] = KEY_END,
+ [SDL_SCANCODE_DOWN] = KEY_DOWN,
+ [SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN,
+ [SDL_SCANCODE_INSERT] = KEY_INSERT,
+ [SDL_SCANCODE_DELETE] = KEY_DELETE,
+ /* KEY_MACRO */
+ [SDL_SCANCODE_MUTE] = KEY_MUTE,
+ [SDL_SCANCODE_VOLUMEDOWN] = KEY_VOLUMEDOWN,
+ [SDL_SCANCODE_VOLUMEUP] = KEY_VOLUMEUP,
+ [SDL_SCANCODE_POWER] = KEY_POWER,
+ [SDL_SCANCODE_KP_EQUALS] = KEY_KPEQUAL,
+ [SDL_SCANCODE_KP_PLUSMINUS] = KEY_KPPLUSMINUS,
+ [SDL_SCANCODE_PAUSE] = KEY_PAUSE,
+ /* KEY_SCALE */
+ [SDL_SCANCODE_KP_COMMA] = KEY_KPCOMMA,
+ [SDL_SCANCODE_LANG1] = KEY_HANGUEL,
+ [SDL_SCANCODE_LANG2] = KEY_HANJA,
+ [SDL_SCANCODE_INTERNATIONAL3] = KEY_YEN,
+ [SDL_SCANCODE_LGUI] = KEY_LEFTMETA,
+ [SDL_SCANCODE_RGUI] = KEY_RIGHTMETA,
+ [SDL_SCANCODE_APPLICATION] = KEY_COMPOSE,
};
int sandbox_sdl_scan_keys(int key[], int max_keys)
diff --git a/arch/sandbox/dts/cros-ec-keyboard.dtsi b/arch/sandbox/dts/cros-ec-keyboard.dtsi
index 9c7fb0acae..d885a5ecd2 100644
--- a/arch/sandbox/dts/cros-ec-keyboard.dtsi
+++ b/arch/sandbox/dts/cros-ec-keyboard.dtsi
@@ -1,12 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Keyboard dts fragment for devices that use cros-ec-keyboard
*
* Copyright (c) 2014 Google, Inc
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
+ * This file is taken from Linux
+ * arch/arm/boot/dts/cros-ec-keyboard.dtsi.
+ *
+ * A duplicate KEY_BACKSLASH key had to be removed.
+ */
#include <dt-bindings/input/input.h>
@@ -22,6 +24,7 @@
MATRIX_KEY(0x00, 0x02, KEY_F1)
MATRIX_KEY(0x00, 0x03, KEY_B)
MATRIX_KEY(0x00, 0x04, KEY_F10)
+ MATRIX_KEY(0x00, 0x05, KEY_RO)
MATRIX_KEY(0x00, 0x06, KEY_N)
MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
@@ -34,6 +37,7 @@
MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
MATRIX_KEY(0x01, 0x09, KEY_F9)
MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
+ MATRIX_KEY(0x01, 0x0c, KEY_HENKAN)
MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
MATRIX_KEY(0x02, 0x01, KEY_TAB)
@@ -45,6 +49,7 @@
MATRIX_KEY(0x02, 0x07, KEY_102ND)
MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
MATRIX_KEY(0x02, 0x09, KEY_F8)
+ MATRIX_KEY(0x02, 0x0a, KEY_YEN)
MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
MATRIX_KEY(0x03, 0x02, KEY_F2)
@@ -52,7 +57,9 @@
MATRIX_KEY(0x03, 0x04, KEY_F5)
MATRIX_KEY(0x03, 0x06, KEY_6)
MATRIX_KEY(0x03, 0x08, KEY_MINUS)
+ MATRIX_KEY(0x03, 0x09, KEY_F13)
MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
+ MATRIX_KEY(0x03, 0x0c, KEY_MUHENKAN)
MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
MATRIX_KEY(0x04, 0x01, KEY_A)
@@ -63,7 +70,10 @@
MATRIX_KEY(0x04, 0x06, KEY_J)
MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
MATRIX_KEY(0x04, 0x09, KEY_L)
- MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+ /*
+ * Do not map any key twice
+ * MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+ */
MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
MATRIX_KEY(0x05, 0x01, KEY_Z)
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e6da47d592..cc372806a0 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -131,6 +131,7 @@
str-value = "test string";
interrupts-extended = <&irq 3 0>;
acpi,name = "GHIJ";
+ phandle-value = <&gpio_c 10>, <0xFFFFFFFF 20>, <&gpio_a 30>;
};
junk {
diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c
index a4d5fbd38a..4496bbfd99 100644
--- a/arch/x86/cpu/intel_common/acpi.c
+++ b/arch/x86/cpu/intel_common/acpi.c
@@ -198,7 +198,7 @@ int southbridge_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx)
struct acpi_global_nvs *gnvs;
int ret;
- ret = bloblist_ensure_size(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs),
+ ret = bloblist_ensure_size(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs), 0,
(void **)&gnvs);
if (ret)
return log_msg_ret("bloblist", ret);
diff --git a/arch/x86/cpu/intel_common/intel_opregion.c b/arch/x86/cpu/intel_common/intel_opregion.c
index 4e6c64d9aa..c95ae04992 100644
--- a/arch/x86/cpu/intel_common/intel_opregion.c
+++ b/arch/x86/cpu/intel_common/intel_opregion.c
@@ -108,7 +108,7 @@ int intel_gma_init_igd_opregion(struct udevice *dev,
struct optionrom_vbt *ext_vbt;
ret = bloblist_ensure_size(BLOBLISTT_INTEL_VBT,
- vbt->hdr_vbt_size,
+ vbt->hdr_vbt_size, 0,
(void **)&ext_vbt);
if (ret) {
log_err("GMA: Unable to add Ext VBT to bloblist\n");
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 3b677d339b..03a19af930 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -314,7 +314,7 @@ static int board_check_usb_power(void)
* for each of them
*/
adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
- "#io-channel-cells");
+ "#io-channel-cells", 0);
if (adc_count < 0) {
if (adc_count == -ENOENT)
return 0;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 999b6cf239..b25d2b02ed 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -631,6 +631,15 @@ config CMD_BINOP
Compute binary operations (xor, or, and) of byte arrays of arbitrary
size from memory and store the result in memory or the environment.
+config CMD_BLOBLIST
+ bool "bloblist"
+ default y if BLOBLIST
+ help
+ Show information about the bloblist, a collection of binary blobs
+ held in memory that persist between SPL and U-Boot. In the case of
+ x86 devices the bloblist can be used to hold ACPI tables so that they
+ remain available in memory.
+
config CMD_CRC32
bool "crc32"
default y
diff --git a/cmd/Makefile b/cmd/Makefile
index c7a08ed109..015b83764c 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_CMD_BIND) += bind.o
obj-$(CONFIG_CMD_BINOP) += binop.o
+obj-$(CONFIG_CMD_BLOBLIST) += bloblist.o
obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_CMD_BMP) += bmp.o
obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o
diff --git a/cmd/bloblist.c b/cmd/bloblist.c
new file mode 100644
index 0000000000..bb2e682ff8
--- /dev/null
+++ b/cmd/bloblist.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Command-line access to bloblist features
+ *
+ * Copyright 2020 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <bloblist.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int do_bloblist_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ bloblist_show_stats();
+
+ return 0;
+}
+
+static int do_bloblist_list(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ bloblist_show_list();
+
+ return 0;
+}
+
+static char bloblist_help_text[] =
+ "info - show information about the bloblist\n"
+ "bloblist list - list blobs in the bloblist";
+
+U_BOOT_CMD_WITH_SUBCMDS(bloblist, "Bloblists", bloblist_help_text,
+ U_BOOT_SUBCMD_MKENT(info, 1, 1, do_bloblist_info),
+ U_BOOT_SUBCMD_MKENT(list, 1, 1, do_bloblist_list));
diff --git a/common/bloblist.c b/common/bloblist.c
index 99501951e0..33b5862380 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -11,17 +11,47 @@
#include <spl.h>
#include <u-boot/crc.h>
+/*
+ * A bloblist is a single contiguous chunk of memory with a header
+ * (struct bloblist_hdr) and a number of blobs in it.
+ *
+ * Each blob starts on a BLOBLIST_ALIGN boundary relative to the start of the
+ * bloblist and consists of a struct bloblist_rec, some padding to the required
+ * alignment for the blog and then the actual data. The padding ensures that the
+ * start address of the data in each blob is aligned as required. Note that
+ * each blob's *data* is aligned to BLOBLIST_ALIGN regardless of the alignment
+ * of the bloblist itself or the blob header.
+ *
+ * So far, only BLOBLIST_ALIGN alignment is supported.
+ */
+
DECLARE_GLOBAL_DATA_PTR;
-struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
+static const char *const tag_name[] = {
+ [BLOBLISTT_NONE] = "(none)",
+ [BLOBLISTT_EC_HOSTEVENT] = "EC host event",
+ [BLOBLISTT_SPL_HANDOFF] = "SPL hand-off",
+ [BLOBLISTT_VBOOT_CTX] = "Chrome OS vboot context",
+ [BLOBLISTT_VBOOT_HANDOFF] = "Chrome OS vboot hand-off",
+};
+
+const char *bloblist_tag_name(enum bloblist_tag_t tag)
+{
+ if (tag < 0 || tag >= BLOBLISTT_COUNT)
+ return "invalid";
+
+ return tag_name[tag];
+}
+
+static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
{
if (hdr->alloced <= hdr->hdr_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
}
-struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
- struct bloblist_rec *rec)
+static struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
+ struct bloblist_rec *rec)
{
ulong offset;
@@ -53,13 +83,25 @@ static struct bloblist_rec *bloblist_findrec(uint tag)
return NULL;
}
-static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp)
+static int bloblist_addrec(uint tag, int size, int align,
+ struct bloblist_rec **recp)
{
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
- int new_alloced;
+ int data_start, new_alloced;
+
+ if (!align)
+ align = BLOBLIST_ALIGN;
+
+ /* Figure out where the new data will start */
+ data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
+
+ /* Align the address and then calculate the offset from ->alloced */
+ data_start = ALIGN(data_start, align) - map_to_sysmem(hdr);
+
+ /* Calculate the new allocated total */
+ new_alloced = data_start + ALIGN(size, align);
- new_alloced = hdr->alloced + sizeof(*rec) + ALIGN(size, BLOBLIST_ALIGN);
if (new_alloced >= hdr->size) {
log(LOGC_BLOBLIST, LOGL_ERR,
"Failed to allocate %x bytes size=%x, need size=%x\n",
@@ -67,21 +109,23 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp)
return log_msg_ret("bloblist add", -ENOSPC);
}
rec = (void *)hdr + hdr->alloced;
- hdr->alloced = new_alloced;
rec->tag = tag;
- rec->hdr_size = sizeof(*rec);
+ rec->hdr_size = data_start - hdr->alloced;
rec->size = size;
rec->spare = 0;
/* Zero the record data */
- memset(rec + 1, '\0', rec->size);
+ memset((void *)rec + rec->hdr_size, '\0', rec->size);
+
+ hdr->alloced = new_alloced;
*recp = rec;
return 0;
}
-static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size)
+static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
+ int align)
{
struct bloblist_rec *rec;
@@ -94,7 +138,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size)
} else {
int ret;
- ret = bloblist_addrec(tag, size, &rec);
+ ret = bloblist_addrec(tag, size, align, &rec);
if (ret)
return ret;
}
@@ -116,22 +160,22 @@ void *bloblist_find(uint tag, int size)
return (void *)rec + rec->hdr_size;
}
-void *bloblist_add(uint tag, int size)
+void *bloblist_add(uint tag, int size, int align)
{
struct bloblist_rec *rec;
- if (bloblist_addrec(tag, size, &rec))
+ if (bloblist_addrec(tag, size, align, &rec))
return NULL;
- return rec + 1;
+ return (void *)rec + rec->hdr_size;
}
-int bloblist_ensure_size(uint tag, int size, void **blobp)
+int bloblist_ensure_size(uint tag, int size, int align, void **blobp)
{
struct bloblist_rec *rec;
int ret;
- ret = bloblist_ensurerec(tag, &rec, size);
+ ret = bloblist_ensurerec(tag, &rec, size, align);
if (ret)
return ret;
*blobp = (void *)rec + rec->hdr_size;
@@ -143,7 +187,7 @@ void *bloblist_ensure(uint tag, int size)
{
struct bloblist_rec *rec;
- if (bloblist_ensurerec(tag, &rec, size))
+ if (bloblist_ensurerec(tag, &rec, size, 0))
return NULL;
return (void *)rec + rec->hdr_size;
@@ -154,7 +198,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
struct bloblist_rec *rec;
int ret;
- ret = bloblist_ensurerec(tag, &rec, *sizep);
+ ret = bloblist_ensurerec(tag, &rec, *sizep, 0);
if (ret == -ESPIPE)
*sizep = rec->size;
else if (ret)
@@ -233,6 +277,46 @@ int bloblist_finish(void)
return 0;
}
+void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
+{
+ struct bloblist_hdr *hdr = gd->bloblist;
+
+ *basep = map_to_sysmem(gd->bloblist);
+ *sizep = hdr->size;
+ *allocedp = hdr->alloced;
+}
+
+static void show_value(const char *prompt, ulong value)
+{
+ printf("%s:%*s %-5lx ", prompt, 8 - (int)strlen(prompt), "", value);
+ print_size(value, "\n");
+}
+
+void bloblist_show_stats(void)
+{
+ ulong base, size, alloced;
+
+ bloblist_get_stats(&base, &size, &alloced);
+ printf("base: %lx\n", base);
+ show_value("size", size);
+ show_value("alloced", alloced);
+ show_value("free", size - alloced);
+}
+
+void bloblist_show_list(void)
+{
+ struct bloblist_hdr *hdr = gd->bloblist;
+ struct bloblist_rec *rec;
+
+ printf("%-8s %8s Tag Name\n", "Address", "Size");
+ for (rec = bloblist_first_blob(hdr); rec;
+ rec = bloblist_next_blob(hdr, rec)) {
+ printf("%08lx %8x %3d %s\n",
+ (ulong)map_to_sysmem((void *)rec + rec->hdr_size),
+ rec->size, rec->tag, bloblist_tag_name(rec->tag));
+ }
+}
+
int bloblist_init(void)
{
bool expected;
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 360f22461a..4674c420ac 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -97,30 +97,39 @@ Command-line Options
--------------------
Various options are available, mostly for test purposes. Use -h to see
-available options. Some of these are described below.
-
-The terminal is normally in what is called 'raw-with-sigs' mode. This means
-that you can use arrow keys for command editing and history, but if you
-press Ctrl-C, U-Boot will exit instead of handling this as a keypress.
-
-Other options are 'raw' (so Ctrl-C is handled within U-Boot) and 'cooked'
-(where the terminal is in cooked mode and cursor keys will not work, Ctrl-C
-will exit).
-
-As mentioned above, -l causes the LCD emulation window to be shown.
-
-A device tree binary file can be provided with -d. If you edit the source
-(it is stored at arch/sandbox/dts/sandbox.dts) you must rebuild U-Boot to
-recreate the binary file.
-
-To use the default device tree, use -D. To use the test device tree, use -T.
-
-To execute commands directly, use the -c option. You can specify a single
-command, or multiple commands separated by a semicolon, as is normal in
-U-Boot. Be careful with quoting as the shell will normally process and
-swallow quotes. When -c is used, U-Boot exits after the command is complete,
-but you can force it to go to interactive mode instead with -i.
-
+available options. Some of these are described below:
+
+* -t, --terminal <arg>
+ - The terminal is normally in what is called 'raw-with-sigs' mode. This means
+ that you can use arrow keys for command editing and history, but if you
+ press Ctrl-C, U-Boot will exit instead of handling this as a keypress.
+ Other options are 'raw' (so Ctrl-C is handled within U-Boot) and 'cooked'
+ (where the terminal is in cooked mode and cursor keys will not work, Ctrl-C
+ will exit).
+
+* -l
+ - Show the LCD emulation window.
+
+* -d <device_tree>
+ - A device tree binary file can be provided with -d. If you edit the source
+ (it is stored at arch/sandbox/dts/sandbox.dts) you must rebuild U-Boot to
+ recreate the binary file.
+
+* -D
+ - To use the default device tree, use -D.
+
+* -T
+ - To use the test device tree, use -T.
+
+* -c [<cmd>;]<cmd>
+ - To execute commands directly, use the -c option. You can specify a single
+ command, or multiple commands separated by a semicolon, as is normal in
+ U-Boot. Be careful with quoting as the shell will normally process and
+ swallow quotes. When -c is used, U-Boot exits after the command is complete,
+ but you can force it to go to interactive mode instead with -i.
+
+* -i
+ - Go to interactive mode after executing the commands specified by -c.
Memory Emulation
----------------
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 4076535271..31c5997aea 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -161,7 +161,7 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
bulk->count = 0;
- count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+ count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0);
if (count < 1)
return count;
@@ -213,7 +213,7 @@ static int clk_set_default_parents(struct udevice *dev, int stage)
int ret;
num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents",
- "#clock-cells");
+ "#clock-cells", 0);
if (num_parents < 0) {
debug("%s: could not read assigned-clock-parents for %p\n",
__func__, dev);
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index bcf1644d05..0a12e9b26f 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -756,10 +756,11 @@ int of_parse_phandle_with_args(const struct device_node *np,
}
int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name)
+ const char *list_name, const char *cells_name,
+ int cell_count)
{
- return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
- -1, NULL);
+ return __of_parse_phandle_with_args(np, list_name, cells_name,
+ cell_count, -1, NULL);
}
static void of_alias_add(struct alias_prop *ap, struct device_node *np,
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 79fcdf5ce2..7d1b89514c 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -432,15 +432,15 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
}
int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
- const char *cells_name)
+ const char *cells_name, int cell_count)
{
if (ofnode_is_np(node))
return of_count_phandle_with_args(ofnode_to_np(node),
- list_name, cells_name);
+ list_name, cells_name, cell_count);
else
return fdtdec_parse_phandle_with_args(gd->fdt_blob,
ofnode_to_offset(node), list_name, cells_name,
- 0, -1, NULL);
+ cell_count, -1, NULL);
}
ofnode ofnode_path(const char *path)
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 86f3f88170..076125824c 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -214,10 +214,11 @@ int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name,
}
int dev_count_phandle_with_args(const struct udevice *dev,
- const char *list_name, const char *cells_name)
+ const char *list_name, const char *cells_name,
+ int cell_count)
{
return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name,
- cells_name);
+ cells_name, cell_count);
}
int dev_read_addr_cells(const struct udevice *dev)
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 1c0e829407..4c19abbaf0 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -688,7 +688,8 @@ int designware_eth_probe(struct udevice *dev)
int i, clock_nb;
priv->clock_count = 0;
- clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+ clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells",
+ 0);
if (clock_nb > 0) {
priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
GFP_KERNEL);
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index 8f456f33d2..f344e94b43 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -214,7 +214,7 @@ int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk)
if (!dev_read_prop(dev, "phys", NULL))
return 0;
- count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
+ count = dev_count_phandle_with_args(dev, "phys", "#phy-cells", 0);
if (count < 1)
return count;
diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c
index c2c7c3bd50..af829db9da 100644
--- a/drivers/power/domain/power-domain-uclass.c
+++ b/drivers/power/domain/power-domain-uclass.c
@@ -117,7 +117,7 @@ static int dev_power_domain_ctrl(struct udevice *dev, bool on)
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "power-domains",
- "#power-domain-cells");
+ "#power-domain-cells", 0);
for (i = 0; i < count; i++) {
ret = power_domain_get_by_index(dev, &pd, i);
if (ret)
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index e7e407ca35..071c389ca0 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -108,7 +108,8 @@ static int __reset_get_bulk(struct udevice *dev, ofnode node,
bulk->count = 0;
- count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells");
+ count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells",
+ 0);
if (count < 1)
return count;
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 304a3437d5..c93a7051a7 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -86,7 +86,7 @@ static int ehci_usb_probe(struct udevice *dev)
err = 0;
priv->clock_count = 0;
clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
- "#clock-cells");
+ "#clock-cells", 0);
if (clock_nb > 0) {
priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
GFP_KERNEL);
@@ -116,7 +116,7 @@ static int ehci_usb_probe(struct udevice *dev)
priv->reset_count = 0;
reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
- "#reset-cells");
+ "#reset-cells", 0);
if (reset_nb > 0) {
priv->resets = devm_kcalloc(dev, reset_nb,
sizeof(struct reset_ctl),
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 22e7b565b5..aa1eba262a 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -95,7 +95,8 @@ static int ohci_da8xx_probe(struct udevice *dev)
err = 0;
priv->clock_count = 0;
- clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+ clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells",
+ 0);
if (clock_nb < 0)
return clock_nb;
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index ed5e500b2c..ac9b7e1e3c 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -85,7 +85,8 @@ static int ohci_usb_probe(struct udevice *dev)
err = 0;
priv->clock_count = 0;
- clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+ clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells",
+ 0);
if (clock_nb > 0) {
priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
GFP_KERNEL);
@@ -111,7 +112,8 @@ static int ohci_usb_probe(struct udevice *dev)
}
priv->reset_count = 0;
- reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells");
+ reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells",
+ 0);
if (reset_nb > 0) {
priv->resets = devm_kcalloc(dev, reset_nb,
sizeof(struct reset_ctl),
diff --git a/include/bloblist.h b/include/bloblist.h
index 5784c2226e..2b4b669689 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -19,6 +19,7 @@ enum {
BLOBLIST_ALIGN = 16,
};
+/* Supported tags - add new ones to tag_name in bloblist.c */
enum bloblist_tag_t {
BLOBLISTT_NONE = 0,
@@ -35,6 +36,8 @@ enum bloblist_tag_t {
BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */
BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG, /* TPM log space */
+
+ BLOBLISTT_COUNT
};
/**
@@ -65,7 +68,7 @@ enum bloblist_tag_t {
* the bloblist can grow up to this size. This starts out as
* sizeof(bloblist_hdr) since we need at least that much space to store a
* valid bloblist
- * @spare: Space space
+ * @spare: Spare space (for future use)
* @chksum: CRC32 for the entire bloblist allocated area. Since any of the
* blobs can be altered after being created, this checksum is only valid
* when the bloblist is finalised before jumping to the next stage of boot.
@@ -112,7 +115,7 @@ struct bloblist_rec {
* Searches the bloblist and returns the blob with the matching tag
*
* @tag: Tag to search for (enum bloblist_tag_t)
- * @size: Expected size of the blob
+ * @size: Expected size of the blob, or 0 for any size
* @return pointer to blob if found, or NULL if not found, or a blob was found
* but it is the wrong size
*/
@@ -129,10 +132,11 @@ void *bloblist_find(uint tag, int size);
*
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
+ * @align: Alignment of the blob (in bytes), 0 for default
* @return pointer to the newly added block, or NULL if there is not enough
* space for the blob
*/
-void *bloblist_add(uint tag, int size);
+void *bloblist_add(uint tag, int size, int align);
/**
* bloblist_ensure_size() - Find or add a blob
@@ -142,10 +146,11 @@ void *bloblist_add(uint tag, int size);
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* @blobp: Returns a pointer to blob on success
+ * @align: Alignment of the blob (in bytes), 0 for default
* @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack
* of space, or -ESPIPE it exists but has the wrong size
*/
-int bloblist_ensure_size(uint tag, int size, void **blobp);
+int bloblist_ensure_size(uint tag, int size, int align, void **blobp);
/**
* bloblist_ensure() - Find or add a blob
@@ -207,6 +212,35 @@ int bloblist_check(ulong addr, uint size);
int bloblist_finish(void);
/**
+ * bloblist_get_stats() - Get information about the bloblist
+ *
+ * This returns useful information about the bloblist
+ */
+void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
+
+/**
+ * bloblist_show_stats() - Show information about the bloblist
+ *
+ * This shows useful information about the bloblist on the console
+ */
+void bloblist_show_stats(void);
+
+/**
+ * bloblist_show_list() - Show a list of blobs in the bloblist
+ *
+ * This shows a list of blobs, showing their address, size and tag.
+ */
+void bloblist_show_list(void);
+
+/**
+ * bloblist_tag_name() - Get the name for a tag
+ *
+ * @tag: Tag to check
+ * @return name of tag, or "invalid" if an invalid tag is provided
+ */
+const char *bloblist_tag_name(enum bloblist_tag_t tag);
+
+/**
* bloblist_init() - Init the bloblist system with a single bloblist
*
* This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index 2fa65c9332..cc382b1671 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -450,6 +450,7 @@ int of_parse_phandle_with_args(const struct device_node *np,
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
+ * @cells_count: Cell count to use if @cells_name is NULL
* @return number of phandle found, -ENOENT if
* @list_name does not exist, -EINVAL if a phandle was not found,
* @cells_name could not be found, the arguments were truncated or there
@@ -460,7 +461,8 @@ int of_parse_phandle_with_args(const struct device_node *np,
*
*/
int of_count_phandle_with_args(const struct device_node *np,
- const char *list_name, const char *cells_name);
+ const char *list_name, const char *cells_name,
+ int cells_count);
/**
* of_alias_scan() - Scan all properties of the 'aliases' node
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 8df2facf99..4b7af37056 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -10,6 +10,7 @@
/* TODO(sjg@chromium.org): Drop fdtdec.h include */
#include <fdtdec.h>
#include <dm/of.h>
+#include <log.h>
/* Enable checks to protect against invalid calls */
#undef OF_CHECKS
@@ -84,7 +85,7 @@ struct ofprop {
};
/**
- * _ofnode_to_np() - convert an ofnode to a live DT node pointer
+ * ofnode_to_np() - convert an ofnode to a live DT node pointer
*
* This cannot be called if the reference contains an offset.
*
@@ -127,7 +128,7 @@ static inline bool ofnode_valid(ofnode node)
if (of_live_active())
return node.np != NULL;
else
- return node.of_offset != -1;
+ return node.of_offset >= 0;
}
/**
@@ -182,8 +183,8 @@ static inline bool ofnode_is_np(ofnode node)
* live tree is in use.
*/
assert(!ofnode_valid(node) ||
- (of_live_active() ? _ofnode_to_np(node)
- : _ofnode_to_np(node)));
+ (of_live_active() ? ofnode_to_np(node)
+ : ofnode_to_np(node)));
#endif
return of_live_active() && ofnode_valid(node);
}
@@ -555,12 +556,13 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
* @node: device tree node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
+ * @cells_count: Cell count to use if @cells_name is NULL
* @return number of phandle on success, -ENOENT if @list_name does not
* exist, -EINVAL if a phandle was not found, @cells_name could not
* be found.
*/
int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
- const char *cells_name);
+ const char *cells_name, int cell_count);
/**
* ofnode_path() - find a node by full path
diff --git a/include/dm/read.h b/include/dm/read.h
index 67db94adfc..0585eb1228 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -429,12 +429,14 @@ int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name,
* @dev: device whose node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
+ * @cells_count: Cell count to use if @cells_name is NULL
* @Returns number of phandle found on success, on error returns appropriate
* errno value.
*/
int dev_count_phandle_with_args(const struct udevice *dev,
- const char *list_name, const char *cells_name);
+ const char *list_name, const char *cells_name,
+ int cell_count);
/**
* dev_read_addr_cells() - Get the number of address cells for a device's node
@@ -880,10 +882,10 @@ static inline int dev_read_phandle_with_args(const struct udevice *dev,
}
static inline int dev_count_phandle_with_args(const struct udevice *dev,
- const char *list_name, const char *cells_name)
+ const char *list_name, const char *cells_name, int cell_count)
{
return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name,
- cells_name);
+ cells_name, cell_count);
}
static inline int dev_read_addr_cells(const struct udevice *dev)
diff --git a/include/test/ut.h b/include/test/ut.h
index 3295cd4e54..3f2ee7514b 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -224,6 +224,19 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
} \
}
+/* Assert that two addresses (converted from pointers) are equal */
+#define ut_asserteq_addr(expr1, expr2) { \
+ ulong _val1 = map_to_sysmem(expr1); \
+ ulong _val2 = map_to_sysmem(expr2); \
+ \
+ if (_val1 != _val2) { \
+ ut_failf(uts, __FILE__, __LINE__, __func__, \
+ #expr1 " = " #expr2, \
+ "Expected %lx, got %lx", _val1, _val2); \
+ return CMD_RET_FAILURE; \
+ } \
+}
+
/* Assert that a pointer is NULL */
#define ut_assertnull(expr) { \
const void *_val = (expr); \
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index b8fc5e2bff..ee1bd41b08 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -746,7 +746,7 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node,
if (cells_name || cur_index == index) {
node = fdt_node_offset_by_phandle(blob,
phandle);
- if (!node) {
+ if (node < 0) {
debug("%s: could not find phandle\n",
fdt_get_name(blob, src_node,
NULL));
diff --git a/test/bloblist.c b/test/bloblist.c
index 4e537ee1b9..0bb9e2d81e 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -7,6 +7,7 @@
#include <bloblist.h>
#include <log.h>
#include <mapmem.h>
+#include <asm/state.h>
#include <test/suites.h>
#include <test/test.h>
#include <test/ut.h>
@@ -24,10 +25,12 @@ enum {
TEST_SIZE = 10,
TEST_SIZE2 = 20,
- TEST_SIZE_LARGE = 0xe0,
+ TEST_SIZE_LARGE = 0x3e0,
TEST_ADDR = CONFIG_BLOBLIST_ADDR,
- TEST_BLOBLIST_SIZE = 0x100,
+ TEST_BLOBLIST_SIZE = 0x400,
+
+ ERASE_BYTE = '\xff',
};
static struct bloblist_hdr *clear_bloblist(void)
@@ -40,7 +43,7 @@ static struct bloblist_hdr *clear_bloblist(void)
* to 0xff for testing purposes.
*/
hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE);
- memset(hdr, '\xff', TEST_BLOBLIST_SIZE);
+ memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
memset(hdr, '\0', sizeof(*hdr));
return hdr;
@@ -94,26 +97,27 @@ static int bloblist_test_blob(struct unit_test_state *uts)
hdr = clear_bloblist();
ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
/* Add a record and check that we can find it */
- data = bloblist_add(TEST_TAG, TEST_SIZE);
+ data = bloblist_add(TEST_TAG, TEST_SIZE, 0);
rec = (void *)(hdr + 1);
- ut_asserteq_ptr(rec + 1, data);
+ ut_asserteq_addr(rec + 1, data);
data = bloblist_find(TEST_TAG, TEST_SIZE);
- ut_asserteq_ptr(rec + 1, data);
+ ut_asserteq_addr(rec + 1, data);
/* Check the data is zeroed */
ut_assertok(check_zero(data, TEST_SIZE));
/* Check the 'ensure' method */
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+ ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2));
rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN));
ut_assertok(check_zero(data, TEST_SIZE));
/* Check for a non-existent record */
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
+ ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+ ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2));
ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0));
return 0;
@@ -139,7 +143,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* Check that we get the same thing again */
ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
ut_asserteq(TEST_SIZE, size);
- ut_asserteq_ptr(data, data2);
+ ut_asserteq_addr(data, data2);
/* Check that the size remains the same */
size = TEST_SIZE2;
@@ -163,8 +167,8 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts)
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
data = hdr + 1;
data += sizeof(struct bloblist_rec);
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
- ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+ ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
+ ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
return 0;
}
@@ -202,10 +206,10 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
hdr->chksum--;
/* Make sure the checksum changes when we add blobs */
- data = bloblist_add(TEST_TAG, TEST_SIZE);
+ data = bloblist_add(TEST_TAG, TEST_SIZE, 0);
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- data2 = bloblist_add(TEST_TAG2, TEST_SIZE2);
+ data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0);
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_finish());
@@ -231,9 +235,123 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
return 0;
}
-
BLOBLIST_TEST(bloblist_test_checksum, 0);
+/* Test the 'bloblist info' command */
+static int bloblist_test_cmd_info(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+ struct bloblist_hdr *hdr;
+ char *data, *data2;
+
+ hdr = clear_bloblist();
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ data = bloblist_ensure(TEST_TAG, TEST_SIZE);
+ data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
+
+ console_record_reset_enable();
+ if (!state->show_test_output)
+ gd->flags |= GD_FLG_SILENT;
+ console_record_reset();
+ run_command("bloblist info", 0);
+ ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
+ ut_assert_nextline("size: 400 1 KiB");
+ ut_assert_nextline("alloced: 70 112 Bytes");
+ ut_assert_nextline("free: 390 912 Bytes");
+ ut_assert_console_end();
+ gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_cmd_info, 0);
+
+/* Test the 'bloblist list' command */
+static int bloblist_test_cmd_list(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+ struct bloblist_hdr *hdr;
+ char *data, *data2;
+
+ hdr = clear_bloblist();
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ data = bloblist_ensure(TEST_TAG, TEST_SIZE);
+ data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
+
+ console_record_reset_enable();
+ if (!state->show_test_output)
+ gd->flags |= GD_FLG_SILENT;
+ console_record_reset();
+ run_command("bloblist list", 0);
+ ut_assert_nextline("Address Size Tag Name");
+ ut_assert_nextline("%08lx %8x 1 EC host event",
+ (ulong)map_to_sysmem(data), TEST_SIZE);
+ ut_assert_nextline("%08lx %8x 2 SPL hand-off",
+ (ulong)map_to_sysmem(data2), TEST_SIZE2);
+ ut_assert_console_end();
+ gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_cmd_list, 0);
+
+/* Test alignment of bloblist blobs */
+static int bloblist_test_align(struct unit_test_state *uts)
+{
+ struct bloblist_hdr *hdr;
+ ulong addr;
+ char *data;
+ int i;
+
+ /* At the start there should be no records */
+ hdr = clear_bloblist();
+ ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+ ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
+
+ /* Check the default alignment */
+ for (i = 0; i < 3; i++) {
+ int size = i * 3;
+ ulong addr;
+ char *data;
+ int j;
+
+ data = bloblist_add(i, size, 0);
+ ut_assertnonnull(data);
+ addr = map_to_sysmem(data);
+ ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1));
+
+ /* Only the bytes in the blob data should be zeroed */
+ for (j = 0; j < size; j++)
+ ut_asserteq(0, data[j]);
+ for (; j < BLOBLIST_ALIGN; j++)
+ ut_asserteq(ERASE_BYTE, data[j]);
+ }
+
+ /* Check larger alignment */
+ for (i = 0; i < 3; i++) {
+ int align = 32 << i;
+
+ data = bloblist_add(3 + i, i * 4, align);
+ ut_assertnonnull(data);
+ addr = map_to_sysmem(data);
+ ut_asserteq(0, addr & (align - 1));
+ }
+
+ /* Check alignment with an bloblist starting on a smaller alignment */
+ hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE);
+ memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
+ memset(hdr, '\0', sizeof(*hdr));
+ ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE,
+ 0));
+
+ data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2);
+ ut_assertnonnull(data);
+ addr = map_to_sysmem(data);
+ ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1));
+
+ return 0;
+}
+BLOBLIST_TEST(bloblist_test_align, 0);
+
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c
index 8bfb706602..01ac3c2094 100644
--- a/test/dm/ofnode.c
+++ b/test/dm/ofnode.c
@@ -19,6 +19,22 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts)
}
DM_TEST(dm_test_ofnode_compatible, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts)
+{
+ /* test invalid phandle */
+ ut_assert(!ofnode_valid(ofnode_get_by_phandle(0)));
+ ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1)));
+
+ /* test first valid phandle */
+ ut_assert(ofnode_valid(ofnode_get_by_phandle(1)));
+
+ /* test unknown phandle */
+ ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000)));
+
+ return 0;
+}
+DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
{
const char propname[] = "compatible";
@@ -87,6 +103,81 @@ static int dm_test_ofnode_read(struct unit_test_state *uts)
}
DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_phandle(struct unit_test_state *uts)
+{
+ struct ofnode_phandle_args args;
+ ofnode node;
+ int ret;
+ const char prop[] = "test-gpios";
+ const char cell[] = "#gpio-cells";
+ const char prop2[] = "phandle-value";
+
+ node = ofnode_path("/a-test");
+ ut_assert(ofnode_valid(node));
+
+ /* Test ofnode_count_phandle_with_args with cell name */
+ ret = ofnode_count_phandle_with_args(node, "missing", cell, 0);
+ ut_asserteq(-ENOENT, ret);
+ ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0);
+ ut_asserteq(-EINVAL, ret);
+ ret = ofnode_count_phandle_with_args(node, prop, cell, 0);
+ ut_asserteq(5, ret);
+
+ /* Test ofnode_parse_phandle_with_args with cell name */
+ ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0,
+ &args);
+ ut_asserteq(-ENOENT, ret);
+ ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0,
+ &args);
+ ut_asserteq(-EINVAL, ret);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args);
+ ut_assertok(ret);
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(1, args.args[0]);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args);
+ ut_assertok(ret);
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(4, args.args[0]);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args);
+ ut_assertok(ret);
+ ut_asserteq(5, args.args_count);
+ ut_asserteq(5, args.args[0]);
+ ut_asserteq(1, args.args[4]);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args);
+ ut_asserteq(-ENOENT, ret);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args);
+ ut_assertok(ret);
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(12, args.args[0]);
+ ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args);
+ ut_asserteq(-ENOENT, ret);
+
+ /* Test ofnode_count_phandle_with_args with cell count */
+ ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2);
+ ut_asserteq(-ENOENT, ret);
+ ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1);
+ ut_asserteq(3, ret);
+
+ /* Test ofnode_parse_phandle_with_args with cell count */
+ ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args);
+ ut_assertok(ret);
+ ut_asserteq(1, ofnode_valid(args.node));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(10, args.args[0]);
+ ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args);
+ ut_asserteq(-EINVAL, ret);
+ ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args);
+ ut_assertok(ret);
+ ut_asserteq(1, ofnode_valid(args.node));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(30, args.args[0]);
+ ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args);
+ ut_asserteq(-ENOENT, ret);
+
+ return 0;
+}
+DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
{
const char *str;
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 26d57f40d1..cc12419ea0 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -968,6 +968,71 @@ static int dm_test_read_int_index(struct unit_test_state *uts)
}
DM_TEST(dm_test_read_int_index, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_read_phandle(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct ofnode_phandle_args args;
+ int ret;
+ const char prop[] = "test-gpios";
+ const char cell[] = "#gpio-cells";
+ const char prop2[] = "phandle-value";
+
+ ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
+ ut_asserteq_str("a-test", dev->name);
+
+ /* Test dev_count_phandle_with_args with cell name */
+ ret = dev_count_phandle_with_args(dev, "missing", cell, 0);
+ ut_asserteq(-ENOENT, ret);
+ ret = dev_count_phandle_with_args(dev, prop, "#invalid", 0);
+ ut_asserteq(-EINVAL, ret);
+ ut_asserteq(5, dev_count_phandle_with_args(dev, prop, cell, 0));
+
+ /* Test dev_read_phandle_with_args with cell name */
+ ret = dev_read_phandle_with_args(dev, "missing", cell, 0, 0, &args);
+ ut_asserteq(-ENOENT, ret);
+ ret = dev_read_phandle_with_args(dev, prop, "#invalid", 0, 0, &args);
+ ut_asserteq(-EINVAL, ret);
+ ut_assertok(dev_read_phandle_with_args(dev, prop, cell, 0, 0, &args));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(1, args.args[0]);
+ ut_assertok(dev_read_phandle_with_args(dev, prop, cell, 0, 1, &args));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(4, args.args[0]);
+ ut_assertok(dev_read_phandle_with_args(dev, prop, cell, 0, 2, &args));
+ ut_asserteq(5, args.args_count);
+ ut_asserteq(5, args.args[0]);
+ ut_asserteq(1, args.args[4]);
+ ret = dev_read_phandle_with_args(dev, prop, cell, 0, 3, &args);
+ ut_asserteq(-ENOENT, ret);
+ ut_assertok(dev_read_phandle_with_args(dev, prop, cell, 0, 4, &args));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(12, args.args[0]);
+ ret = dev_read_phandle_with_args(dev, prop, cell, 0, 5, &args);
+ ut_asserteq(-ENOENT, ret);
+
+ /* Test dev_count_phandle_with_args with cell count */
+ ret = dev_count_phandle_with_args(dev, "missing", NULL, 2);
+ ut_asserteq(-ENOENT, ret);
+ ut_asserteq(3, dev_count_phandle_with_args(dev, prop2, NULL, 1));
+
+ /* Test dev_read_phandle_with_args with cell count */
+ ut_assertok(dev_read_phandle_with_args(dev, prop2, NULL, 1, 0, &args));
+ ut_asserteq(1, ofnode_valid(args.node));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(10, args.args[0]);
+ ret = dev_read_phandle_with_args(dev, prop2, NULL, 1, 1, &args);
+ ut_asserteq(-EINVAL, ret);
+ ut_assertok(dev_read_phandle_with_args(dev, prop2, NULL, 1, 2, &args));
+ ut_asserteq(1, ofnode_valid(args.node));
+ ut_asserteq(1, args.args_count);
+ ut_asserteq(30, args.args[0]);
+ ret = dev_read_phandle_with_args(dev, prop2, NULL, 1, 3, &args);
+ ut_asserteq(-ENOENT, ret);
+
+ return 0;
+}
+DM_TEST(dm_test_read_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
/* Test iteration through devices by drvdata */
static int dm_test_uclass_drvdata(struct unit_test_state *uts)
{