<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div dir="ltr"><div>Comments inline below.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 19, 2023 at 12:43 AM <<a href="mailto:aaron.nyholm@unfoldedeffective.com" target="_blank">aaron.nyholm@unfoldedeffective.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Aaron Nyholm <<a href="mailto:aaron.nyholm@southerninnovation.com" target="_blank">aaron.nyholm@southerninnovation.com</a>><br>
<br>
---<br>
 .../dev/spi/versal_xqspi_flash.c              | 296 ++++++++++++++++++<br>
 bsps/aarch64/xilinx-versal/include/bsp/irq.h  |   1 +<br>
 .../include/dev/spi/versal_xqspi_flash.h      |  49 +++<br>
 bsps/include/dev/spi/xqspipsu-flash-helper.h  |  24 ++<br>
 bsps/shared/dev/spi/xqspipsu-flash-helper.c   |  16 +<br>
 spec/build/bsps/aarch64/xilinx-versal/grp.yml |   2 +<br>
 .../aarch64/xilinx-versal/objxqspiflash.yml   |  24 ++<br>
 7 files changed, 412 insertions(+)<br>
 create mode 100644 bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c<br>
 create mode 100644 bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h<br>
 create mode 100644 spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml<br>
<br>
diff --git a/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c b/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c<br>
new file mode 100644<br>
index 0000000000..7771af9dcd<br>
--- /dev/null<br>
+++ b/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c<br>
@@ -0,0 +1,296 @@<br>
+/*<br>
+ * Copyright (C) 2023, 2023 Aaron Nyholm<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#include <bsp/irq.h><br>
+#include <dev/spi/versal_xqspi_flash.h><br>
+#include <dev/spi/xqspipsu.h><br>
+#include <dev/spi/xqspipsu-flash-helper.h><br>
+#include <dev/spi/xqspipsu_flash_config.h><br>
+<br>
+#include <stdlib.h><br>
+#include <string.h><br>
+<br>
+<br>
+uint32_t xqspi_get_jedec_id(rtems_flashdev *flash);<br>
+<br>
+int xqspi_get_flash_type(<br>
+  rtems_flashdev *flash,<br>
+  rtems_flashdev_flash_type *type<br>
+);<br>
+<br>
+int xqspi_page_info_by_off(<br>
+  rtems_flashdev *flash,<br>
+  off_t search_offset,<br>
+  off_t *page_offset,<br>
+  size_t *page_size<br>
+);<br>
+<br>
+int xqspi_page_info_by_index(<br>
+  rtems_flashdev *flash,<br>
+  off_t search_index,<br>
+  off_t *page_offset,<br>
+  size_t *page_size<br>
+);<br>
+<br>
+int xqspi_page_count(<br>
+  rtems_flashdev *flash,<br>
+  int *page_count<br>
+);<br>
+<br>
+int xqspi_write_block_size(<br>
+  rtems_flashdev *flash,<br>
+  size_t *write_block_size<br>
+);<br>
+<br>
+int xqspi_read_wrapper(rtems_flashdev *flash,<br>
+  uintptr_t offset,<br>
+  size_t count,<br>
+  void *buffer<br>
+);<br>
+<br>
+int xqspi_write_wrapper(<br>
+  rtems_flashdev *flash,<br>
+  uintptr_t offset,<br>
+  size_t count,<br>
+  const void *buffer<br>
+);<br>
+<br>
+int xqspi_erase_wrapper(<br>
+  rtems_flashdev *flash,<br>
+  uintptr_t offset,<br>
+  size_t count<br>
+);<br></blockquote><div><br></div><div>The above prototypes are unnecessary and the corresponding functions below should be marked static so as not to require them.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+uint32_t xqspi_get_jedec_id(rtems_flashdev *flash) {<br>
+  return QspiPsu_NOR_Get_JEDEC_ID(flash->driver);<br>
+}<br></blockquote><div><br></div><div>Side commentary: I don't really like that this NOR driver has as much untracked internal state as it does, but that's how it came from Xilinx. An alternative would be to read the 3 relevant bytes using QspiPsu_NOR_RDID. Longer term I'd like to get that state pulled out into a NOR management/wrapper struct that holds the raw XQspiPsu driver struct.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+int xqspi_get_flash_type(<br>
+  rtems_flashdev *flash,<br>
+  rtems_flashdev_flash_type *type<br>
+)<br>
+{<br>
+  *type = RTEMS_FLASHDEV_NOR;<br>
+  return 0;<br>
+}<br>
+<br>
+int xqspi_read_wrapper(<br>
+    rtems_flashdev *flash,<br>
+    uintptr_t offset,<br>
+    size_t count,<br>
+    void *buffer<br>
+)<br>
+{<br>
+  XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;<br>
+  uint8_t *tmp_buffer;<br>
+  int status;<br>
+  int startAlign = 0;<br>
+<br>
+  /* Align offset to two byte boundary */<br>
+  if (offset%2) {<br>
+    startAlign = 1;<br>
+    offset = offset - 1;<br>
+    count = count + 1;<br>
+  }<br>
+<br>
+  while (count > MAX_READ_SIZE) {<br>
+    /* Read block and copy to buffer */<br>
+    status = QspiPsu_NOR_Read(flash_driver, (uint32_t)offset, MAX_READ_SIZE, &tmp_buffer);<br>
+<br>
+    if (status == 0) {<br>
+      memcpy(buffer, tmp_buffer + startAlign, MAX_READ_SIZE - startAlign);<br>
+      /* Update count, offset and buffer pointer */<br>
+      count = count - MAX_READ_SIZE;<br>
+      buffer = buffer + MAX_READ_SIZE - startAlign;<br>
+      offset = offset + MAX_READ_SIZE;<br>
+      /* Clear startAlign once first block read */<br>
+      if (startAlign) {<br>
+        startAlign = 0;<br>
+      }<br>
+    } else {<br>
+      return status;<br>
+    }<br>
+  }<br>
+<br>
+  status = QspiPsu_NOR_Read(flash_driver, (uint32_t)offset, (uint32_t)count, &tmp_buffer);<br>
+<br>
+  if (status == 0) {<br>
+    memcpy(buffer, tmp_buffer + startAlign, count);<br>
+  }<br>
+  return status;<br>
+}<br>
+<br>
+int xqspi_page_info_by_off(<br>
+  rtems_flashdev *flash,<br>
+  off_t search_offset,<br>
+  off_t *page_offset,<br>
+  size_t *page_size<br>
+)<br>
+{<br>
+  *page_size = QspiPsu_NOR_Get_Sector_Size(flash->driver);<br>
+  *page_offset = search_offset - (search_offset%((off_t)(*page_size)));<br>
+  return 0;<br>
+}<br>
+<br>
+int xqspi_page_info_by_index(<br>
+  rtems_flashdev *flash,<br>
+  off_t search_index,<br>
+  off_t *page_offset,<br>
+  size_t *page_size<br>
+)<br>
+{<br>
+  *page_size = QspiPsu_NOR_Get_Page_Size(flash->driver);<br>
+  *page_offset = *page_size * search_index;<br>
+  return 0;<br>
+}<br></blockquote><div><br></div><div>You're mixing page size and sector size in these two functions. <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+int xqspi_page_count(<br>
+  rtems_flashdev *flash,<br>
+  int *page_count<br>
+)<br>
+{<br>
+  *page_count = QspiPsu_NOR_Get_Device_Size(flash->driver) /<br>
+                  QspiPsu_NOR_Get_Page_Size(flash->driver);<br>
+  return 0;<br>
+}<br>
+<br>
+int xqspi_write_block_size(<br>
+  rtems_flashdev *flash,<br>
+  size_t *write_block_size<br>
+)<br>
+{<br>
+  *write_block_size = QspiPsu_NOR_Get_Page_Size(flash->driver);<br>
+  return 0;<br>
+}<br>
+<br>
+int xqspi_write_wrapper(<br>
+  rtems_flashdev *flash,<br>
+  uintptr_t offset,<br>
+  size_t count,<br>
+  const void *buffer<br>
+)<br>
+{<br>
+  XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;<br>
+  return QspiPsu_NOR_Write(flash_driver, (uint32_t)offset, (uint32_t)count, (void*)buffer);<br>
+}<br>
+<br>
+int xqspi_erase_wrapper(<br>
+  rtems_flashdev *flash,<br>
+  uintptr_t offset,<br>
+  size_t count<br>
+)<br>
+{<br>
+  XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;<br>
+  return QspiPsu_NOR_Erase(flash_driver, (uint32_t)offset, (uint32_t)count);<br>
+}<br>
+<br>
+rtems_flashdev* xqspi_flash_init(void)<br></blockquote><div><br></div><div>I'd recommend that this be passed an initialized XQspiPsu pointer and this flashdev adapter should be moved to bsps/shared so that it can be used by any consumer of XQspiPsu. Is there anything preventing this?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+{<br>
+  int status;<br>
+  XQspiPsu *xQspiDev;<br>
+  XQspiPsu_Config *xQspiDev_Config;<br>
+<br>
+  xQspiDev = calloc(1, sizeof(XQspiPsu));<br>
+  if (xQspiDev == NULL) {<br>
+    return NULL;<br>
+  }<br>
+  xQspiDev_Config = calloc(1, sizeof(XQspiPsu_Config));<br>
+  if (xQspiDev_Config == NULL) {<br>
+    free(xQspiDev);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  xQspiDev_Config->DeviceId = 0;<br>
+  xQspiDev_Config->BaseAddress = XQSPIPS_BASEADDR;<br>
+  xQspiDev_Config->InputClockHz = VERSAL_QSPI_INPUT_CLOCK_HZ;<br>
+  xQspiDev_Config->ConnectionMode = XQSPIPSU_CONNECTION_MODE_PARALLEL;<br>
+  xQspiDev_Config->BusWidth = 2;<br>
+  xQspiDev_Config->IsCacheCoherent = 0;<br>
+<br>
+  status = XQspiPsu_CfgInitialize(xQspiDev, xQspiDev_Config, XQSPIPS_BASEADDR);<br>
+<br>
+  if (status != 0) {<br>
+    free(xQspiDev);<br>
+    free(xQspiDev_Config);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  versal_xqspi_region_table *xtable =<br>
+    calloc(1, sizeof(versal_xqspi_region_table));<br>
+<br>
+  if (xtable == NULL) {<br>
+    free(xQspiDev);<br>
+    free(xQspiDev_Config);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  rtems_flashdev_region_table *ftable =<br>
+    calloc(1, sizeof(rtems_flashdev_region_table));<br>
+<br>
+  if (ftable == NULL) {<br>
+    free(ftable);<br>
+    free(xQspiDev);<br>
+    free(xQspiDev_Config);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  ftable->regions = (rtems_flashdev_region*)(&(xtable->versal_xqspi_regions));<br>
+  ftable->max_regions = VERSAL_XQSPI_MAX_REGIONS;<br>
+  ftable->bit_allocator = &(xtable->versal_xqspi_bit_allocator);<br>
+<br>
+  status = QspiPsu_NOR_Initialize(<br>
+    xQspiDev,<br>
+    VERSAL_IRQ_QSPI<br>
+  );<br>
+<br>
+  if (status != 0) {<br>
+    free(xQspiDev);<br>
+    free(xQspiDev_Config);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  rtems_flashdev *flash = rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));<br>
+<br>
+  if (flash == NULL) {<br>
+    free(xQspiDev);<br>
+    free(xQspiDev_Config);<br>
+    return NULL;<br>
+  }<br>
+<br>
+  flash->driver = xQspiDev;<br>
+  flash->read = &xqspi_read_wrapper;<br>
+  flash->write = &xqspi_write_wrapper;<br>
+  flash->erase = &xqspi_erase_wrapper;<br>
+  flash->jedec_id = &xqspi_get_jedec_id;<br>
+  flash->flash_type = &xqspi_get_flash_type;<br>
+  flash->page_info_by_offset = &xqspi_page_info_by_off;<br>
+  flash->page_info_by_index = &xqspi_page_info_by_index;<br>
+  flash->page_count = &xqspi_page_count;<br>
+  flash->write_block_size = &xqspi_write_block_size;<br>
+  flash->region_table = ftable;<br></blockquote><div><br></div><div>This seems to be missing a destroy call to clean up the various allocations.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+  return flash;<br>
+<br>
+}<br>
diff --git a/bsps/aarch64/xilinx-versal/include/bsp/irq.h b/bsps/aarch64/xilinx-versal/include/bsp/irq.h<br>
index b34bdfd345..6f4d387e8f 100644<br>
--- a/bsps/aarch64/xilinx-versal/include/bsp/irq.h<br>
+++ b/bsps/aarch64/xilinx-versal/include/bsp/irq.h<br>
@@ -61,6 +61,7 @@ extern "C" {<br>
 #define VERSAL_IRQ_ETHERNET_0_WAKEUP 89<br>
 #define VERSAL_IRQ_ETHERNET_1 90<br>
 #define VERSAL_IRQ_ETHERNET_1_WAKEUP 91<br>
+#define VERSAL_IRQ_QSPI 157<br>
<br>
 /** @} */<br>
<br>
diff --git a/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h b/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h<br>
new file mode 100644<br>
index 0000000000..fe0ffd3e71<br>
--- /dev/null<br>
+++ b/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h<br>
@@ -0,0 +1,49 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/*<br>
+ * Copyright (C) 2023, 2023 Aaron Nyholm<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#ifndef LIBBSP_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H<br>
+#define LIBBSP_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H<br>
+<br>
+#include <dev/flash/flashdev.h><br>
+<br>
+#define VERSAL_XQSPI_MAX_REGIONS 32<br>
+#define VERSAL_QSPI_INPUT_CLOCK_HZ 295833038<br>
+#define MAX_READ_SIZE 0x8000<br>
+<br>
+/*<br>
+ * Initalize a qspi_flash device using Xilinx's qspi flash<br>
+ * driver. Device still needs to be registered using<br>
+ * qspi_flash_register in qspi_flash.c.<br>
+*/<br>
+rtems_flashdev* xqspi_flash_init(void);<br>
+<br>
+typedef struct versal_xqspi_region_table {<br>
+  rtems_flashdev_region versal_xqspi_regions[VERSAL_XQSPI_MAX_REGIONS];<br>
+  uint32_t versal_xqspi_bit_allocator;<br>
+} versal_xqspi_region_table;<br>
+<br>
+#endif /* LIBBSP_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H */<br>
diff --git a/bsps/include/dev/spi/xqspipsu-flash-helper.h b/bsps/include/dev/spi/xqspipsu-flash-helper.h<br>
index 5e4233e64e..69660d28f7 100644<br>
--- a/bsps/include/dev/spi/xqspipsu-flash-helper.h<br>
+++ b/bsps/include/dev/spi/xqspipsu-flash-helper.h<br>
@@ -155,3 +155,27 @@ u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr);<br>
  *<br>
  ******************************************************************************/<br>
 u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr);<br>
+<br>
+/*****************************************************************************/<br>
+/**<br>
+ *<br>
+ * This function returns the page size of attached flash parts.<br>
+ *<br>
+ * @param      QspiPsuPtr is a pointer to the QSPIPSU driver component to use.<br>
+ *<br>
+ * @return     The page size of attached flash in bytes.<br>
+ *<br>
+ ******************************************************************************/<br>
+u32 QspiPsu_NOR_Get_Page_Size(XQspiPsu *QspiPsuPtr);<br>
+<br>
+/*****************************************************************************/<br>
+/**<br>
+ *<br>
+ * This function returns the JEDEC ID of attached flash parts.<br>
+ *<br>
+ * @param      QspiPsuPtr is a pointer to the QSPIPSU driver component to use.<br>
+ *<br>
+ * @return     The JEDEC ID of attached flash in bytes.<br>
+ *<br>
+ ******************************************************************************/<br>
+u32 QspiPsu_NOR_Get_JEDEC_ID(XQspiPsu *QspiPsuPtr);<br>
diff --git a/bsps/shared/dev/spi/xqspipsu-flash-helper.c b/bsps/shared/dev/spi/xqspipsu-flash-helper.c<br>
index c9d8273b87..1795c9756b 100644<br>
--- a/bsps/shared/dev/spi/xqspipsu-flash-helper.c<br>
+++ b/bsps/shared/dev/spi/xqspipsu-flash-helper.c<br>
@@ -2277,3 +2277,19 @@ u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr)<br>
   }<br>
   return Flash_Config_Table[FCTIndex].FlashDeviceSize;<br>
 }<br>
+<br>
+u32 QspiPsu_NOR_Get_Page_Size(XQspiPsu *QspiPsuPtr)<br>
+{<br>
+  if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {<br>
+    return Flash_Config_Table[FCTIndex].PageSize * 2;<br>
+  }<br>
+  return Flash_Config_Table[FCTIndex].PageSize;<br>
+}<br>
+<br>
+u32 QspiPsu_NOR_Get_JEDEC_ID(XQspiPsu *QspiPsuPtr)<br>
+{<br>
+  if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {<br>
+    return Flash_Config_Table[FCTIndex].jedec_id * 2;<br>
+  }<br>
+  return Flash_Config_Table[FCTIndex].jedec_id;<br>
+}<br></blockquote><div><br></div><div>Copy and paste error?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
diff --git a/spec/build/bsps/aarch64/xilinx-versal/grp.yml b/spec/build/bsps/aarch64/xilinx-versal/grp.yml<br>
index badfa07fcc..098a8481db 100644<br>
--- a/spec/build/bsps/aarch64/xilinx-versal/grp.yml<br>
+++ b/spec/build/bsps/aarch64/xilinx-versal/grp.yml<br>
@@ -24,6 +24,8 @@ links:<br>
   uid: abi<br>
 - role: build-dependency<br>
   uid: obj<br>
+- role: build-dependency<br>
+  uid: objxqspiflash<br>
 - role: build-dependency<br>
   uid: optconirq<br>
 - role: build-dependency<br>
diff --git a/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml b/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml<br>
new file mode 100644<br>
index 0000000000..6d84bfa8cd<br>
--- /dev/null<br>
+++ b/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml<br>
@@ -0,0 +1,24 @@<br>
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause<br>
+build-type: objects<br>
+cflags: []<br>
+copyrights:<br>
+- Copyright (C) 2022 On-Line Applications Research (OAR)<br>
+cppflags: []<br>
+cxxflags: []<br>
+enabled-by: true<br>
+includes:<br>
+- bsps/include/dev/spi/<br>
+- bsps/include/xil/<br>
+- bsps/include/xil/${XIL_SUPPORT_PATH}/<br>
+install:<br>
+- destination: ${BSP_INCLUDEDIR}/bsp<br>
+  source:<br>
+  - bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h<br>
+links:<br>
+- role: build-dependency<br>
+  uid: ../../objxilinxsupport<br>
+- role: build-dependency<br>
+  uid: ../../objqspipsu<br>
+source:<br>
+    - bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c<br>
+type: build<br>
-- <br>
2.25.1<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div></div>