Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/releases/release-notes-2.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ interface and listing all issues with the `bug label
API Changes
***********

Deprecated in this release

* :c:macro:`DT_ENUM_TOKEN` and :c:macro:`DT_ENUM_UPPER_TOKEN`,
were deprecated in favor of utilizing
:c:macro:`DT_STRING_TOKEN` and :c:macro:`DT_STRING_UPPER_TOKEN`

Changes in this release

==========================
Expand Down
2 changes: 1 addition & 1 deletion drivers/flash/nrf_qspi_nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ BUILD_ASSERT(INST_0_SCK_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16),
#define QSPI_PROP_LEN(prop) DT_PROP_LEN(QSPI_NODE, prop)

#define INST_0_QER _CONCAT(JESD216_DW15_QER_, \
DT_ENUM_TOKEN(DT_DRV_INST(0), \
DT_STRING_TOKEN(DT_DRV_INST(0), \
quad_enable_requirements))

BUILD_ASSERT(((INST_0_QER == JESD216_DW15_QER_NONE)
Expand Down
23 changes: 23 additions & 0 deletions dts/bindings/reserved-memory/reserved-memory.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
description: |
Reserved memory - Each child of the reserved-memory node specifies one or
more regions of reserved memory. Regions in the /reserved-memory node may be
referenced by other device nodes by adding a memory-region property to the
device node.

compatible: "reserved-memory"

include:
- name: base.yaml
property-allowlist: ['#address-cells', '#size-cells']

child-binding:
description: Regions
properties:
label:
type: string
required: false
description: Human readable string describing the device (used as device_get_binding() argument)
reg:
type: array
description: register space
required: true
116 changes: 114 additions & 2 deletions include/devicetree.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@
*
* _ENUM_IDX: property's value as an index into bindings enum
* _ENUM_TOKEN: property's value as a token into bindings enum (string
* enum values are identifiers)
* _ENUM_UPPER_TOKEN: like _ENUM_TOKEN, but uppercased
* enum values are identifiers) [deprecated, use _STRING_TOKEN]
* _ENUM_UPPER_TOKEN: like _ENUM_TOKEN, but uppercased [deprecated, use
* _STRING_UPPER_TOKEN]
* _EXISTS: property is defined
* _FOREACH_PROP_ELEM: helper for "iterating" over values in the property
* _IDX_<i>: logical index into property
Expand All @@ -54,6 +55,8 @@
* _NAME_<name>_PH: phandle array's phandle by name
* _NAME_<name>_VAL_<val>: phandle array's property specifier by name
* _NAME_<name>_VAL_<val>_EXISTS: cell value exists, by name
* _STRING_TOKEN: string property's value as a token
* _STRING_UPPER_TOKEN: like _STRING_TOKEN, but uppercased
*/

/**
Expand Down Expand Up @@ -701,6 +704,113 @@
COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
(DT_ENUM_IDX(node_id, prop)), (default_idx_value))

/**
* @brief Get a string property's value as a token.
*
* This removes "the quotes" from string-valued properties, and converts
* non-alphanumeric characters to underscores. That can be useful, for example,
* when programmatically using the value to form a C variable or code.
*
* DT_STRING_TOKEN() can only be used for properties with string type.
*
* It is an error to use DT_STRING_TOKEN() in other circumstances.
*
* Example devicetree fragment:
*
* n1: node-1 {
* prop = "foo";
* };
* n2: node-2 {
* prop = "FOO";
* }
* n3: node-3 {
* prop = "123 foo";
* };
*
* Example bindings fragment:
*
* properties:
* prop:
* type: string
*
* Example usage:
*
* DT_STRING_TOKEN(DT_NODELABEL(n1), prop) // foo
* DT_STRING_TOKEN(DT_NODELABEL(n2), prop) // FOO
* DT_STRING_TOKEN(DT_NODELABEL(n3), prop) // 123_foo
*
* Notice how:
*
* - Unlike C identifiers, the property values may begin with a
* number. It's the user's responsibility not to use such values as
* the name of a C identifier.
*
* - The uppercased "FOO" in the DTS remains @p FOO as a token. It is
* *not* converted to @p foo.
*
* - The whitespace in the DTS "123 foo" string is converted to @p
* 123_foo as a token.
*
* @param node_id node identifier
* @param prop lowercase-and-underscores property string name
* @return the value of @p prop as a token, i.e. without any quotes
* and with special characters converted to underscores
*/
#define DT_STRING_TOKEN(node_id, prop) \
DT_CAT4(node_id, _P_, prop, _STRING_TOKEN)

/**
* @brief Like DT_STRING_TOKEN(), but uppercased.
*
* This removes "the quotes and capitalize" from string-valued properties, and
* converts non-alphanumeric characters to underscores. That can be useful, for
* example, when programmatically using the value to form a C variable or code.
*
* DT_STRING_UPPER_TOKEN() can only be used for properties with string type.
*
* It is an error to use DT_STRING_UPPER_TOKEN() in other circumstances.
*
* Example devicetree fragment:
*
* n1: node-1 {
* prop = "foo";
* };
* n2: node-2 {
* prop = "123 foo";
* };
*
* Example bindings fragment:
*
* properties:
* prop:
* type: string
*
* Example usage:
*
* DT_STRING_UPPER_TOKEN(DT_NODELABEL(n1), prop) // FOO
* DT_STRING_UPPER_TOKEN(DT_NODELABEL(n2), prop) // 123_FOO
*
* Notice how:
*
* - Unlike C identifiers, the property values may begin with a
* number. It's the user's responsibility not to use such values as
* the name of a C identifier.
*
* - The lowercased "foo" in the DTS becomes @p FOO as a token, i.e.
* it is uppercased.
*
* - The whitespace in the DTS "123 foo" string is converted to @p
* 123_FOO as a token, i.e. it is uppercased and whitespace becomes
* an underscore.
*
* @param node_id node identifier
* @param prop lowercase-and-underscores property string name
* @return the value of @p prop as a token, i.e. without any quotes
* and with special characters converted to underscores
*/
#define DT_STRING_UPPER_TOKEN(node_id, prop) \
DT_CAT4(node_id, _P_, prop, _STRING_UPPER_TOKEN)

/**
* @brief Get an enumeration property's value as a token.
*
Expand Down Expand Up @@ -763,6 +873,7 @@
* and with special characters converted to underscores
*/
#define DT_ENUM_TOKEN(node_id, prop) \
__DEPRECATED_MACRO \
DT_CAT4(node_id, _P_, prop, _ENUM_TOKEN)

/**
Expand Down Expand Up @@ -822,6 +933,7 @@
* underscores
*/
#define DT_ENUM_UPPER_TOKEN(node_id, prop) \
__DEPRECATED_MACRO \
DT_CAT4(node_id, _P_, prop, _ENUM_UPPER_TOKEN)

/*
Expand Down
139 changes: 139 additions & 0 deletions include/devicetree/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* @file
* @brief reserved-memory Devicetree macro public API header file.
*/

/*
* Copyright (c) 2021 Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
#define ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_

#ifdef __cplusplus
extern "C" {
#endif

/**
* @defgroup devicetree-reserved Devicetree reserved-memory API
* @ingroup devicetree
* @{
*/

/**
* @brief Get the pointer to the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(n)) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @return pointer to the beginning of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_PTR(node_id) _DT_RESERVED_START(node_id)

/**
* @brief Get the size of the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
*
* @param node_id node identifier
* @return the size of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_SIZE(node_id) DT_REG_SIZE(node_id)

/**
* @brief Get the pointer to the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return pointer to the beginning of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
DT_RESERVED_MEM_GET_PTR(DT_PHANDLE(node_id, ph))

/**
* @brief Get the size of the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return size of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))

/**
* @}
*/

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_ */
59 changes: 59 additions & 0 deletions include/linker/devicetree_reserved.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2021, Carlo Caione <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*
* Generate memory regions and sections from reserved-memory nodes.
*/

#include <devicetree.h>

/* Reserved memory node */
#define _NODE_RESERVED DT_INST(0, reserved_memory)

/* Unquoted region label */
#define _DT_LABEL_TOKEN(res) DT_STRING_TOKEN(res, label)

/* _start and _end section symbols */
#define _DT_RESERVED_PREFIX(res) UTIL_CAT(__, _DT_LABEL_TOKEN(res))
#define _DT_RESERVED_START(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _start)
#define _DT_RESERVED_END(res) UTIL_CAT(_DT_RESERVED_PREFIX(res), _end)

/* Declare a reserved memory region */
#define _RESERVED_REGION_DECLARE(res) DT_STRING_TOKEN(res, label) (rw) : \
ORIGIN = DT_REG_ADDR(res), \
LENGTH = DT_REG_SIZE(res)

/* Declare a reserved memory section */
#define _RESERVED_SECTION_DECLARE(res) SECTION_DATA_PROLOGUE(_DT_LABEL_TOKEN(res), ,) \
{ \
_DT_RESERVED_START(res) = .; \
KEEP(*(._DT_LABEL_TOKEN(res))) \
KEEP(*(._DT_LABEL_TOKEN(res).*)) \
_DT_RESERVED_END(res) = \
_DT_RESERVED_START(res) + DT_REG_SIZE(res); \
} GROUP_LINK_IN(_DT_LABEL_TOKEN(res))

/* Declare reserved memory linker symbols */
#define _RESERVED_SYMBOL_DECLARE(res) extern char _DT_RESERVED_START(res)[]; \
extern char _DT_RESERVED_END(res)[];

/* Apply a macro to a reserved memory region */
#define _RESERVED_REGION_APPLY(f) \
COND_CODE_1(IS_ENABLED(UTIL_CAT(_NODE_RESERVED, _EXISTS)), \
(DT_FOREACH_CHILD(_NODE_RESERVED, f)), ())

/**
* @brief Generate region definitions for all the reserved memory regions
*/
#define DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)

/**
* @brief Generate section definitions for all the reserved memory regions
*/
#define DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)

/**
* @brief Generate linker script symbols for all the reserved memory regions
*/
#define DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)
Loading