diff --git a/dts/bindings/test/vnd,reg-holder-64.yaml b/dts/bindings/test/vnd,reg-holder-64.yaml new file mode 100644 index 00000000000000..0e0800e784b281 --- /dev/null +++ b/dts/bindings/test/vnd,reg-holder-64.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Syntacore +# SPDX-License-Identifier: Apache-2.0 + +description: Test 64-bit register property container + +compatible: "vnd,reg-holder-64" + +include: [base.yaml] + +properties: + reg: + required: true + + reg-names: + required: true diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index ed8db9edfc7095..c9aab6653431b7 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -18,6 +18,10 @@ #include +#if !defined(_LINKER) && !defined(_ASMLANGUAGE) +#include +#endif + #include /** @@ -2219,6 +2223,18 @@ */ #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0) +/** + * @brief 64-bit version of DT_REG_ADDR() + * + * This macro version adds the appropriate suffix for 64-bit unsigned + * integer literals. + * Note that this macro is equivalent to DT_REG_ADDR() in linker/ASM context. + * + * @param node_id node identifier + * @return node's register block address + */ +#define DT_REG_ADDR_U64(node_id) DT_U64_C(DT_REG_ADDR(node_id)) + /** * @brief Get a node's (only) register block size * @@ -2237,6 +2253,21 @@ #define DT_REG_ADDR_BY_NAME(node_id, name) \ DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS) +/** + * @brief 64-bit version of DT_REG_ADDR_BY_NAME() + * + * This macro version adds the appropriate suffix for 64-bit unsigned + * integer literals. + * Note that this macro is equivalent to DT_REG_ADDR_BY_NAME() in + * linker/ASM context. + * + * @param node_id node identifier + * @param name lowercase-and-underscores register specifier name + * @return address of the register block specified by name + */ +#define DT_REG_ADDR_BY_NAME_U64(node_id, name) \ + DT_U64_C(DT_REG_ADDR_BY_NAME(node_id, name)) + /** * @brief Get a register block's size by name * @param node_id node identifier @@ -3681,6 +3712,21 @@ #define DT_INST_REG_ADDR_BY_NAME(inst, name) \ DT_REG_ADDR_BY_NAME(DT_DRV_INST(inst), name) +/** + * @brief 64-bit version of DT_INST_REG_ADDR_BY_NAME() + * + * This macro version adds the appropriate suffix for 64-bit unsigned + * integer literals. + * Note that this macro is equivalent to DT_INST_REG_ADDR_BY_NAME() in + * linker/ASM context. + * + * @param inst instance number + * @param name lowercase-and-underscores register specifier name + * @return address of the register block with the given @p name + */ +#define DT_INST_REG_ADDR_BY_NAME_U64(inst, name) \ + DT_U64_C(DT_INST_REG_ADDR_BY_NAME(inst, name)) + /** * @brief Get a `DT_DRV_COMPAT`'s register block size by name * @param inst instance number @@ -3697,6 +3743,19 @@ */ #define DT_INST_REG_ADDR(inst) DT_INST_REG_ADDR_BY_IDX(inst, 0) +/** + * @brief 64-bit version of DT_INST_REG_ADDR() + * + * This macro version adds the appropriate suffix for 64-bit unsigned + * integer literals. + * Note that this macro is equivalent to DT_INST_REG_ADDR() in + * linker/ASM context. + * + * @param inst instance number + * @return instance's register block address + */ +#define DT_INST_REG_ADDR_U64(inst) DT_U64_C(DT_INST_REG_ADDR(inst)) + /** * @brief Get a `DT_DRV_COMPAT`'s (only) register block size * @param inst instance number @@ -4172,6 +4231,16 @@ #define DT_INST_NODE_HAS_PROP_AND_OR(inst, prop) \ DT_INST_NODE_HAS_PROP(inst, prop) || +/** + * @def DT_U64_C + * @brief Macro to add ULL postfix to the devicetree address constants + */ +#if defined(_LINKER) || defined(_ASMLANGUAGE) +#define DT_U64_C(_v) (_v) +#else +#define DT_U64_C(_v) UINT64_C(_v) +#endif + /** @endcond */ /* have these last so they have access to all previously defined macros */ diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 0a915b1f31ff9a..49c71263740ace 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -621,4 +621,16 @@ val = "XA XPLUS XB", "XC XPLUS XD", "XA XMINUS XB", "XC XMINUS XD"; }; }; + + test_64 { + #address-cells = < 2 >; + #size-cells = < 0 >; + + test_reg_64: reg-holder-64@ffffffff11223344 { + compatible = "vnd,reg-holder-64"; + reg = < 0xffffffff 0x11223344>; + status = "okay"; + reg-names = "test_name"; + }; + }; }; diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 55c92fdc9de508..d173e3357f255e 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -39,6 +39,7 @@ #define TEST_VENDOR DT_NODELABEL(test_vendor) #define TEST_MODEL DT_NODELABEL(test_vendor) #define TEST_ENUM_0 DT_NODELABEL(test_enum_0) +#define TEST_64BIT DT_NODELABEL(test_reg_64) #define TEST_I2C DT_NODELABEL(test_i2c) #define TEST_I2C_DEV DT_PATH(test, i2c_11112222, test_i2c_dev_10) @@ -546,6 +547,9 @@ ZTEST(devicetree_api, test_reg) /* DT_REG_ADDR */ zassert_equal(DT_REG_ADDR(TEST_ABCD1234), 0xabcd1234, ""); + /* DT_REG_ADDR_U64 */ + zassert_equal(DT_REG_ADDR_U64(TEST_ABCD1234), 0xabcd1234, ""); + /* DT_REG_SIZE */ zassert_equal(DT_REG_SIZE(TEST_ABCD1234), 0x500, ""); @@ -553,6 +557,10 @@ ZTEST(devicetree_api, test_reg) zassert_equal(DT_REG_ADDR_BY_NAME(TEST_ABCD1234, one), 0xabcd1234, ""); zassert_equal(DT_REG_ADDR_BY_NAME(TEST_ABCD1234, two), 0x98765432, ""); + /* DT_REG_ADDR_BY_NAME_U64 */ + zassert_equal(DT_REG_ADDR_BY_NAME_U64(TEST_ABCD1234, one), 0xabcd1234, ""); + zassert_equal(DT_REG_ADDR_BY_NAME_U64(TEST_ABCD1234, two), 0x98765432, ""); + /* DT_REG_SIZE_BY_NAME */ zassert_equal(DT_REG_SIZE_BY_NAME(TEST_ABCD1234, one), 0x500, ""); zassert_equal(DT_REG_SIZE_BY_NAME(TEST_ABCD1234, two), 0xff, ""); @@ -576,6 +584,9 @@ ZTEST(devicetree_api, test_reg) /* DT_INST_REG_ADDR */ zassert_equal(DT_INST_REG_ADDR(0), 0x9999aaaa, ""); + /* DT_INST_REG_ADDR_U64 */ + zassert_equal(DT_INST_REG_ADDR_U64(0), 0x9999aaaa, ""); + /* DT_INST_REG_SIZE */ zassert_equal(DT_INST_REG_SIZE(0), 0x1000, ""); @@ -583,11 +594,32 @@ ZTEST(devicetree_api, test_reg) zassert_equal(DT_INST_REG_ADDR_BY_NAME(0, first), 0x9999aaaa, ""); zassert_equal(DT_INST_REG_ADDR_BY_NAME(0, second), 0xbbbbcccc, ""); + /* DT_INST_REG_ADDR_BY_NAME_U64 */ + zassert_equal(DT_INST_REG_ADDR_BY_NAME_U64(0, first), 0x9999aaaa, ""); + zassert_equal(DT_INST_REG_ADDR_BY_NAME_U64(0, second), 0xbbbbcccc, ""); + /* DT_INST_REG_SIZE_BY_NAME */ zassert_equal(DT_INST_REG_SIZE_BY_NAME(0, first), 0x1000, ""); zassert_equal(DT_INST_REG_SIZE_BY_NAME(0, second), 0x3f, ""); } +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT vnd_reg_holder_64 +ZTEST(devicetree_api, test_reg_64) +{ + /* DT_REG_ADDR_U64 */ + zassert_equal(DT_REG_ADDR_U64(TEST_64BIT), 0xffffffff11223344, ""); + + /* DT_REG_ADDR_BY_NAME_U64 */ + zassert_equal(DT_REG_ADDR_BY_NAME_U64(TEST_64BIT, test_name), 0xffffffff11223344, ""); + + /* DT_INST_REG_ADDR_U64 */ + zassert_equal(DT_INST_REG_ADDR_U64(0), 0xffffffff11223344, ""); + + /* DT_INST_REG_ADDR_BY_NAME_U64 */ + zassert_equal(DT_INST_REG_ADDR_BY_NAME_U64(0, test_name), 0xffffffff11223344, ""); +} + #undef DT_DRV_COMPAT #define DT_DRV_COMPAT vnd_interrupt_holder ZTEST(devicetree_api, test_irq)