devicetree_regions: Fix fallback on token

Fix the wrong fallback on token and add a new test to catch this kind of
errors early.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2022-03-31 14:27:14 +02:00 committed by Marti Bolivar
commit cd51657ed1
7 changed files with 173 additions and 16 deletions

View file

@ -8,13 +8,14 @@
*/
/**
* @brief Get the linker memory-region name
* @brief Get the linker memory-region name in a token form
*
* This attempts to use the zephyr,memory-region property (with
* non-alphanumeric characters replaced with underscores).
* non-alphanumeric characters replaced with underscores) returning a token.
*
* Example devicetree fragment:
*
* @code{.dts}
* / {
* soc {
* sram1: memory@2000000 {
@ -25,23 +26,60 @@
* };
* };
* };
* @endcode
*
* Example usage:
*
* @code{.c}
* LINKER_DT_NODE_REGION_NAME_TOKEN(DT_NODELABEL(sram1)) // MY_NAME
* LINKER_DT_NODE_REGION_NAME_TOKEN(DT_NODELABEL(sram2)) // MY_OTHER_NAME
* @endcode
*
* @param node_id node identifier
* @return the name of the memory memory region the node will generate
*/
#define LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
DT_STRING_TOKEN(node_id, zephyr_memory_region)
/**
* @brief Get the linker memory-region name
*
* This attempts to use the zephyr,memory-region property (with
* non-alphanumeric characters replaced with underscores).
*
* Example devicetree fragment:
*
* @code{.dts}
* / {
* soc {
* sram1: memory@2000000 {
* zephyr,memory-region = "MY_NAME";
* };
* sram2: memory@2001000 {
* zephyr,memory-region = "MY@OTHER@NAME";
* };
* };
* };
* @endcode
*
* Example usage:
*
* @code{.c}
* LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram1)) // "MY_NAME"
* LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram2)) // "MY_OTHER_NAME"
* @endcode
*
* @param node_id node identifier
* @return the name of the memory memory region the node will generate
*/
#define LINKER_DT_NODE_REGION_NAME(node_id) \
DT_STRING_TOKEN(node_id, zephyr_memory_region)
STRINGIFY(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
/** @cond INTERNAL_HIDDEN */
#define _DT_COMPATIBLE zephyr_memory_region
#define _DT_SECTION_PREFIX(node_id) UTIL_CAT(__, LINKER_DT_NODE_REGION_NAME(node_id))
#define _DT_SECTION_PREFIX(node_id) UTIL_CAT(__, LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))
#define _DT_SECTION_START(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _start)
#define _DT_SECTION_END(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _end)
#define _DT_SECTION_SIZE(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _size)
@ -50,11 +88,27 @@
/**
* @brief Declare a memory region
*
* Example devicetree fragment:
*
* @code{.dts}
* test_sram: sram@20010000 {
* compatible = "zephyr,memory-region", "mmio-sram";
* reg = < 0x20010000 0x1000 >;
* zephyr,memory-region = "FOOBAR";
* };
* @endcode
*
* will result in:
*
* @code{.unparsed}
* FOOBAR (rw) : ORIGIN = (0x20010000), LENGTH = (0x1000)
* @endcode
*
* @param node_id devicetree node identifier
* @param attr region attributes
*/
#define _REGION_DECLARE(node_id) \
LINKER_DT_NODE_REGION_NAME(node_id) : \
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) : \
ORIGIN = DT_REG_ADDR(node_id), \
LENGTH = DT_REG_SIZE(node_id)
@ -62,18 +116,42 @@
* @brief Declare a memory section from the device tree nodes with
* compatible 'zephyr,memory-region'
*
* Example devicetree fragment:
*
* @code{.dts}
* test_sram: sram@20010000 {
* compatible = "zephyr,memory-region", "mmio-sram";
* reg = < 0x20010000 0x1000 >;
* zephyr,memory-region = "FOOBAR";
* };
* @endcode
*
* will result in:
*
* @code{.unparsed}
* FOOBAR 0x20010000 (NOLOAD) :
* {
* __FOOBAR_start = .;
* KEEP(*(FOOBAR))
* KEEP(*(FOOBAR.*))
* __FOOBAR_end = .;
* } > FOOBAR
* __FOOBAR_size = __FOOBAR_end - __FOOBAR_start;
* __FOOBAR_load_start = LOADADDR(FOOBAR);
* @endcode
*
* @param node_id devicetree node identifier
*/
#define _SECTION_DECLARE(node_id) \
LINKER_DT_NODE_REGION_NAME(node_id) DT_REG_ADDR(node_id) (NOLOAD) : \
LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) DT_REG_ADDR(node_id) (NOLOAD) : \
{ \
_DT_SECTION_START(node_id) = .; \
KEEP(*(LINKER_DT_NODE_REGION_NAME(node_id))) \
KEEP(*(LINKER_DT_NODE_REGION_NAME(node_id).*)) \
KEEP(*(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id))) \
KEEP(*(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id).*)) \
_DT_SECTION_END(node_id) = .; \
} > LINKER_DT_NODE_REGION_NAME(node_id) \
} > LINKER_DT_NODE_REGION_NAME_TOKEN(node_id) \
_DT_SECTION_SIZE(node_id) = _DT_SECTION_END(node_id) - _DT_SECTION_START(node_id); \
_DT_SECTION_LOAD(node_id) = LOADADDR(LINKER_DT_NODE_REGION_NAME(node_id));
_DT_SECTION_LOAD(node_id) = LOADADDR(LINKER_DT_NODE_REGION_NAME_TOKEN(node_id));
/** @endcond */

View file

@ -17,10 +17,8 @@
static void test_linker_regions(void)
{
zassert_true(!strcmp(STRINGIFY(LINKER_DT_NODE_REGION_NAME(TEST_SRAM1)),
"SRAM_REGION"), "");
zassert_true(!strcmp(STRINGIFY(LINKER_DT_NODE_REGION_NAME(TEST_SRAM2)),
"SRAM_REGION_2"), "");
zassert_true(!strcmp(LINKER_DT_NODE_REGION_NAME(TEST_SRAM1), "SRAM_REGION"), "");
zassert_true(!strcmp(LINKER_DT_NODE_REGION_NAME(TEST_SRAM2), "SRAM_REGION_2"), "");
}
void test_main(void)

View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(memory_region)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2022, Carlo Caione <ccaione@baylibre.com>
*/
/ {
test {
#address-cells = < 0x1 >;
#size-cells = < 0x1 >;
test_sram: sram@20010000 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = < 0x20010000 0x1000 >;
zephyr,memory-region = "SRAM_REGION";
};
};
};

View file

@ -0,0 +1 @@
CONFIG_ZTEST=y

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <devicetree.h>
#include <device.h>
#include <linker/devicetree_regions.h>
#define TEST_SRAM_NODE DT_NODELABEL(test_sram)
#define TEST_SRAM_SECT LINKER_DT_NODE_REGION_NAME(TEST_SRAM_NODE)
#define TEST_SRAM_ADDR DT_REG_ADDR(TEST_SRAM_NODE)
#define TEST_SRAM_SIZE DT_REG_SIZE(TEST_SRAM_NODE)
uint8_t var_in_test_sram[TEST_SRAM_SIZE] Z_GENERIC_SECTION(TEST_SRAM_SECT);
extern char __SRAM_REGION_start[];
extern char __SRAM_REGION_end[];
extern char __SRAM_REGION_size[];
extern char __SRAM_REGION_load_start[];
static void test_memory_region(void)
{
zassert_true(!strcmp(LINKER_DT_NODE_REGION_NAME(TEST_SRAM_NODE), "SRAM_REGION"), "");
zassert_equal_ptr(var_in_test_sram, TEST_SRAM_ADDR, "");
zassert_equal_ptr(__SRAM_REGION_start, TEST_SRAM_ADDR, "");
zassert_equal_ptr(__SRAM_REGION_end, TEST_SRAM_ADDR + TEST_SRAM_SIZE, "");
zassert_equal_ptr(__SRAM_REGION_load_start, TEST_SRAM_ADDR, "");
zassert_equal((unsigned long) __SRAM_REGION_size, TEST_SRAM_SIZE, "");
}
void test_main(void)
{
ztest_test_suite(devicetree_memory_region,
ztest_unit_test(test_memory_region)
);
ztest_run_test_suite(devicetree_memory_region);
}

View file

@ -0,0 +1,11 @@
tests:
libraries.devicetree.memory_region:
platform_allow: qemu_cortex_m3
tags: devicetree
libraries.devicetree.memory_region.linker_generator:
platform_allow: qemu_cortex_m3
tags: devicetree
extra_configs:
- CONFIG_CMAKE_LINKER_GENERATOR=y