From a47a5ba1a15633571ad47e2c8d4f406afdaa221c Mon Sep 17 00:00:00 2001
From: Lukasz Majewski <lukma@denx.de>
Date: Mon, 20 Jan 2025 11:10:48 +0100
Subject: [PATCH] drivers: net: ot: Provide structure instance for HDLC RCP
 context

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 <lukma@denx.de>
---
 drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c  | 6 +++---
 drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c b/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c
index d69420377375..f66af5b349ac 100644
--- a/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c
+++ b/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c
@@ -34,10 +34,10 @@
 #define LOG_LEVEL       CONFIG_HDLC_RCP_IF_DRIVER_LOG_LEVEL
 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
 
-struct ot_hdlc_rcp_context {
+static struct ot_hdlc_rcp_context {
 	struct net_if *iface;
 	struct openthread_context *ot_context;
-};
+} ot_hdlc_rcp_ctx;
 
 /* -------------------------------------------------------------------------- */
 /*                             Private prototypes                             */
@@ -111,7 +111,7 @@ static const struct hdlc_api nxp_hdlc_api = {
 
 NET_DEVICE_DT_INST_DEFINE(0, NULL,                             /* Initialization Function */
 			  NULL,                                /* No PM API support */
-			  NULL,                                /* No context data */
+			  &ot_hdlc_rcp_ctx,                    /* HDLC RCP context data */
 			  NULL,                                /* Configuration info */
 			  CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, /* Initial priority */
 			  &nxp_hdlc_api,                       /* API interface functions */
diff --git a/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c b/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c
index f14f1f792c66..0157f4f36939 100644
--- a/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c
+++ b/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c
@@ -54,10 +54,10 @@ struct openthread_uart {
 OT_UART_DEFINE(ot_uart, CONFIG_OPENTHREAD_HDLC_RCP_IF_UART_RX_RING_BUFFER_SIZE,
 	       CONFIG_OPENTHREAD_HDLC_RCP_IF_UART_TX_RING_BUFFER_SIZE);
 
-struct ot_hdlc_rcp_context {
+static struct ot_hdlc_rcp_context {
 	struct net_if *iface;
 	struct openthread_context *ot_context;
-};
+} ot_hdlc_rcp_ctx;
 
 /* -------------------------------------------------------------------------- */
 /*                             Private functions                              */
@@ -210,7 +210,7 @@ static const struct hdlc_api uart_hdlc_api = {
 
 NET_DEVICE_DT_INST_DEFINE(0, NULL,                             /* Initialization Function */
 			  NULL,                                /* No PM API support */
-			  NULL,                                /* No context data */
+			  &ot_hdlc_rcp_ctx,                    /* HDLC RCP context data */
 			  NULL,                                /* Configuration info */
 			  CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, /* Initial priority */
 			  &uart_hdlc_api,                       /* API interface functions */