Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: net: ot: Provide structure instance for HDLC RCP context #84227

Merged
merged 1 commit into from
Jan 30, 2025

Conversation

lmajewski
Copy link
Collaborator

Without this patch the hdlc_iface_init() function assigns to ot_hdlc_rcp_context structure pointer (*ctx) value of 0, as in the NET_DEVICE_DT_INST_DEFINE() preprocessor macro the 'data' field is set to NULL.

Afterwards, the ctx->iface is set to iface address passed to the function (as well as the ctx->ot_context is set).
Writing those values to address 0x0 is catastrophic to for example mimxrt1020, which uses ITCM memory (mapped from 0x0) to store flash handling functions, as those are used to XIP code directly from SPI NOR memory (as mximxrt1020 doesn't have internal flash).

In this particular case - the flash_flexspi_nor_erase() function is mapped (i.e. relocated) to ITCM's 0x0 address. Overwriting first 8 bytes of it causes the SoC to enter "Precise data bus error" exception.

The fix is to define the static instance of struct ot_hdlc_rcp_context and pass its address to the NET_DEVICE_DT_INST_DEFINE() macro. As a result its storage is now in RAM, not ITCM.

This issue has been discovered on UART based HDLC RCP communication, but as it also may be problematic on the NXP driver, this patch fixes it too.

@zephyrbot zephyrbot added the platform: NXP Drivers NXP Semiconductors, drivers label Jan 20, 2025
@manuargue manuargue removed their request for review January 20, 2025 14:50
@decsny
Copy link
Member

decsny commented Jan 20, 2025

@xavraz

@lmajewski
Copy link
Collaborator Author

Gentle ping on this issue ....

@mmahadevan108
Copy link
Collaborator

@JA-NXP @xavraz can you help take a look at the PR.

dleach02
dleach02 previously approved these changes Jan 27, 2025
@xavraz
Copy link
Contributor

xavraz commented Jan 28, 2025

Hello @lmajewski,
Please, find here, the call stack during the initialisation step :
hdlc_iface_init@0x18014690 (<user_path>\zephyr_downstream\zephyr\drivers\hdlc_rcp_if\hdlc_rcp_if_nxp.c:55)
init_iface@0x1800ef9e (<user_path>\zephyr_downstream\zephyr\subsys\net\ip\net_if.c:446)
net_if_init@0x1800ef9e (<user_path>\zephyr_downstream\zephyr\subsys\net\ip\net_if.c:6162)
init_rx_queues@0x1800c482 (<user_path>\zephyr_downstream\zephyr\subsys\net\ip\net_core.c:585)
net_init@0x1800c482 (<user_path>\zephyr_downstream\zephyr\subsys\net\ip\net_core.c:641)
z_sys_init_run_level@0x1802c0c0 (<user_path>\zephyr_downstream\zephyr\kernel\init.c:371)
bg_thread_main@0x1802c0e0 (<user_path>\zephyr_downstream\zephyr\kernel\init.c:519)
z_thread_entry@0x18005c74 (<user_path>\zephyr_downstream\zephyr\lib\os\thread_entry.c:48)
arch_switch_to_main_thread@0x1800ac9a (<user_path>\zephyr_downstream\zephyr\arch\arm\core\cortex_m\thread.c:575)

There is no problem with the NET_DEVICE_DT_INST_DEFINE macro and the "No context data" field set to NULL as you can see with the previous call stack.

I can understand the static ot_hdlc_rcp_ctx variable instantiation can change the mapping. But the ot_hdlc_rcp_ctx variable is not used in the hdlc_iface_init() function.

Why the following code is not done ?
*struct ot_hdlc_rcp_context ctx = net_if_get_device(iface)->data;
replaced by
*ot_hdlc_rcp_ctx = net_if_get_device(iface)->data;

Thanks

@lmajewski
Copy link
Collaborator Author

lmajewski commented Jan 29, 2025

@xavraz - Thanks for your input.

There is no problem with the NET_DEVICE_DT_INST_DEFINE macro and the "No context data" field set to NULL as you can see with the previous call stack.

IMHO the issue is that you currently have a dereference to the area of memory starting from 0x0, which in case MIMXRT1020 is a valid one and has flash driver code necessary for XIP.

As both hdlc_rcp_if_uart.c and hdlc_rcp_if_nxp.c define struct ot_hdlc_rcp_context structure - it shall be passed as "context data" to NET_DEVICE_DT_INST_DEFINE() macro.

I can understand the static ot_hdlc_rcp_ctx variable instantiation can change the mapping.

There is no instantiation - without this patch the struct ot_hdlc_rcp_context structure is "laid" on 0x0 address and then in hdlc_iface_init() the call to ctx->ot_context = net_if_l2_data(iface); overwrites 4 bytes at 0x0 memory, which on MIMXRT1020 has code for flash erasing function.

But the ot_hdlc_rcp_ctx variable is not used in the hdlc_iface_init() function.

In the hdlc_iface_init() function the pointer (*ctx) to static struct ot_hdlc_rcp_context is used. And for the NET_DEVICE_DT_INST_DEFINE() definition the pointer to instantiated static struct ot_hdlc_rcp_context - in this case pointer to ot_hdlc_rcp_ctx.

Why the following code is not done ?
*struct ot_hdlc_rcp_context ctx = net_if_get_device(iface)->data;

It shall be (as it is now): struct ot_hdlc_rcp_context *ctx = net_if_get_device(iface)->data;

replaced by
*ot_hdlc_rcp_ctx = net_if_get_device(iface)->data;

Is the *ot_hdlc_rcp_ctx valid ?

With the struct ot_hdlc_rcp_context *ctx = net_if_get_device(iface)->data; I've followed Zephyr's paradigm to use pointer - very often - named as ctx. This is also the code used without this patch.

I think that this approach is correct.

@xavraz
Copy link
Contributor

xavraz commented Jan 29, 2025

@lmajewski ,
Thanks for the explanation. The previous /* No context data */ field shall be initialized to the &ot_hdlc_rcp_ctx, you are right.

It would be better to change the comment /* No context data */, now.
image

Proposal :
/* driver context structure address */

Copy link
Contributor

@JA-NXP JA-NXP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment should be updated /* No context data */

Without this patch the hdlc_iface_init() function assigns to
ot_hdlc_rcp_context structure pointer (*ctx) value of 0, as in the
NET_DEVICE_DT_INST_DEFINE() preprocessor macro the 'data' field is
set to NULL.

Afterwards, the ctx->iface is set to iface address passed to the function
(as well as the ctx->ot_context is set).
Writing those values to address 0x0 is catastrophic to for example
mimxrt1020, which uses ITCM memory (mapped from 0x0) to store flash
handling functions, as those are used to XIP code directly from
SPI NOR memory (as mximxrt1020 doesn't have internal flash).

In this particular case - the flash_flexspi_nor_erase() function is mapped
(i.e. relocated) to ITCM's 0x0 address. Overwriting first 8 bytes of it
causes the SoC to enter "Precise data bus error" exception.

The fix is to define the static instance of struct ot_hdlc_rcp_context
and pass its address to the NET_DEVICE_DT_INST_DEFINE() macro. As a result
its storage is now in RAM, not ITCM.

This issue has been discovered on UART based HDLC RCP communication, but as
it also may be problematic on the NXP driver, this patch fixes it too.

Signed-off-by: Lukasz Majewski <[email protected]>
@kartben kartben merged commit d0d68d6 into zephyrproject-rtos:main Jan 30, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: NXP Drivers NXP Semiconductors, drivers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants