Re: Runtime Loader Exported Symbols Address Size

2022-06-17 Thread Chris Johns
On 18/6/22 10:08 am, Joel Sherrill wrote:
> On Fri, Jun 17, 2022, 2:28 PM Alex White  > wrote:
> 
> Hi,
> 
> While testing libdl on AArch64 QEMU, we found a bug where the exported
> symbol table appears to always use 32-bit values for addresses, but where
> the exported symbols table is read in `rtems_rtl_symbol_global_add`, the
> addresses are expected to be of size `sizeof(unsigned long)`.
> 
> This did not cause a problem on ARM since `sizeof(unsigned long)` is 4, 
> but
> with AArch64 `sizeof(unsigned long)` is 8. So it is trying to read the
> address as 64 bits instead of 32.
> 
> The simple fix is to use an exact-width integer type - like
> `sizeof(uint32_t)`. But this would not allow for 64-bit architectures to 
> use
> the full address space. It would also break on 64-bit RISC-V (see below).
> Perhaps we could have an ifdef to choose a 32 or 64-bit type based on the
> architecture rather than relying on `sizeof(unsigned long)`?
> 
> It looks like there is an exception in the rtems-syms tool for 64-bit 
> RISC-V
> to emit 64-bit addresses rather than 32-bit addresses. Is this the right
> solution? Should we add another exception for AArch64?
> 
> After having given this some thought, I think the code that is generated and 
> the
> parsing code in rtl-sym.c should be conditionalized on the GCC CPP predefine
> that indicates the size of a void *.

Good idea. The symbol value is held as a `void*` in the symbol table so the key
is the generated asm size in rtems-syms.cpp matches the runtime `void*` size.
That code maybe conditional on the size selecting the correct variable size.

> The code in rtl-sym.c should use a type definition for the type that the 
> sizeof
> is operating on. Using unsigned long is just not good enough. Both cases 
> should
> be fixed width types.

Sure `unsigned long` may not be the best type to use. It was selected because it
happened change size with the arch but I am sure there are types that are better
suited. The type needs to be the size of a full address space pointer.

> There also should be a very good comment above the parsing method in rtl-sym.c
> explaining where the file comes from that it is reading and why there is the
> need for a type which varies by architecture.

Sure, happy to see comments added. Is this something you would like me to 
handle?

The generation and source of the symbols can be handled in a number of ways. I
have provided a tool that should cover most use cases however I can imagine
more, eg symbol filters for defined exported symbols. I documented things here:

https://docs.rtems.org/branches/master/user/exe/loader.html#base-image-symbols

Does that documentation help cover what you are looking for?

> Based on our current understanding, I think this address is everything and
> leaves sufficient information and organization to cover all the cases in the
> future. Very likely without anyone actively having to fix anything. Running 
> into
> this issue again and again as architectures are added is not a good long-term
> solution.

Agreed. Figuring out stable 64bit addressing in libdl is a good idea and
welcome. I think the main requirement is for the full address range to be 
supported.

> Chris.. is this a good path to you? 

Yes this sounds good.

> Is there somewhere else in the dynamic loader system with a similar issue?

This is the only external interface of this type where static checking does not
help. The other is ELF which I hope is OK. I am not sure if other places may
have a problem. All care was taken however only using the code with 64bits will
determine this.

The elftools libelf support was ported and tested with only 32bit targets. I am
not sure if there are issues there.

Chris
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


Re: Runtime Loader Exported Symbols Address Size

2022-06-17 Thread Joel Sherrill
On Fri, Jun 17, 2022, 2:28 PM Alex White  wrote:

> Hi,
>
> While testing libdl on AArch64 QEMU, we found a bug where the exported
> symbol table appears to always use 32-bit values for addresses, but where
> the exported symbols table is read in `rtems_rtl_symbol_global_add`, the
> addresses are expected to be of size `sizeof(unsigned long)`.
>
> This did not cause a problem on ARM since `sizeof(unsigned long)` is 4,
> but with AArch64 `sizeof(unsigned long)` is 8. So it is trying to read the
> address as 64 bits instead of 32.
>
> The simple fix is to use an exact-width integer type - like
> `sizeof(uint32_t)`. But this would not allow for 64-bit architectures to
> use the full address space. It would also break on 64-bit RISC-V (see
> below). Perhaps we could have an ifdef to choose a 32 or 64-bit type based
> on the architecture rather than relying on `sizeof(unsigned long)`?
>
> It looks like there is an exception in the rtems-syms tool for 64-bit
> RISC-V to emit 64-bit addresses rather than 32-bit addresses. Is this the
> right solution? Should we add another exception for AArch64?
>

After having given this some thought, I think the code that is generated
and the parsing code in rtl-sym.c should be conditionalized on the GCC CPP
predefine that indicates the size of a void *.

The code in rtl-sym.c should use a type definition for the type that the
sizeof is operating on. Using unsigned long is just not good enough. Both
cases should be fixed width types.

There also should be a very good comment above the parsing method in
rtl-sym.c explaining where the file comes from that it is reading and why
there is the need for a type which varies by architecture.

Based on our current understanding, I think this address is everything and
leaves sufficient information and organization to cover all the cases in
the future. Very likely without anyone actively having to fix anything.
Running into this issue again and again as architectures are added is not a
good long-term solution.

Chris.. is this a good path to you? Is there somewhere else in the dynamic
loader system with a similar issue?

--joel

>
> Thanks,
>
> Alex
> ___
> devel mailing list
> devel@rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Runtime Loader Exported Symbols Address Size

2022-06-17 Thread Alex White
Hi,

While testing libdl on AArch64 QEMU, we found a bug where the exported symbol 
table appears to always use 32-bit values for addresses, but where the exported 
symbols table is read in `rtems_rtl_symbol_global_add`, the addresses are 
expected to be of size `sizeof(unsigned long)`.

This did not cause a problem on ARM since `sizeof(unsigned long)` is 4, but 
with AArch64 `sizeof(unsigned long)` is 8. So it is trying to read the address 
as 64 bits instead of 32.

The simple fix is to use an exact-width integer type - like `sizeof(uint32_t)`. 
But this would not allow for 64-bit architectures to use the full address 
space. It would also break on 64-bit RISC-V (see below). Perhaps we could have 
an ifdef to choose a 32 or 64-bit type based on the architecture rather than 
relying on `sizeof(unsigned long)`?

It looks like there is an exception in the rtems-syms tool for 64-bit RISC-V to 
emit 64-bit addresses rather than 32-bit addresses. Is this the right solution? 
Should we add another exception for AArch64?

Thanks,

Alex
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


Re: [PATCH 3/5] bsps/stm32h7: allow config and usage of QSPI memory on stm32h757i-eval BSP

2022-06-17 Thread Karel Gardas

On 6/15/22 17:05, Gedare Bloom wrote:

+#endif
+
+void stm32h7_init_qspi(void)


Also, is this function declared somewhere?

Probably what you should do is to add this function declaration to
stm32h747i_eval_qspi.h, and include that file here always?


Yes, it is in bsps/arm/stm32h7/include/bsp.h:

[...]
/* default functions */
void stm32h7_init_power(void);
void stm32h7_init_oscillator(void);
void stm32h7_init_clocks(void);
void stm32h7_init_peripheral_clocks(void);
void stm32h7_init_qspi(void);
[...]

I think it should stay there instead of being moved into ST Micro code.

Karel
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


Re: [PATCH 3/5] bsps/stm32h7: allow config and usage of QSPI memory on stm32h757i-eval BSP

2022-06-17 Thread Karel Gardas

On 6/15/22 17:00, Gedare Bloom wrote:

On Fri, Jun 10, 2022 at 6:49 AM Karel Gardas  wrote:


The QSPI memory is initialized and used only when the BSP configure file
sets QSPI memory size to non-zero value. Currently QSPI is run in memory
mapped mode which allows future RTEMS binary linkage and upload into QSPI
memory.

Sponsored-By:   Precidata
---
  .../stm/stm32h757i-eval/stm32h7-bspstarthooks.c | 17 +
  bsps/arm/stm32h7/include/bsp.h  |  1 +
  .../bsps/arm/stm32h7/bspstm32h757i-eval.yml |  5 -
  spec/build/bsps/arm/stm32h7/optmemquadspisz.yml |  1 +
  4 files changed, 23 insertions(+), 1 deletion(-)

diff --git 
a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c 
b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
index 8d34e357ee..9916b740ce 100644
--- a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
+++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
@@ -36,6 +36,22 @@

  #include 

+#if defined(STM32H7_MEMORY_QUADSPI_SIZE) && STM32H7_MEMORY_QUADSPI_SIZE > 0
+#include 
+BSP_QSPI_Init_t QSPinit;


Do you need this variable to be in the global namespace? Can it be a
static variable here?


I've just resent patch version just for 757i-eval to make review simpler 
where I've switch to static variable here. It has its own pros/cons:


+ not populating global namespace
+ not require explicit initialization
- require to be used after BSS is initialized

So it's really a question what is prefefrred way here.

Thanks,
Karel
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


[PATCH 3/5] bsps/stm32h7: allow config and usage of QSPI memory on stm32h757i-eval BSP

2022-06-17 Thread Karel Gardas
The QSPI memory is initialized and used only when the BSP configure file
sets QSPI memory size to non-zero value. Currently QSPI is run in memory
mapped mode which allows future RTEMS binary linkage and upload into QSPI
memory.

Sponsored-By:   Precidata
---
 .../stm/stm32h757i-eval/stm32h7-bspstarthooks.c | 17 +
 bsps/arm/stm32h7/include/bsp.h  |  1 +
 .../bsps/arm/stm32h7/bspstm32h757i-eval.yml |  5 -
 spec/build/bsps/arm/stm32h7/optmemquadspisz.yml |  1 +
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git 
a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c 
b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
index 8d34e357ee..1bb81e3b60 100644
--- a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
+++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
@@ -36,6 +36,22 @@
 
 #include 
 
+#include 
+static BSP_QSPI_Init_t QSPinit;
+
+void stm32h7_init_qspi(void)
+{
+#if defined(STM32H7_MEMORY_QUADSPI_SIZE) && STM32H7_MEMORY_QUADSPI_SIZE > 0
+/* let's initialize Quad SPI memory here for memory mapped mode */
+/* due to usage of static QSPinit variable please call this function
+   after bsp_start_clear_bss call since otherwise you would hit 
uninitialized
+   variable memory while accessing it and in addition the call to 
bsp_start_clear_bss
+   would wipe the variable content later after its initialization here. */
+BSP_QSPI_Init(0, &QSPinit);
+BSP_QSPI_EnableMemoryMappedMode(0);
+#endif
+}
+
 void bsp_start_hook_0(void)
 {
   if ((RCC->AHB3ENR & RCC_AHB3ENR_FMCEN) == 0) {
@@ -75,4 +91,5 @@ void bsp_start_hook_1(void)
   SCB_InvalidateICache();
 #endif
   bsp_start_clear_bss();
+  stm32h7_init_qspi();
 }
diff --git a/bsps/arm/stm32h7/include/bsp.h b/bsps/arm/stm32h7/include/bsp.h
index 08311bf51e..cd4d25c069 100644
--- a/bsps/arm/stm32h7/include/bsp.h
+++ b/bsps/arm/stm32h7/include/bsp.h
@@ -62,6 +62,7 @@ void stm32h7_init_power(void);
 void stm32h7_init_oscillator(void);
 void stm32h7_init_clocks(void);
 void stm32h7_init_peripheral_clocks(void);
+void stm32h7_init_qspi(void);
 
 /** @} */
 
diff --git a/spec/build/bsps/arm/stm32h7/bspstm32h757i-eval.yml 
b/spec/build/bsps/arm/stm32h7/bspstm32h757i-eval.yml
index 5d7ee1348d..7516e55a3f 100644
--- a/spec/build/bsps/arm/stm32h7/bspstm32h757i-eval.yml
+++ b/spec/build/bsps/arm/stm32h7/bspstm32h757i-eval.yml
@@ -8,7 +8,8 @@ copyrights:
 cppflags: []
 enabled-by: true
 family: stm32h7
-includes: []
+includes:
+- bsps/arm/stm32h7/boards/stm/stm32h757i-eval
 install: []
 links:
 - role: build-dependency
@@ -16,6 +17,8 @@ links:
 - role: build-dependency
   uid: tststm32h757i-eval
 source:
+- bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.c
+- bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.c
 - bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c
 - bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-clk.c
 - bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-osc.c
diff --git a/spec/build/bsps/arm/stm32h7/optmemquadspisz.yml 
b/spec/build/bsps/arm/stm32h7/optmemquadspisz.yml
index 11e5f943e0..9337610b45 100644
--- a/spec/build/bsps/arm/stm32h7/optmemquadspisz.yml
+++ b/spec/build/bsps/arm/stm32h7/optmemquadspisz.yml
@@ -1,6 +1,7 @@
 actions:
 - get-integer: null
 - env-assign: null
+- define-unquoted: null
 build-type: option
 default: 0
 default-by-variant: []
-- 
2.25.1

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


[PATCH 2/5] bsps/stm32h7: import stm32h757i-eval QSPI memory high-level driver

2022-06-17 Thread Karel Gardas
Sponsored-By:   Precidata
---
 .../stm32h757i-eval/stm32h747i_eval_conf.h|  130 ++
 .../stm32h757i-eval/stm32h747i_eval_errno.h   |  105 ++
 .../stm32h757i-eval/stm32h747i_eval_qspi.c| 1088 +
 .../stm32h757i-eval/stm32h747i_eval_qspi.h|  284 +
 4 files changed, 1607 insertions(+)
 create mode 100644 
bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h
 create mode 100644 
bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_errno.h
 create mode 100644 
bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.c
 create mode 100644 
bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.h

diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h 
b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h
new file mode 100644
index 00..673125eec3
--- /dev/null
+++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/** 
+  
**
+  * @filestm32h747i_eval_config.h
+  * @author  MCD Application Team
+  * @brief   STM32H747I_EVAL board configuration file.
+  
**
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  
**
+  */
+/*
+ * RTEMS committer clarification comment on license above:
+ *
+ * This file comes from STM32CubeH7 project and is located here:
+ * 
https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-EVAL/stm32h747i_eval_conf_template.h
+ *
+ * The file root directory is:
+ * 
https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL
+ *
+ * This directory contains LICENSE.md file with a following license text:
+ *
+ * Copyright 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation 
and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its 
contributors
+ * may be used to endorse or promote products derived from this software 
without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+  
+/* Define to prevent recursive inclusion 
-*/
+#ifndef STM32H747I_EVAL_CONFIG_H
+#define STM32H747I_EVAL_CONFIG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes 
--*/
+#include "stm32h7xx_hal.h"
+
+   /* COM define */
+#define USE_COM_LOG 0U
+   
+   /* IO class usage define */  
+#define USE_BSP_IO_CLASS1U
+   
+   /* JOY usage define */
+#define USE_BSP_JOY_FEATURE 1U
+   
+   /* POT usage define */   
+#define USE_BSP_POT_FEATURE 1U
+   
+   /* LCD controllers defines */
+#define USE_LCD_CTRL_OTM8009A   1U
+#define USE_LCD_CTRL_ADV75331U
+#define LCD_LAYER_0_ADDRESS 0xD000U
+#define LCD_LAYER_1_ADDRESS 0xD020U
+   
+   /* SD high performance usage define */
+#define USE_SD_HIGH_PERFORMANCE 0U
+   
+   /*DMA2D to fill RGB rectangle usage define*/
+#define USE_DMA2D_TO_FILL_RGB_RECT  0U
+   
+   /* Audio codecs defines */
+#define USE_AUDIO_CODEC_WM8994  1U
+#define USE_AUDIO_CODEC_ADV7533  

[PATCH 1/5] bsps/stm32h7: import MT25TL01G QSPI memory low-level driver

2022-06-17 Thread Karel Gardas
Sponsored-By:   Precidata
---
 .../stm/Components/mt25tl01g/mt25tl01g.c  | 1046 +
 .../stm/Components/mt25tl01g/mt25tl01g.h  |  362 ++
 .../stm/Components/mt25tl01g/mt25tl01g_conf.h |   68 ++
 3 files changed, 1476 insertions(+)
 create mode 100644 bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.c
 create mode 100644 bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.h
 create mode 100644 
bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g_conf.h

diff --git a/bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.c 
b/bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.c
new file mode 100644
index 00..740cdbbd27
--- /dev/null
+++ b/bsps/arm/stm32h7/boards/stm/Components/mt25tl01g/mt25tl01g.c
@@ -0,0 +1,1046 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+  
**
+  * @fileMT25TL01G.c
+  * @author  MCD Application Team
+  * @brief   This file provides the MT25TL01G QSPI driver.
+  
**
+  * @attention
+  *
+  * © Copyright (c) 2016 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *opensource.org/licenses/BSD-3-Clause
+  *
+  
**
+  */
+/* Includes 
--*/
+#include "mt25tl01g.h"
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+
+/** @addtogroup MT25TL01G
+  * @brief This file provides a set of functions needed to drive the
+  * MT25TL01G QSPI memory.
+  * @{
+  */
+/** @defgroup MT25TL01G_Exported_Functions MT25TL01G Exported Functions
+  * @{
+  */
+
+/**
+  * @brief  Return the configuration of the QSPI memory.
+  * @param  pInfo pointer on the configuration structure
+  * @retval QSPI memory status
+  */
+int32_t MT25TL01G_GetFlashInfo(MT25TL01G_Info_t *pInfo)
+{
+  pInfo->FlashSize  = MT25TL01G_FLASH_SIZE;
+  pInfo->EraseSectorSize= (2 * MT25TL01G_SUBSECTOR_SIZE);
+  pInfo->ProgPageSize   = MT25TL01G_PAGE_SIZE;
+  pInfo->EraseSectorsNumber = (MT25TL01G_FLASH_SIZE/pInfo->EraseSectorSize);
+  pInfo->ProgPagesNumber= (MT25TL01G_FLASH_SIZE/pInfo->ProgPageSize);
+  return MT25TL01G_OK;
+}
+
+/**
+  * @brief  This function set the QSPI memory in 4-byte address mode
+  *  SPI/QPI; 1-0-1/4-0-4
+  * @param  Ctx Component object pointer
+  * @param  Mode Interface mode
+  * @retval QSPI memory status
+  */
+int32_t MT25TL01G_Enter4BytesAddressMode(QSPI_HandleTypeDef *Ctx, 
MT25TL01G_Interface_t Mode)
+{
+  QSPI_CommandTypeDef s_command;
+
+  /* Initialize the command */
+  s_command.InstructionMode   = (Mode == MT25TL01G_QPI_MODE) ? 
QSPI_INSTRUCTION_4_LINES : QSPI_INSTRUCTION_1_LINE;
+  s_command.Instruction   = MT25TL01G_ENTER_4_BYTE_ADDR_MODE_CMD;
+  s_command.AddressMode   = QSPI_ADDRESS_NONE;
+  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  s_command.DataMode  = QSPI_DATA_NONE;
+  s_command.DummyCycles   = 0;
+  s_command.DdrMode   = QSPI_DDR_MODE_DISABLE;
+  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  s_command.SIOOMode  = QSPI_SIOO_INST_EVERY_CMD;
+
+  /*write enable */
+  if( MT25TL01G_WriteEnable(Ctx,Mode)!=MT25TL01G_OK)
+  {
+return MT25TL01G_ERROR_COMMAND;
+  }
+  /* Send the command */
+  if (HAL_QSPI_Command(Ctx, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != 
HAL_OK)
+  {
+return MT25TL01G_ERROR_COMMAND;
+  }
+
+  /* Configure automatic polling mode to wait the memory is ready */
+  else if(MT25TL01G_AutoPollingMemReady(Ctx,Mode)!=MT25TL01G_OK)
+  {
+return MT25TL01G_ERROR_COMMAND;
+  }
+
+  return MT25TL01G_OK;
+}
+
+/**
+  * @brief  Flash exit 4 Byte address mode. Effect 3/4 address byte commands 
only.
+  * SPI/QPI; 1-0-0/4-0-0
+  * @param  Ctx Component object pointer
+  * @param  Mode Interface mode
+  * @retval QSPI memory status
+  */
+int32_t MT25TL01G_Exit4BytesAddressMode(QSPI_HandleTypeDef *Ctx, 
MT25TL01G_Interface_t Mode)
+{
+  QSPI_CommandTypeDef s_command;
+
+  /* Initialize the command */
+  s_command.InstructionMode   = (Mode == MT25TL01G_QPI_MODE) ? 
QSPI_INSTRUCTION_4_LINES : QSPI_INSTRUCTION_1_LINE;
+  s_command.Instruction   = MT25TL01G_EXIT_4_BYTE_ADDR_MODE_CMD;
+  s_command.AddressMode   = QSPI_ADDRESS_NONE;
+  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  s_command.DataMode  = QSPI_DATA_NONE;
+  s_command.DummyCycles   = 0;
+  s_command.DdrMode   = QSPI_DDR_MODE_DISABLE;
+  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  s_command.SIOOMode  = QSPI_SIOO_INST_EVER