From b0b3524d94bd81bdbaa9e7c25abe76f5b695fa3b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 19 Sep 2020 20:04:57 +0200 Subject: [PATCH 01/14] MAINTAINERS: assign doc/arch/sandbox.rst Add doc/arch/sandbox.rst to the scope of SANDBOX. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 85babd1908..ed5e354873 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -959,6 +959,7 @@ SANDBOX M: Simon Glass S: Maintained F: arch/sandbox/ +F: doc/arch/sandbox.rst SH M: Marek Vasut From 9c22adb8f979ce1386b600a13f5abc37ec92d696 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 19 Sep 2020 20:05:47 +0200 Subject: [PATCH 02/14] doc/arch/sandbox.rst: reformat command line options Reformat the command line options chapter so that the command line options clearly stand out. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- doc/arch/sandbox.rst | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) 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. +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. +* -t, --terminal + - 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). -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. -As mentioned above, -l causes the LCD emulation window to be shown. +* -d + - 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. -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. -To use the default device tree, use -D. To use the test device tree, use -T. +* -T + - 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. +* -c [;] + - 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 ---------------- From 4aed22762303755f8f26d14f0ad2608d63550e72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:26 -0600 Subject: [PATCH 03/14] bloblist: Add a command It is helpful to be able to see basic statistics about the bloblist and also to list its contents. Add a 'bloblist' command to handle this. Put the display functions in the bloblist modules rather than in the command code itself. That allows showing a list from SPL, where commands are not available. Also make bloblist_first/next_blob() static as they are not used outside this file. Signed-off-by: Simon Glass --- cmd/Kconfig | 9 +++++++ cmd/Makefile | 1 + cmd/bloblist.c | 37 +++++++++++++++++++++++++++ common/bloblist.c | 62 +++++++++++++++++++++++++++++++++++++++++++--- include/bloblist.h | 32 ++++++++++++++++++++++++ test/bloblist.c | 59 ++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 cmd/bloblist.c 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 + */ + +#include +#include +#include + +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..c86ea029c8 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -13,15 +13,31 @@ 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; @@ -233,6 +249,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/include/bloblist.h b/include/bloblist.h index 5784c2226e..6c37cd2a63 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 }; /** @@ -206,6 +209,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 * diff --git a/test/bloblist.c b/test/bloblist.c index 4e537ee1b9..cbdc9db4ec 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -231,9 +232,65 @@ 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: %x", map_to_sysmem(hdr)); + ut_assert_nextline("size: 100 256 Bytes"); + ut_assert_nextline("alloced: 70 112 Bytes"); + ut_assert_nextline("free: 90 144 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("%08x %8x 1 EC host event", map_to_sysmem(data), + TEST_SIZE); + ut_assert_nextline("%08x %8x 2 SPL hand-off", 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); + int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { From cdd4e30dfcaba706120df340c0c8757d56e48b7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:27 -0600 Subject: [PATCH 04/14] bloblist: Compare addresses rather than pointers in tests When running these tests on sandbox any failures result in very large or long pointer values which are a pain to work with. Map them to an address so it is easier to diagnose failures. Signed-off-by: Simon Glass --- include/test/ut.h | 13 +++++++++++++ test/bloblist.c | 27 ++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) 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/test/bloblist.c b/test/bloblist.c index cbdc9db4ec..028b0a9383 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -95,26 +95,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); 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; @@ -140,7 +141,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; @@ -164,8 +165,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; } @@ -251,7 +252,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) gd->flags |= GD_FLG_SILENT; console_record_reset(); run_command("bloblist info", 0); - ut_assert_nextline("base: %x", map_to_sysmem(hdr)); + ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); ut_assert_nextline("size: 100 256 Bytes"); ut_assert_nextline("alloced: 70 112 Bytes"); ut_assert_nextline("free: 90 144 Bytes"); @@ -280,10 +281,10 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) console_record_reset(); run_command("bloblist list", 0); ut_assert_nextline("Address Size Tag Name"); - ut_assert_nextline("%08x %8x 1 EC host event", map_to_sysmem(data), - TEST_SIZE); - ut_assert_nextline("%08x %8x 2 SPL hand-off", map_to_sysmem(data2), - TEST_SIZE2); + 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); From 751b7c79634003b4cb326b79e80202ea45b75fc8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:28 -0600 Subject: [PATCH 05/14] bloblist: Tidy up the data alignment The intention which bloblists is that each blob's data is aligned in memory. At present it is only the headers that are aligned. Update the code to correct this and add a little more documentation. Signed-off-by: Simon Glass --- common/bloblist.c | 32 ++++++++++++++++++++++++++------ test/bloblist.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/common/bloblist.c b/common/bloblist.c index c86ea029c8..173f28d8ec 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -11,6 +11,20 @@ #include #include +/* + * 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; static const char *const tag_name[] = { @@ -73,9 +87,14 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) { struct bloblist_hdr *hdr = gd->bloblist; struct bloblist_rec *rec; - int new_alloced; + int data_start, new_alloced; - new_alloced = hdr->alloced + sizeof(*rec) + ALIGN(size, BLOBLIST_ALIGN); + /* Figure out where the new data will start */ + data_start = hdr->alloced + sizeof(*rec); + data_start = ALIGN(data_start, BLOBLIST_ALIGN); + + /* Calculate the new allocated total */ + new_alloced = data_start + 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", @@ -83,15 +102,16 @@ 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; @@ -139,7 +159,7 @@ void *bloblist_add(uint tag, int size) if (bloblist_addrec(tag, size, &rec)) return NULL; - return rec + 1; + return (void *)rec + rec->hdr_size; } int bloblist_ensure_size(uint tag, int size, void **blobp) diff --git a/test/bloblist.c b/test/bloblist.c index 028b0a9383..6853523764 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -29,6 +29,8 @@ enum { TEST_ADDR = CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE = 0x100, + + ERASE_BYTE = '\xff', }; static struct bloblist_hdr *clear_bloblist(void) @@ -41,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; @@ -292,6 +294,40 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) } 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; + 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 alignment */ + for (i = 0; i < 3; i++) { + int size = i * 3; + ulong addr; + char *data; + int j; + + data = bloblist_add(i, size); + 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]); + } + + return 0; +} +BLOBLIST_TEST(bloblist_test_align, 0); + int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { From 4c1497e77661eea47d3dbb9bee029532cc0da198 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:29 -0600 Subject: [PATCH 06/14] bloblist: Allow custom alignment for blobs Some blobs need a larger alignment than the default. For example, ACPI tables often start at a 4KB boundary. Add support for this. Update the size of the test blob to allow these larger records. Signed-off-by: Simon Glass --- arch/x86/cpu/intel_common/acpi.c | 2 +- arch/x86/cpu/intel_common/intel_opregion.c | 2 +- common/bloblist.c | 32 ++++++++++------- include/bloblist.h | 6 ++-- test/bloblist.c | 42 +++++++++++++++++----- 5 files changed, 59 insertions(+), 25 deletions(-) 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/common/bloblist.c b/common/bloblist.c index 173f28d8ec..33b5862380 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -83,18 +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 data_start, new_alloced; + if (!align) + align = BLOBLIST_ALIGN; + /* Figure out where the new data will start */ - data_start = hdr->alloced + sizeof(*rec); - data_start = ALIGN(data_start, BLOBLIST_ALIGN); + 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, BLOBLIST_ALIGN); + new_alloced = data_start + ALIGN(size, align); + if (new_alloced >= hdr->size) { log(LOGC_BLOBLIST, LOGL_ERR, "Failed to allocate %x bytes size=%x, need size=%x\n", @@ -117,7 +124,8 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) 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; @@ -130,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; } @@ -152,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 (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; @@ -179,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; @@ -190,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) diff --git a/include/bloblist.h b/include/bloblist.h index 6c37cd2a63..965d8e9a29 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -132,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 @@ -145,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 diff --git a/test/bloblist.c b/test/bloblist.c index 6853523764..0bb9e2d81e 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -25,10 +25,10 @@ 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', }; @@ -100,7 +100,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) 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_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); @@ -206,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()); @@ -255,9 +255,9 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) console_record_reset(); run_command("bloblist info", 0); ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); - ut_assert_nextline("size: 100 256 Bytes"); + ut_assert_nextline("size: 400 1 KiB"); ut_assert_nextline("alloced: 70 112 Bytes"); - ut_assert_nextline("free: 90 144 Bytes"); + ut_assert_nextline("free: 390 912 Bytes"); ut_assert_console_end(); gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); @@ -298,6 +298,8 @@ BLOBLIST_TEST(bloblist_test_cmd_list, 0); 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 */ @@ -305,14 +307,14 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); - /* Check the alignment */ + /* 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); + data = bloblist_add(i, size, 0); ut_assertnonnull(data); addr = map_to_sysmem(data); ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1)); @@ -324,6 +326,28 @@ static int bloblist_test_align(struct unit_test_state *uts) 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); From e9b6b2c77dd57b591d025f6895a779930a39a5ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:30 -0600 Subject: [PATCH 07/14] bloblist: Fix up a few comments Adjust a few comments to make the meaning clearer. Signed-off-by: Simon Glass --- include/bloblist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bloblist.h b/include/bloblist.h index 965d8e9a29..2b4b669689 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -68,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. @@ -115,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 */ From 45dbe75da6fbc3de280021bf4b5c9dfc94c70f8f Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 23 Sep 2020 08:23:27 +0200 Subject: [PATCH 08/14] dm: ofnode: Fix compile breakage with OF_CHECKS enabled Include missing log.h and change _ofnode_to_np() to ofnode_to_np() so that compiling with OF_CHECKS enabled does not break. Signed-off-by: Stefan Roese Cc: Simon Glass Reviewed-by: Simon Glass --- include/dm/ofnode.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 8df2facf99..d7852daf7f 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -10,6 +10,7 @@ /* TODO(sjg@chromium.org): Drop fdtdec.h include */ #include #include +#include /* 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. * @@ -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); } From 6d9949fe866751c527c5dafab5350af89b7b8332 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 24 Sep 2020 17:26:20 +0200 Subject: [PATCH 09/14] dm: update test on of_offset in ofnode_valid Update the test for node.of_offset because an invalid offset is not always set to -1 because the return value of the libfdt functions are: + an error with a value < 0 + a valid offset with value >=0 For example, in ofnode_get_by_phandle() function, we have: node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, phandle); and this function can return -FDT_ERR_BADPHANDLE (-6). Without this patch, the added test dm_test_ofnode_get_by_phandle failed. Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- include/dm/ofnode.h | 2 +- test/dm/ofnode.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index d7852daf7f..98c64fece3 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -128,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; } /** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 8bfb706602..4ae8d281a7 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"; From 89f68302cacaa41330959420d7329b7c89afdd88 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 25 Sep 2020 09:41:14 +0200 Subject: [PATCH 10/14] dm: add cells_count parameter in *_count_phandle_with_args The cell_count argument is required when cells_name is NULL. This patch adds this parameter in live tree API - of_count_phandle_with_args - ofnode_count_phandle_with_args - dev_count_phandle_with_args This parameter solves issue when these API is used to count the number of element of a cell without cell name. This parameter allow to force the size cell. For example: count = dev_count_phandle_with_args(dev, "array", NULL, 3); Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- board/st/stm32mp1/stm32mp1.c | 2 +- drivers/clk/clk-uclass.c | 4 ++-- drivers/core/of_access.c | 7 ++++--- drivers/core/ofnode.c | 6 +++--- drivers/core/read.c | 5 +++-- drivers/net/designware.c | 3 ++- drivers/phy/phy-uclass.c | 2 +- drivers/power/domain/power-domain-uclass.c | 2 +- drivers/reset/reset-uclass.c | 3 ++- drivers/usb/host/ehci-generic.c | 4 ++-- drivers/usb/host/ohci-da8xx.c | 3 ++- drivers/usb/host/ohci-generic.c | 6 ++++-- include/dm/of_access.h | 4 +++- include/dm/ofnode.h | 3 ++- include/dm/read.h | 8 +++++--- 15 files changed, 37 insertions(+), 25 deletions(-) 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/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/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 98c64fece3..4b7af37056 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -556,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) From cba487c7fc0fea21757cd8dba10271469d5fde9c Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 25 Sep 2020 09:41:15 +0200 Subject: [PATCH 11/14] fdtdec: correct test on return of fdt_node_offset_by_phandle The result of fdt_node_offset_by_phandle is negative for error, so this patch corrects the check of this result in fdtdec_parse_phandle_with_args. This patch allows to have the same behavior with or without OF_LIVE for the function dev_read_phandle_with_args with cell_name = NULL and with invalid phandle. Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- lib/fdtdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)); From cc72f3e026c342e30dcf2848d3a1aeb3d49045b7 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 25 Sep 2020 09:41:16 +0200 Subject: [PATCH 12/14] test: dm: add test for phandle access functions Add unitary test for phandle access functions - ofnode_count_phandle_with_args - ofnode_parse_phandle_with_args - dev_count_phandle_with_args - dev_read_phandle_with_args Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 1 + test/dm/ofnode.c | 75 +++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 65 +++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) 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/test/dm/ofnode.c b/test/dm/ofnode.c index 4ae8d281a7..01ac3c2094 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -103,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) { From c4216219ec5accf831a02f51c37c73e5ad7f4b96 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 29 Sep 2020 01:41:18 +0200 Subject: [PATCH 13/14] sandbox: add missing SDL key scan codes Add missing SDL key scan codes, e.g. * shift, ctrl, meta, alt * brace/bracket Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- arch/sandbox/cpu/sdl.c | 160 +++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 69 deletions(-) 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_KP_MINUS] = KEY_KPMINUS, - [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_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_1] = KEY_KP1, + [SDL_SCANCODE_KP_2] = KEY_KP2, + [SDL_SCANCODE_KP_3] = KEY_KP3, [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) From 175e8322bcee64127a24acdac12c54f5ddb95f82 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 29 Sep 2020 03:56:20 +0200 Subject: [PATCH 14/14] sandbox: avoid duplicate backslash input When using SDL for input the SDL key codes are first converted to Linux key codes and then to matrix entries of the cross wired keyboard. We must not map any key code to two different places on the keyboard. So comment out one backslash position. Update the rest of the file from Linux 5.7. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- arch/sandbox/dts/cros-ec-keyboard.dtsi | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) 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 @@ -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)