From 098ad421a16234c81eea3f74173516fc2e07ba70 Mon Sep 17 00:00:00 2001 From: Alex White Date: Sun, 18 Dec 2022 21:07:11 -0600 Subject: bsps/xilinx-zynqmp: Add JFFS2 GQSPI NOR driver --- bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h | 1 + .../xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h | 62 +++++++ bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c | 186 +++++++++++++++++++++ spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml | 2 + .../bsps/aarch64/xilinx-zynqmp/objjffs2qspinor.yml | 22 +++ 5 files changed, 273 insertions(+) create mode 100644 bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h create mode 100644 bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c create mode 100644 spec/build/bsps/aarch64/xilinx-zynqmp/objjffs2qspinor.yml diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h index 3ffb01d1df..2cbe99f863 100644 --- a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h +++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h @@ -53,6 +53,7 @@ extern "C" { /* Interrupts vectors */ #define BSP_TIMER_VIRT_PPI 27 #define BSP_TIMER_PHYS_NS_PPI 30 +#define ZYNQMP_IRQ_QSPI 47 #define ZYNQMP_IRQ_I2C_0 49 #define ZYNQMP_IRQ_I2C_1 50 #define ZYNQMP_IRQ_UART_0 54 diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h new file mode 100644 index 0000000000..ac957bb686 --- /dev/null +++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsAArch64XilinxZynqMP + * + * @brief XilinxZynqMP QSPI JFFS2 flash driver definitions + */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * + * 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. + * + * 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 OWNER 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. + */ + +#ifndef LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H +#define LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H + +#include "xqspipsu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Mount jffs2 filesystem. + * + * @param[in] mount_dir The directory to mount the filesystem at. + * @param[in] qspipsu_ptr A pointer to an initialized QSPI instance. + * + * @retval 0 Successful operation. Negative number otherwise. + */ +int xilinx_zynqmp_nor_jffs2_initialize( + const char *mount_dir, + XQspiPsu *qspipsu_ptr +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H */ diff --git a/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c new file mode 100644 index 0000000000..f647c19ec1 --- /dev/null +++ b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * + * 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. + * + * 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 OWNER 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. + */ + +#include + +#include +#include +#include +#include +#include + +typedef struct { + rtems_jffs2_flash_control super; + XQspiPsu *qspipsu; +} flash_control; + +/* From the N25Q512A datasheet */ +#define BLOCK_SIZE (64UL * 1024UL) +#define FLASH_SIZE (1024UL * BLOCK_SIZE) +#define FLASH_DEVICE_ID 0xbb20 /* Type: 0xbb, Capacity: 0x20 */ + +static flash_control *get_flash_control( rtems_jffs2_flash_control *super ) +{ + return (flash_control *) super; +} + +static int do_read( + rtems_jffs2_flash_control *super, + uint32_t offset, + unsigned char *buffer, + size_t size_of_buffer +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + u8* ReadBuffer = NULL; + + Status = QspiPsu_NOR_Read( + QspiPsuPtr, + offset, + size_of_buffer, + &ReadBuffer + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + /* + * We have to copy since we can't be sure that buffer is properly aligned. + */ + memcpy( buffer, ReadBuffer, size_of_buffer ); + + return 0; +} + +static int do_write( + rtems_jffs2_flash_control *super, + uint32_t offset, + const unsigned char *buffer, + size_t size_of_buffer +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + + Status = QspiPsu_NOR_Write( + QspiPsuPtr, + offset, + size_of_buffer, + (unsigned char *) buffer + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + return 0; +} + +static int do_erase( + rtems_jffs2_flash_control *super, + uint32_t offset +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + + Status = QspiPsu_NOR_Erase( + QspiPsuPtr, + offset, + BLOCK_SIZE + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + return 0; +} + +static void do_destroy( rtems_jffs2_flash_control *super ) +{ + flash_control *self = get_flash_control( super ); + + rtems_interrupt_handler_remove( + ZYNQMP_IRQ_QSPI, + (rtems_interrupt_handler) XQspiPsu_InterruptHandler, + self->qspipsu + ); +} + +static flash_control flash_instance = { + .super = { + .block_size = BLOCK_SIZE, + .flash_size = FLASH_SIZE, + .read = do_read, + .write = do_write, + .erase = do_erase, + .destroy = do_destroy, + .device_identifier = FLASH_DEVICE_ID + } +}; + +static rtems_jffs2_mount_data mount_data = { + .flash_control = &flash_instance.super, + .compressor_control = NULL +}; + +int xilinx_zynqmp_nor_jffs2_initialize( + const char *mount_dir, + XQspiPsu *qspipsu_ptr +) +{ + int rv = 0; + + flash_instance.qspipsu = qspipsu_ptr; + + rv = QspiPsu_NOR_Initialize( + flash_instance.qspipsu, + ZYNQMP_IRQ_QSPI + ); + if ( rv != 0 ) { + return rv; + } + + rv = mount( + NULL, + mount_dir, + RTEMS_FILESYSTEM_TYPE_JFFS2, + RTEMS_FILESYSTEM_READ_WRITE, + &mount_data + ); + if ( rv != 0 ) { + return rv; + } + + return 0; +} diff --git a/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml b/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml index 4274d1222f..f0c3a13ffd 100644 --- a/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml +++ b/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml @@ -20,6 +20,8 @@ links: uid: abi - role: build-dependency uid: obj +- role: build-dependency + uid: objjffs2qspinor - role: build-dependency uid: objsmp - role: build-dependency diff --git a/spec/build/bsps/aarch64/xilinx-zynqmp/objjffs2qspinor.yml b/spec/build/bsps/aarch64/xilinx-zynqmp/objjffs2qspinor.yml new file mode 100644 index 0000000000..818e32d985 --- /dev/null +++ b/spec/build/bsps/aarch64/xilinx-zynqmp/objjffs2qspinor.yml @@ -0,0 +1,22 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: objects +cflags: [] +copyrights: +- Copyright (C) 2022 On-Line Applications Research (OAR) +cppflags: [] +cxxflags: [] +enabled-by: true +includes: +- bsps/include/dev/spi/ +- bsps/include/xil/ +- bsps/include/xil/${XIL_SUPPORT_PATH}/ +install: +- destination: ${BSP_INCLUDEDIR}/bsp + source: + - bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h +links: +- role: build-dependency + uid: ../../objqspipsu +source: +- bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c +type: build -- cgit v1.2.3