diff options
Diffstat (limited to '')
183 files changed, 17986 insertions, 658 deletions
diff --git a/bsps/sh/gensh1/console/scitab.c b/bsps/sh/gensh1/console/scitab.c index 37eaa5041a..2dd36d55da 100644 --- a/bsps/sh/gensh1/console/scitab.c +++ b/bsps/sh/gensh1/console/scitab.c @@ -1,9 +1,28 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* - * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * Copyright (c) 2018 embedded brains GmbH & Co. KG + * + * 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. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /* diff --git a/bsps/sh/gensh1/start/linkcmds b/bsps/sh/gensh1/start/linkcmds index fc06126941..b47eedaadf 100644 --- a/bsps/sh/gensh1/start/linkcmds +++ b/bsps/sh/gensh1/start/linkcmds @@ -188,18 +188,18 @@ SECTIONS PROVIDE (end = .); .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram - .rtemsstackidle (NOLOAD) : { - *(SORT(.rtemsstack.idle*)) - } > ram - - _WorkAreaBase = . ; + .rtemsstackinterrupt (NOLOAD) : { + *(.rtemsstack.interrupt) + } > onchip_ram .rtemsstack (NOLOAD) : { *(SORT(.rtemsstack.*)) - } > onchip_ram + } > ram + + _WorkAreaBase = . ; /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/bsps/sh/gensh2/console/config.c b/bsps/sh/gensh2/console/config.c index a2f25742dd..33ed1bd76e 100644 --- a/bsps/sh/gensh2/console/config.c +++ b/bsps/sh/gensh2/console/config.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This file contains the TTY driver table. The implementation is * based on libchip/serial drivers, but it uses internal SHx SCI so @@ -7,9 +9,26 @@ * COPYRIGHT (c) 1989-2001. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * */ @@ -35,7 +54,7 @@ const console_fns sh_sci_fns = sh_sci_initialize_interrupts, /* deviceInitialize */ sh_sci_write_polled, /* deviceWritePolled */ sh_sci_set_attributes, /* deviceSetAttributes */ - TERMIOS_IRQ_DRIVEN /* deviceOutputUsesInterrupts */ + true /* deviceOutputUsesInterrupts */ }; /* @@ -51,7 +70,7 @@ const console_fns sh_sci_fns_polled = sh_sci_init, /* deviceInitialize */ sh_sci_write_polled, /* deviceWritePolled */ sh_sci_set_attributes, /* deviceSetAttributes */ - TERMIOS_POLLED /* deviceOutputUsesInterrupts */ + false /* deviceOutputUsesInterrupts */ }; #if 1 /* (CONSOLE_USE_INTERRUPTS) */ diff --git a/bsps/sh/gensh2/console/sci.c b/bsps/sh/gensh2/console/sci.c index e02049cbf3..ba7f8bc832 100644 --- a/bsps/sh/gensh2/console/sci.c +++ b/bsps/sh/gensh2/console/sci.c @@ -539,7 +539,7 @@ const rtems_termios_callbacks sci_poll_callbacks = { _sh_sci_set_attributes, /* setAttributes */ NULL, /* stopRemoteTX */ NULL, /* StartRemoteTX */ - 0 /* outputUsesInterrupts */ + TERMIOS_POLLED /* outputUsesInterrupts */ }; /* FIXME: not yet supported */ diff --git a/bsps/sh/gensh2/console/sci_termios.c b/bsps/sh/gensh2/console/sci_termios.c index 5d588065af..b9f507eb23 100644 --- a/bsps/sh/gensh2/console/sci_termios.c +++ b/bsps/sh/gensh2/console/sci_termios.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Termios console serial driver. */ @@ -10,9 +12,26 @@ * COPYRIGHT (c) 1989-2001. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * */ diff --git a/bsps/sh/gensh2/console/scitab.c b/bsps/sh/gensh2/console/scitab.c index 2db152dff2..7c8e699246 100644 --- a/bsps/sh/gensh2/console/scitab.c +++ b/bsps/sh/gensh2/console/scitab.c @@ -1,9 +1,28 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* - * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * Copyright (c) 2018 embedded brains GmbH & Co. KG + * + * 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. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /* diff --git a/bsps/sh/gensh2/include/sh/sci_termios.h b/bsps/sh/gensh2/include/sh/sci_termios.h index 63750c9461..8b5f3974f3 100644 --- a/bsps/sh/gensh2/include/sh/sci_termios.h +++ b/bsps/sh/gensh2/include/sh/sci_termios.h @@ -1,10 +1,29 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * COPYRIGHT (c) 1989-2001. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * */ diff --git a/bsps/sh/gensh2/start/linkcmds b/bsps/sh/gensh2/start/linkcmds index bdc71bb984..98178b6101 100644 --- a/bsps/sh/gensh2/start/linkcmds +++ b/bsps/sh/gensh2/start/linkcmds @@ -199,18 +199,18 @@ SECTIONS PROVIDE (end = .); .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram - .rtemsstackidle (NOLOAD) : { - *(SORT(.rtemsstack.idle*)) - } > ram - - _WorkAreaBase = . ; + .rtemsstackinterrupt (NOLOAD) : { + *(.rtemsstack.interrupt) + } > onchip_ram .rtemsstack (NOLOAD) : { *(SORT(.rtemsstack.*)) - } > onchip_ram + } > ram + + _WorkAreaBase = . ; /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/bsps/sh/gensh2/start/linkcmds.ram b/bsps/sh/gensh2/start/linkcmds.ram index ccf752a26b..c6f173d129 100644 --- a/bsps/sh/gensh2/start/linkcmds.ram +++ b/bsps/sh/gensh2/start/linkcmds.ram @@ -201,7 +201,7 @@ SECTIONS PROVIDE (end = .); .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstackidle (NOLOAD) : { diff --git a/bsps/sh/gensh2/start/linkcmds.rom b/bsps/sh/gensh2/start/linkcmds.rom index 6b2a760cfa..2d3071e260 100644 --- a/bsps/sh/gensh2/start/linkcmds.rom +++ b/bsps/sh/gensh2/start/linkcmds.rom @@ -202,7 +202,7 @@ SECTIONS PROVIDE (end = .); .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstackidle (NOLOAD) : { diff --git a/bsps/sh/gensh4/console/console.c b/bsps/sh/gensh4/console/console.c index 917556df4e..02c43786d5 100644 --- a/bsps/sh/gensh4/console/console.c +++ b/bsps/sh/gensh4/console/console.c @@ -284,7 +284,7 @@ console_open(rtems_device_major_number major, console_set_attributes, /* setAttributes */ console_stop_remote_tx, /* stopRemoteTx */ console_start_remote_tx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ }; static const rtems_termios_callbacks poll_callbacks = { console_first_open, /* firstOpen */ @@ -294,7 +294,7 @@ console_open(rtems_device_major_number major, console_set_attributes, /* setAttributes */ console_stop_remote_tx, /* stopRemoteTx */ console_start_remote_tx, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ + TERMIOS_POLLED /* outputUsesInterrupts */ }; switch (console_mode) diff --git a/bsps/sh/gensh4/include/tm27.h b/bsps/sh/gensh4/include/tm27.h index c26ec49272..978bf8505a 100644 --- a/bsps/sh/gensh4/include/tm27.h +++ b/bsps/sh/gensh4/include/tm27.h @@ -27,6 +27,8 @@ # error "..." #endif +#define TM27_USE_VECTOR_HANDLER + #define Install_tm27_vector( handler ) \ { \ rtems_isr_entry old_handler; \ diff --git a/bsps/sh/gensh4/start/linkcmds b/bsps/sh/gensh4/start/linkcmds index b940aadb2b..b0a4baeef4 100644 --- a/bsps/sh/gensh4/start/linkcmds +++ b/bsps/sh/gensh4/start/linkcmds @@ -146,7 +146,7 @@ SECTIONS } > ram .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstack (NOLOAD) : { diff --git a/bsps/sh/gensh4/start/linkcmds.rom b/bsps/sh/gensh4/start/linkcmds.rom index 704b624f01..127bc38763 100644 --- a/bsps/sh/gensh4/start/linkcmds.rom +++ b/bsps/sh/gensh4/start/linkcmds.rom @@ -189,7 +189,7 @@ SECTIONS } > ram .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstack (NOLOAD) : { diff --git a/bsps/sh/gensh4/start/linkcmds.rom2ram b/bsps/sh/gensh4/start/linkcmds.rom2ram index 6785556416..89d8c59bd1 100644 --- a/bsps/sh/gensh4/start/linkcmds.rom2ram +++ b/bsps/sh/gensh4/start/linkcmds.rom2ram @@ -193,7 +193,7 @@ SECTIONS } >ram .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstack (NOLOAD) : { diff --git a/bsps/sh/shared/doxygen.h b/bsps/sh/shared/doxygen.h index ae5d985f81..e529f13080 100644 --- a/bsps/sh/shared/doxygen.h +++ b/bsps/sh/shared/doxygen.h @@ -1,4 +1,12 @@ /** + * @file + * + * @ingroup RTEMSImplDoxygen + * + * @brief This header file defines sh-specific groups. + */ + +/** * @defgroup RTEMSBSPsSH SuperH (sh) * * @ingroup RTEMSBSPs diff --git a/bsps/sh/shared/start/bsphwinit.c b/bsps/sh/shared/start/bsphwinit.c index 2e9bd2eacd..66786be8f9 100644 --- a/bsps/sh/shared/start/bsphwinit.c +++ b/bsps/sh/shared/start/bsphwinit.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This is a dummy bsp_hw_init routine. */ @@ -6,9 +8,26 @@ * COPYRIGHT (c) 1989-2014. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/sh/shsim/console/console-debugio.c b/bsps/sh/shsim/console/console-debugio.c index 0a81dbe45b..24d37dcc49 100644 --- a/bsps/sh/shsim/console/console-debugio.c +++ b/bsps/sh/shsim/console/console-debugio.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @brief Stub printk() support @@ -7,9 +9,26 @@ * COPYRIGHT (c) 1989-2014. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /* diff --git a/bsps/sh/shsim/console/console-io.c b/bsps/sh/shsim/console/console-io.c index 71b089fdf7..ee4fadca0c 100644 --- a/bsps/sh/shsim/console/console-io.c +++ b/bsps/sh/shsim/console/console-io.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This file contains the hardware specific portions of the TTY driver * for the simulators stdin/out. @@ -7,9 +9,26 @@ * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/sh/shsim/start/cpu_asm.c b/bsps/sh/shsim/start/cpu_asm.c index db5171b17a..e92b8dd87b 100644 --- a/bsps/sh/shsim/start/cpu_asm.c +++ b/bsps/sh/shsim/start/cpu_asm.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Support for SuperH Simulator in GDB */ @@ -6,9 +8,26 @@ * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems/score/cpu.h> diff --git a/bsps/sh/shsim/start/linkcmds b/bsps/sh/shsim/start/linkcmds index 3a8d0d9d5b..e22e0bc98a 100644 --- a/bsps/sh/shsim/start/linkcmds +++ b/bsps/sh/shsim/start/linkcmds @@ -204,7 +204,7 @@ SECTIONS PROVIDE (end = .); .noinit (NOLOAD) : { - *(.noinit*) + *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*))) } > ram .rtemsstack (NOLOAD) : { diff --git a/bsps/sh/shsim/start/sysexit.c b/bsps/sh/shsim/start/sysexit.c index dde20f35e8..fcb888d9af 100644 --- a/bsps/sh/shsim/start/sysexit.c +++ b/bsps/sh/shsim/start/sysexit.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This file contains the simulator specific exit trap. */ @@ -6,9 +8,26 @@ * COPYRIGHT (c) 1989-2014. * On-Line Applications Research Corporation (OAR). * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/shared/cache/cacheimpl.h b/bsps/shared/cache/cacheimpl.h index 16fe59d804..ddd125aa87 100644 --- a/bsps/shared/cache/cacheimpl.h +++ b/bsps/shared/cache/cacheimpl.h @@ -1,7 +1,16 @@ +/** + * @file + * + * @ingroup RTEMSImplClassicCache + * + * @brief This header file contains the implementation of the + * @ref RTEMSAPIClassicCache. + */ + /* * Cache Manager * - * Copyright (C) 2014, 2018 embedded brains GmbH + * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -11,10 +20,12 @@ * http://www.rtems.org/license/LICENSE. */ -/* - * The functions in this file implement the API to the RTEMS Cache Manager. - * This file is intended to be included in a cache implemention source file - * provided by the architecture or BSP, e.g. +/** + * @file + * + * The functions in this file implement the API to the + * @ref RTEMSAPIClassicCache. This file is intended to be included in a cache + * implemention source file provided by the architecture or BSP, e.g. * * - bsps/${RTEMS_CPU}/shared/cache/cache.c * - bsps/${RTEMS_CPU}/${RTEMS_BSP_FAMILY}/start/cache.c @@ -22,25 +33,33 @@ * In this file a couple of defines and inline functions may be provided and * afterwards this file is included, e.g. * + * @code * #define CPU_DATA_CACHE_ALIGNMENT XYZ * ... * #include "../../../bsps/shared/cache/cacheimpl.h" + * @endcode * * The cache implementation source file shall define * + * @code * #define CPU_DATA_CACHE_ALIGNMENT <POSITIVE INTEGER> + * @endcode * * to enable the data cache support. * * The cache implementation source file shall define * + * @code * #define CPU_INSTRUCTION_CACHE_ALIGNMENT <POSITIVE INTEGER> + * @endcode * * to enable the instruction cache support. * * The cache implementation source file shall define * + * @code * #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS + * @endcode * * if it provides cache maintenance functions which operate on multiple lines. * Otherwise a generic loop with single line operations will be used. It is @@ -49,28 +68,36 @@ * * The cache implementation source file shall define * + * @code * #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS + * @endcode * * if it provides functions to get the data and instruction cache sizes by * level. * * The cache implementation source file shall define * + * @code * #define CPU_CACHE_SUPPORT_PROVIDES_INSTRUCTION_SYNC_FUNCTION + * @endcode * * if special instructions must be used to synchronize the instruction caches * after a code change. * * The cache implementation source file shall define * + * @code * #define CPU_CACHE_SUPPORT_PROVIDES_DISABLE_DATA + * @endcode * * if an external implementation of rtems_cache_disable_data() is provided, * e.g. as an implementation in assembly code. * * The cache implementation source file shall define * + * @code * #define CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING + * @endcode * * if the hardware provides no instruction cache snooping and the instruction * cache invalidation needs software support. @@ -98,6 +125,14 @@ #error "CPU_INSTRUCTION_CACHE_ALIGNMENT is greater than CPU_CACHE_LINE_BYTES" #endif +/** + * @defgroup RTEMSImplClassicCache Cache Manager + * + * @ingroup RTEMSImplClassic + * + * @brief This group contains the Cache Manager implementation. + */ + /* * THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE A DATA CACHE */ @@ -283,6 +318,7 @@ static void smp_cache_inst_inv(void *arg) static void smp_cache_inst_inv_all(void *arg) { + (void) arg; _CPU_cache_invalidate_entire_instruction(); } diff --git a/bsps/shared/dev/btimer/btimer-cpucounter.c b/bsps/shared/dev/btimer/btimer-cpucounter.c index 3698778913..8757cb844b 100644 --- a/bsps/shared/dev/btimer/btimer-cpucounter.c +++ b/bsps/shared/dev/btimer/btimer-cpucounter.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/clock/arm-generic-timer.c b/bsps/shared/dev/clock/arm-generic-timer.c index 07a31fb3b7..ba159f6833 100644 --- a/bsps/shared/dev/clock/arm-generic-timer.c +++ b/bsps/shared/dev/clock/arm-generic-timer.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,15 +54,12 @@ typedef struct { static arm_gt_clock_context arm_gt_clock_instance; -/* This is defined in dev/clock/clockimpl.h */ -void Clock_isr(rtems_irq_hdl_param arg); - -static void arm_gt_clock_at_tick(void) +static void arm_gt_clock_at_tick(arm_gt_clock_context *ctx) { uint64_t cval; uint32_t interval; - interval = arm_gt_clock_instance.interval; + interval = ctx->interval; cval = arm_gt_clock_get_compare_value(); cval += interval; arm_gt_clock_set_compare_value(cval); @@ -71,7 +68,7 @@ static void arm_gt_clock_at_tick(void) #endif /* ARM_GENERIC_TIMER_UNMASK_AT_TICK */ } -static void arm_gt_clock_handler_install(void) +static void arm_gt_clock_handler_install(rtems_interrupt_handler handler) { rtems_status_code sc; @@ -79,8 +76,8 @@ static void arm_gt_clock_handler_install(void) arm_gt_clock_instance.irq, "Clock", RTEMS_INTERRUPT_UNIQUE, - (rtems_interrupt_handler) Clock_isr, - NULL + handler, + &arm_gt_clock_instance ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(BSP_ARM_FATAL_GENERIC_TIMER_CLOCK_IRQ_INSTALL); @@ -185,14 +182,14 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_ORDER_FIRST ); -#define Clock_driver_support_at_tick() \ - arm_gt_clock_at_tick() +#define Clock_driver_support_at_tick(arg) \ + arm_gt_clock_at_tick(arg) #define Clock_driver_support_initialize_hardware() \ arm_gt_clock_initialize() #define Clock_driver_support_install_isr(isr) \ - arm_gt_clock_handler_install() + arm_gt_clock_handler_install(isr) /* Include shared source clock driver code */ #include "../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/clock/bcm2835-system-timer.c b/bsps/shared/dev/clock/bcm2835-system-timer.c new file mode 100644 index 0000000000..bb8490d03a --- /dev/null +++ b/bsps/shared/dev/clock/bcm2835-system-timer.c @@ -0,0 +1,94 @@ +/** + * @file + * + * @ingroup RTEMSDriverClockImpl + * + * @brief This source file contains the implementation of the BCM2835 Clock + * Driver. + */ + +/* + * Copyright (c) 2013 Alan Cudmore + * Copyright (c) 2016 Pavel Pisa + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * +*/ + +#include <rtems.h> +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/irq-generic.h> +#include <bsp/raspberrypi.h> +#include <rtems/timecounter.h> + +static struct timecounter raspberrypi_tc; + +static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc) +{ + return BCM2835_REG(BCM2835_GPU_TIMER_CLO); +} + +static void raspberrypi_clock_at_tick(void) +{ + uint32_t act_val; + uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3); + next_cmp += rtems_configuration_get_microseconds_per_tick(); + BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp; + act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO); + + /* + * Clear interrupt only if there is time left to the next tick. + * If time of the next tick has already passed then interrupt + * request stays active and fires immediately after current tick + * processing is finished. + */ + if ((int32_t)(next_cmp - act_val) > 0) + BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3; +} + +static void raspberrypi_clock_handler_install_isr( + rtems_interrupt_handler clock_isr +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + sc = rtems_interrupt_handler_install( + BCM2835_IRQ_ID_GPU_TIMER_M3, + "Clock", + RTEMS_INTERRUPT_UNIQUE, + clock_isr, + NULL + ); + if ( sc != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred(0xdeadbeef); + } +} + +static void raspberrypi_clock_initialize_hardware(void) +{ + uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO); + next_cmp += rtems_configuration_get_microseconds_per_tick(); + BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp; + BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3; + + raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount; + raspberrypi_tc.tc_counter_mask = 0xffffffff; + raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */ + raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&raspberrypi_tc); +} + +#define Clock_driver_support_at_tick(arg) raspberrypi_clock_at_tick() + +#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware() + +#define Clock_driver_support_install_isr(clock_isr) \ + raspberrypi_clock_handler_install_isr(clock_isr) + +#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1 + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/clock/clockimpl.h b/bsps/shared/dev/clock/clockimpl.h index ccf6d3ab60..b27f7c15bc 100644 --- a/bsps/shared/dev/clock/clockimpl.h +++ b/bsps/shared/dev/clock/clockimpl.h @@ -3,9 +3,12 @@ /** * @file * - * @ingroup bsp_clock + * @ingroup RTEMSDriverClockImpl * - * @brief Clock Tick Device Driver Shell + * @brief This header file contains the shared Clock Driver implementation. + * + * This header file shall only be included by a particular Clock Driver + * implementation source file. */ /* @@ -39,27 +42,35 @@ #include <bsp.h> #include <rtems/clockdrv.h> #include <rtems/score/percpu.h> +#include <rtems/score/processormaskimpl.h> #include <rtems/score/smpimpl.h> #include <rtems/score/timecounter.h> #include <rtems/score/thread.h> #include <rtems/score/watchdogimpl.h> -#ifdef Clock_driver_nanoseconds_since_last_tick -#error "Update driver to use the timecounter instead of nanoseconds extension" -#endif - /** - * @defgroup bsp_clock Clock Support - * - * @ingroup RTEMSBSPsShared + * @defgroup RTEMSDriverClockImpl Clock Driver Implementation * - * @brief Clock support + * @ingroup RTEMSDriverClock * + * @brief This group contains the Clock Driver implementation. */ + +#ifdef Clock_driver_nanoseconds_since_last_tick +#error "Update driver to use the timecounter instead of nanoseconds extension" +#endif + #if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK #error "Fast Idle PLUS n ISRs per tick is not supported" #endif +#if defined(BSP_FEATURE_IRQ_EXTENSION) || \ + (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE) +typedef void * Clock_isr_argument; +#else +typedef rtems_vector_number Clock_isr_argument; +#endif + /** * @brief Do nothing by default. */ @@ -78,7 +89,7 @@ * @brief Do nothing by default. */ #ifndef Clock_driver_support_at_tick - #define Clock_driver_support_at_tick() + #define Clock_driver_support_at_tick( arg ) do { (void) arg; } while (0) #endif /** @@ -93,8 +104,9 @@ * instead of the default. */ #ifndef Clock_driver_timecounter_tick -static void Clock_driver_timecounter_tick( void ) +static void Clock_driver_timecounter_tick( Clock_isr_argument arg ) { + (void) arg; #if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER) rtems_clock_tick(); #elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR) @@ -136,25 +148,31 @@ volatile uint32_t Clock_driver_ticks; #error "Clock_driver_support_shutdown_hardware() is no longer supported" #endif +#if CLOCK_DRIVER_USE_FAST_IDLE +static bool _Clock_Has_watchdogs(const Per_CPU_Control *cpu) +{ + size_t i; + + for (i = 0; i < RTEMS_ARRAY_SIZE(cpu->Watchdog.Header); ++i) { + if (_Watchdog_Header_first(&cpu->Watchdog.Header[i]) != NULL) { + return true; + } + } + + return false; +} +#endif + /** * @brief Clock_isr * * This is the clock tick interrupt handler. * - * @param vector Vector number. + * @param arg is the clock interrupt handler argument. */ -#if defined(BSP_FEATURE_IRQ_EXTENSION) || \ - (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE) -void Clock_isr(void *arg); -void Clock_isr(void *arg) +void Clock_isr( Clock_isr_argument arg ); +void Clock_isr( Clock_isr_argument arg ) { -#else -rtems_isr Clock_isr(rtems_vector_number vector); -rtems_isr Clock_isr( - rtems_vector_number vector -) -{ -#endif /* * Accurate count of ISRs */ @@ -162,7 +180,7 @@ rtems_isr Clock_isr( #if CLOCK_DRIVER_USE_FAST_IDLE { - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); if (_SMP_Get_processor_maximum() == 1) { struct timecounter *tc; @@ -179,6 +197,7 @@ rtems_isr Clock_isr( cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level && cpu_self->heir == cpu_self->executing && cpu_self->executing->is_idle + && _Clock_Has_watchdogs(cpu_self) ) { ISR_lock_Context lock_context; @@ -191,7 +210,7 @@ rtems_isr Clock_isr( } } - Clock_driver_support_at_tick(); + Clock_driver_support_at_tick( arg ); } #else /* @@ -199,14 +218,14 @@ rtems_isr Clock_isr( * * The counter/timer may or may not be set to automatically reload. */ - Clock_driver_support_at_tick(); + Clock_driver_support_at_tick( arg ); #if CLOCK_DRIVER_ISRS_PER_TICK /* * The driver is multiple ISRs per clock tick. */ if ( !Clock_driver_isrs ) { - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE; } @@ -215,7 +234,7 @@ rtems_isr Clock_isr( /* * The driver is one ISR per clock tick. */ - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); #endif #endif } diff --git a/bsps/shared/dev/clock/xil-ttc.c b/bsps/shared/dev/clock/xil-ttc.c new file mode 100644 index 0000000000..624845d71c --- /dev/null +++ b/bsps/shared/dev/clock/xil-ttc.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDriverClockXilTTC + * + * @brief This source file contains a Clock Driver implementation using the + * Xilinx Triple Timer Counter (TTC). + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * Copyright (C) 2023 Reflex Aerospace GmbH + * + * Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.com> + * + * 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 <bsp.h> +#include <bsp/irq.h> +#include <bsp/fatal.h> +#include <dev/clock/xttcps_hw.h> +#include <rtems/sysinit.h> +#include <rtems/timecounter.h> + +#if XTTCPS_COUNT_VALUE_MASK != UINT32_MAX +#error "unexpected XTTCPS_COUNT_VALUE_MASK value" +#endif + +/** + * @defgroup RTEMSDriverClockXilTTC \ + * Xilinx Triple Timer Counter (TTC) Clock Driver + * + * @ingroup RTEMSDriverClockImpl + * + * @brief This group contains the Xilinx Triple Timer Counter (TTC) Clock + * Driver implementation. + * + * @{ + */ + +uint32_t _CPU_Counter_frequency( void ) +{ + return XIL_CLOCK_TTC_REFERENCE_CLOCK; +} + +CPU_Counter_ticks _CPU_Counter_read(void) +{ + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); +} + +static void xil_ttc_initialize(void) +{ + /* Do not use a prescaler to get a high resolution time source */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0); + + /* Disable interupts */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, 0); + + /* + * Enable the timer, do not enable waveform output, increment up, use + * overflow mode, enable match mode. + */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CNT_CNTRL_OFFSET, + XTTCPS_CNT_CNTRL_EN_WAVE_MASK | XTTCPS_CNT_CNTRL_MATCH_MASK); +} + +RTEMS_SYSINIT_ITEM( + xil_ttc_initialize, + RTEMS_SYSINIT_CPU_COUNTER, + RTEMS_SYSINIT_ORDER_MIDDLE +); + +typedef struct { + struct timecounter base; + uint32_t irq_match_interval; +} xil_ttc_timecounter; + +static xil_ttc_timecounter xil_ttc_clock_instance; + +static uint32_t xil_ttc_get_timecount(struct timecounter *tc) +{ + (void) tc; + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); +} + +static void xil_ttc_clock_driver_support_initialize_hardware(void) +{ + xil_ttc_timecounter *tc; + uint64_t frequency; + uint32_t irq_match_interval; + uint32_t count; + + tc = &xil_ttc_clock_instance; + frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + irq_match_interval = (uint32_t) + ((frequency * rtems_configuration_get_microseconds_per_tick()) / 1000000); + + /* Setup match register to generate clock interrupts */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, + count + irq_match_interval); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Enable interupt for match register */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, + XTTCPS_IXR_MATCH_0_MASK); + + /* Install timecounter */ + tc->irq_match_interval = irq_match_interval; + tc->base.tc_counter_mask = UINT32_MAX; + tc->base.tc_frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + tc->base.tc_get_timecount = xil_ttc_get_timecount; + tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&tc->base); +} + +static void xil_ttc_clock_driver_support_at_tick(xil_ttc_timecounter *tc) +{ + uint32_t irq_match_interval; + uint32_t count; + uint32_t match; + + irq_match_interval = tc->irq_match_interval; + + /* Update match register */ + match = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET); + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Check that the new match value is in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + + while (RTEMS_PREDICT_FALSE(match - count > irq_match_interval)) { + /* + * Tick misses may happen if interrupts are disabled for an extremly long + * period or while debugging. + */ + rtems_timecounter_tick(); + + /* Update match register */ + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Maybe the new match value is now in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + } +} + +static rtems_interrupt_entry xil_ttc_interrupt_entry; + +static void xil_ttc_clock_driver_support_install_isr( + rtems_interrupt_handler handler +) +{ + rtems_status_code sc; + + rtems_interrupt_entry_initialize( + &xil_ttc_interrupt_entry, + handler, + &xil_ttc_clock_instance, + "Clock" + ); + sc = rtems_interrupt_entry_install( + XIL_CLOCK_TTC_IRQ, + RTEMS_INTERRUPT_UNIQUE, + &xil_ttc_interrupt_entry + ); + if ( sc != RTEMS_SUCCESSFUL ) { + bsp_fatal(XIL_FATAL_TTC_IRQ_INSTALL); + } +} + +#define Clock_driver_support_at_tick(arg) \ + xil_ttc_clock_driver_support_at_tick(arg) + +#define Clock_driver_support_initialize_hardware \ + xil_ttc_clock_driver_support_initialize_hardware + +#define Clock_driver_support_install_isr(isr) \ + xil_ttc_clock_driver_support_install_isr(isr) + +/** @} */ + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/cpucounter/cpucounterfrequency.c b/bsps/shared/dev/cpucounter/cpucounterfrequency.c index fcc4cdbc33..96a4078889 100644 --- a/bsps/shared/dev/cpucounter/cpucounterfrequency.c +++ b/bsps/shared/dev/cpucounter/cpucounterfrequency.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * Copyright (c) 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/cpucounter/cpucounterread.c b/bsps/shared/dev/cpucounter/cpucounterread.c index f27784f9a7..f4e6e77fc1 100644 --- a/bsps/shared/dev/cpucounter/cpucounterread.c +++ b/bsps/shared/dev/cpucounter/cpucounterread.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/disp_fonts.h b/bsps/shared/dev/display/disp_fonts.h index 6705f8d164..e6023721ee 100644 --- a/bsps/shared/dev/display/disp_fonts.h +++ b/bsps/shared/dev/display/disp_fonts.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/disp_hcms29xx.c b/bsps/shared/dev/display/disp_hcms29xx.c index e22dc10f21..4e221a1a94 100644 --- a/bsps/shared/dev/display/disp_hcms29xx.c +++ b/bsps/shared/dev/display/disp_hcms29xx.c @@ -8,7 +8,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/font_hcms29xx.c b/bsps/shared/dev/display/font_hcms29xx.c index a60e665b4b..43596923a8 100644 --- a/bsps/shared/dev/display/font_hcms29xx.c +++ b/bsps/shared/dev/display/font_hcms29xx.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/font_hcms29xx.h b/bsps/shared/dev/display/font_hcms29xx.h index ca5e0fd055..d390b9c90b 100644 --- a/bsps/shared/dev/display/font_hcms29xx.h +++ b/bsps/shared/dev/display/font_hcms29xx.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/dma/fsl-edma.c b/bsps/shared/dev/dma/fsl-edma.c index b3e1bb2fc5..c8b812c1a5 100644 --- a/bsps/shared/dev/dma/fsl-edma.c +++ b/bsps/shared/dev/dma/fsl-edma.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,7 +40,7 @@ #include <bsp/fatal.h> #include <bsp/irq.h> #ifdef LIBBSP_ARM_IMXRT_BSP_H -#include <MIMXRT1052.h> +#include <fsl_device_registers.h> #endif #define EDMA_CHANNELS_PER_GROUP 32U diff --git a/bsps/shared/dev/getentropy/getentropy-cpucounter.c b/bsps/shared/dev/getentropy/getentropy-cpucounter.c index d5b2edeb13..44a2573f50 100644 --- a/bsps/shared/dev/getentropy/getentropy-cpucounter.c +++ b/bsps/shared/dev/getentropy/getentropy-cpucounter.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/cadence-i2c.c b/bsps/shared/dev/i2c/cadence-i2c.c index 91774fb926..67dec0da46 100644 --- a/bsps/shared/dev/i2c/cadence-i2c.c +++ b/bsps/shared/dev/i2c/cadence-i2c.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2014 embedded brains GmbH + * Copyright (C) 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,7 +28,6 @@ #include <dev/i2c/cadence-i2c.h> #include <dev/i2c/cadence-i2c-regs.h> -#include <rtems/irq-extension.h> #include <rtems/score/assert.h> #include <dev/i2c/i2c.h> diff --git a/bsps/shared/dev/i2c/i2c-sc620.c b/bsps/shared/dev/i2c/i2c-sc620.c index 8840a77f24..ed360086d8 100644 --- a/bsps/shared/dev/i2c/i2c-sc620.c +++ b/bsps/shared/dev/i2c/i2c-sc620.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-flash-m25p40.c b/bsps/shared/dev/i2c/spi-flash-m25p40.c index 66d893cb09..9f6189cd3c 100644 --- a/bsps/shared/dev/i2c/spi-flash-m25p40.c +++ b/bsps/shared/dev/i2c/spi-flash-m25p40.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007 embedded brains GmbH. All rights reserved. + * Copyright (c) 2007 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-fram-fm25l256.c b/bsps/shared/dev/i2c/spi-fram-fm25l256.c index f85ac0d4bf..e1ff15e5b3 100644 --- a/bsps/shared/dev/i2c/spi-fram-fm25l256.c +++ b/bsps/shared/dev/i2c/spi-fram-fm25l256.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-memdrv.c b/bsps/shared/dev/i2c/spi-memdrv.c index 55460d30a4..d890b9e41a 100644 --- a/bsps/shared/dev/i2c/spi-memdrv.c +++ b/bsps/shared/dev/i2c/spi-memdrv.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-sd-card.c b/bsps/shared/dev/i2c/spi-sd-card.c index 0375e72be5..36a2721bb9 100644 --- a/bsps/shared/dev/i2c/spi-sd-card.c +++ b/bsps/shared/dev/i2c/spi-sd-card.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008, 2018 embedded brains GmbH + * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/ide/ata_util.c b/bsps/shared/dev/ide/ata_util.c index 68e0f0bbe5..5fd286cdc5 100644 --- a/bsps/shared/dev/ide/ata_util.c +++ b/bsps/shared/dev/ide/ata_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 embedded brains GmbH. + * Copyright (c) 2010 embedded brains GmbH & Co. KG * * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru> diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c index 8a1351bbe5..613174bb3a 100644 --- a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c +++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c @@ -3,13 +3,14 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2. */ /* - * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c index ee4479155a..bb9bfafb48 100644 --- a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c +++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c @@ -3,9 +3,11 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2 of Xilinx Zynq UltraScale+ + * MPSoC and RFSoC devices. */ /* diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index 42fed8a762..263278148b 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -1,7 +1,16 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup DevIRQGIC + * + * @brief This source file contains the implementation of the generic GICv2 + * support. + */ + /* - * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +37,17 @@ #include <dev/irq/arm-gic.h> #include <dev/irq/arm-gic-arch.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> + +/* + * The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special + * purposes. + */ +#if BSP_INTERRUPT_VECTOR_COUNT >= 1020 +#error "BSP_INTERRUPT_VECTOR_COUNT is too large" +#endif #define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE) @@ -66,12 +83,19 @@ void bsp_interrupt_dispatch(void) { volatile gic_cpuif *cpuif = GIC_CPUIF; - uint32_t icciar = cpuif->icciar; - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + while (true) { + uint32_t icciar = cpuif->icciar; + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; + + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } + + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); cpuif->icceoir = icciar; } @@ -320,6 +344,7 @@ rtems_status_code arm_gic_irq_get_group( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -379,6 +404,7 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { @@ -392,9 +418,11 @@ void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) | GIC_DIST_ICDSGIR_SGIINTID(vector); } +#ifdef RTEMS_SMP uint32_t arm_gic_irq_processor_count(void) { volatile gic_dist *dist = ARM_GIC_DIST; return GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1; } +#endif diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c index 4772ff5db4..958b1061bd 100644 --- a/bsps/shared/dev/irq/arm-gicv3.c +++ b/bsps/shared/dev/irq/arm-gicv3.c @@ -1,6 +1,15 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevIRQGIC * + * @brief This source file contains the implementation of the generic GICv3 + * support. + */ + +/* * Copyright (C) 2019 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without @@ -27,18 +36,24 @@ #include <dev/irq/arm-gicv3.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> void bsp_interrupt_dispatch(void) { - uint32_t icciar = READ_SR(ICC_IAR1); - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; + while (true) { + uint32_t icciar = READ_SR(ICC_IAR1); + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } + + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); WRITE_SR(ICC_EOIR1, icciar); } @@ -242,6 +257,7 @@ rtems_status_code arm_gic_irq_get_priority( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -274,12 +290,14 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { gicv3_trigger_sgi(vector, targets); } +#ifdef RTEMS_SMP uint32_t arm_gic_irq_processor_count(void) { volatile gic_dist *dist = ARM_GIC_DIST; @@ -306,3 +324,4 @@ uint32_t arm_gic_irq_processor_count(void) return cpu_count; } +#endif diff --git a/bsps/shared/dev/nand/VERSION b/bsps/shared/dev/nand/VERSION new file mode 100644 index 0000000000..5e4eb00fe9 --- /dev/null +++ b/bsps/shared/dev/nand/VERSION @@ -0,0 +1,24 @@ +The information in this file describes the source of files in +bsps/shared/dev/nand/ and bsps/include/dev/nand/. + +Import from: + +https://github.com/Xilinx/embeddedsw.git + +commit 5330a64c8efd14f0eef09befdbb8d3d738c33ec2 +Refs: <xilinx_v2022.2> +Author: Nicole Baze <nicole.baze@xilinx.com> +AuthorDate: Mon Oct 3 13:27:19 2022 -0700 +Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com> +CommitDate: Fri Oct 7 10:26:16 2022 +0530 + + xilpm: versal: server: Fix bug in AIE2 zeroization + + There is a bug in AIE2 zeriozation function when polling for memory + zeroization complete. Currently the entire memory register is being + checked against zero but instead we need to check the bits specific + to the memory tiles. This patch updates the zeroization check by + adding a mask so that only the desired bits are checked for zero. + + Signed-off-by: Nicole Baze <nicole.baze@xilinx.com> + Acked-by: Jesus De Haro <jesus.de-haro@xilinx.com> diff --git a/bsps/shared/dev/nand/xnandpsu.c b/bsps/shared/dev/nand/xnandpsu.c new file mode 100644 index 0000000000..79025f3c04 --- /dev/null +++ b/bsps/shared/dev/nand/xnandpsu.c @@ -0,0 +1,3027 @@ +/****************************************************************************** +* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xnandpsu.c +* @addtogroup Overview +* @{ +* +* This file contains the implementation of the interface functions for +* XNandPsu driver. Refer to the header file xnandpsu.h for more detailed +* information. +* +* This module supports for NAND flash memory devices that conform to the +* "Open NAND Flash Interface" (ONFI) 3.0 Specification. This modules +* implements basic flash operations like read, write and erase. +* +* @note Driver has been renamed to nandpsu after change in +* naming convention. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- ---------- ----------------------------------------------- +* 1.0 nm 05/06/2014 First release +* 2.0 sb 01/12/2015 Removed Null checks for Buffer passed +* as parameter to Read API's +* - XNandPsu_Read() +* - XNandPsu_ReadPage +* Modified +* - XNandPsu_SetFeature() +* - XNandPsu_GetFeature() +* and made them public. +* Removed Failure Return for BCF Error check in +* XNandPsu_ReadPage() and added BCH_Error counter +* in the instance pointer structure. +* Added XNandPsu_Prepare_Cmd API +* Replaced +* - XNandPsu_IntrStsEnable +* - XNandPsu_IntrStsClear +* - XNandPsu_IntrClear +* - XNandPsu_SetProgramReg +* with XNandPsu_WriteReg call +* Modified xnandpsu.c file API's with above changes. +* Corrected the program command for Set Feature API. +* Modified +* - XNandPsu_OnfiReadStatus +* - XNandPsu_GetFeature +* - XNandPsu_SetFeature +* to add support for DDR mode. +* Changed Convention for SLC/MLC +* SLC --> HAMMING +* MLC --> BCH +* SlcMlc --> IsBCH +* Removed extra DMA mode initialization from +* the XNandPsu_CfgInitialize API. +* Modified +* - XNandPsu_SetEccAddrSize +* ECC address now is calculated based upon the +* size of spare area +* Modified Block Erase API, removed clearing of +* packet register before erase. +* Clearing Data Interface Register before +* XNandPsu_OnfiReset call. +* Modified XNandPsu_ChangeTimingMode API supporting +* SDR and NVDDR interface for timing modes 0 to 5. +* Modified Bbt Signature and Version Offset value for +* Oob and No-Oob region. +* 1.0 kpc 17/6/2015 Added timer based timeout intsead of sw counter. +* 1.1 mi 09/16/16 Removed compilation warnings with extra compiler flags. +* 1.1 nsk 11/07/16 Change memcpy to Xil_MemCpy to handle word aligned +* data access. +* 1.2 nsk 01/19/17 Fix for the failure of reading nand first redundant +* parameter page. CR#966603 +* 1.3 nsk 08/14/17 Added CCI support +* 1.4 nsk 04/10/18 Added ICCARM compiler support. CR#997552. +* 1.5 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform. +* 1.5 mus 11/05/18 Updated XNandPsu_ChangeClockFreq to fix compilation +* warnings. +* 1.6 sd 06/02/20 Added Clock support +* 1.6 sd 20/03/20 Added compilation flag +* 1.8 sg 03/18/21 Added validation check for parameter page. +* 1.9 akm 07/15/21 Initialize NandInstPtr with Data Interface & Timing mode info. +* 1.10 akm 10/20/21 Fix gcc warnings. +* 1.10 akm 12/21/21 Validate input parameters before use. +* 1.10 akm 01/05/22 Remove assert checks form static and internal APIs. +* 1.11 akm 03/31/22 Fix unused parameter warning. +* 1.11 akm 03/31/22 Fix misleading-indentation warning. +* +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xnandpsu.h" +#include "xnandpsu_bbm.h" +#include "sleep.h" +#include "xil_mem.h" +/************************** Constant Definitions *****************************/ + +static const XNandPsu_EccMatrix EccMatrix[] = { + /* 512 byte page */ + {XNANDPSU_PAGE_SIZE_512, 9U, 1U, XNANDPSU_HAMMING, 0x20DU, 0x3U}, + {XNANDPSU_PAGE_SIZE_512, 9U, 4U, XNANDPSU_BCH, 0x209U, 0x7U}, + {XNANDPSU_PAGE_SIZE_512, 9U, 8U, XNANDPSU_BCH, 0x203U, 0xDU}, + /* 2K byte page */ + {XNANDPSU_PAGE_SIZE_2K, 9U, 1U, XNANDPSU_HAMMING, 0x834U, 0xCU}, + {XNANDPSU_PAGE_SIZE_2K, 9U, 4U, XNANDPSU_BCH, 0x826U, 0x1AU}, + {XNANDPSU_PAGE_SIZE_2K, 9U, 8U, XNANDPSU_BCH, 0x80cU, 0x34U}, + {XNANDPSU_PAGE_SIZE_2K, 9U, 12U, XNANDPSU_BCH, 0x822U, 0x4EU}, + {XNANDPSU_PAGE_SIZE_2K, 10U, 24U, XNANDPSU_BCH, 0x81cU, 0x54U}, + /* 4K byte page */ + {XNANDPSU_PAGE_SIZE_4K, 9U, 1U, XNANDPSU_HAMMING, 0x1068U, 0x18U}, + {XNANDPSU_PAGE_SIZE_4K, 9U, 4U, XNANDPSU_BCH, 0x104cU, 0x34U}, + {XNANDPSU_PAGE_SIZE_4K, 9U, 8U, XNANDPSU_BCH, 0x1018U, 0x68U}, + {XNANDPSU_PAGE_SIZE_4K, 9U, 12U, XNANDPSU_BCH, 0x1044U, 0x9CU}, + {XNANDPSU_PAGE_SIZE_4K, 10U, 24U, XNANDPSU_BCH, 0x1038U, 0xA8U}, + /* 8K byte page */ + {XNANDPSU_PAGE_SIZE_8K, 9U, 1U, XNANDPSU_HAMMING, 0x20d0U, 0x30U}, + {XNANDPSU_PAGE_SIZE_8K, 9U, 4U, XNANDPSU_BCH, 0x2098U, 0x68U}, + {XNANDPSU_PAGE_SIZE_8K, 9U, 8U, XNANDPSU_BCH, 0x2030U, 0xD0U}, + {XNANDPSU_PAGE_SIZE_8K, 9U, 12U, XNANDPSU_BCH, 0x2088U, 0x138U}, + {XNANDPSU_PAGE_SIZE_8K, 10U, 24U, XNANDPSU_BCH, 0x2070U, 0x150U}, + /* 16K byte page */ + {XNANDPSU_PAGE_SIZE_16K, 9U, 1U, XNANDPSU_HAMMING, 0x4460U, 0x60U}, + {XNANDPSU_PAGE_SIZE_16K, 9U, 4U, XNANDPSU_BCH, 0x43f0U, 0xD0U}, + {XNANDPSU_PAGE_SIZE_16K, 9U, 8U, XNANDPSU_BCH, 0x4320U, 0x1A0U}, + {XNANDPSU_PAGE_SIZE_16K, 9U, 12U, XNANDPSU_BCH, 0x4250U, 0x270U}, + {XNANDPSU_PAGE_SIZE_16K, 10U, 24U, XNANDPSU_BCH, 0x4220U, 0x2A0U} +}; + +/**************************** Type Definitions *******************************/ +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +static s32 XNandPsu_FlashInit(XNandPsu *InstancePtr); + +static s32 XNandPsu_InitGeometry(XNandPsu *InstancePtr, OnfiParamPage *Param); + +static void XNandPsu_InitFeatures(XNandPsu *InstancePtr, OnfiParamPage *Param); + +static void XNandPsu_InitDataInterface(XNandPsu *InstancePtr, OnfiParamPage *Param); + +static void XNandPsu_InitTimingMode(XNandPsu *InstancePtr, OnfiParamPage *Param); + +static s32 XNandPsu_PollRegTimeout(XNandPsu *InstancePtr, u32 RegOffset, + u32 Mask, u32 Timeout); + +static void XNandPsu_SetPktSzCnt(XNandPsu *InstancePtr, u32 PktSize, + u32 PktCount); + +static void XNandPsu_SetPageColAddr(XNandPsu *InstancePtr, u32 Page, u16 Col); + +static void XNandPsu_SetPageSize(XNandPsu *InstancePtr); + +static void XNandPsu_SelectChip(XNandPsu *InstancePtr, u32 Target); + +static s32 XNandPsu_OnfiReset(XNandPsu *InstancePtr, u32 Target); + +static s32 XNandPsu_OnfiReadStatus(XNandPsu *InstancePtr, u32 Target, + u16 *OnfiStatus); + +static s32 XNandPsu_OnfiReadId(XNandPsu *InstancePtr, u32 Target, u8 IdAddr, + u32 IdLen, u8 *Buf); + +static s32 XNandPsu_OnfiReadParamPage(XNandPsu *InstancePtr, u32 Target, + u8 *Buf); + +static s32 XNandPsu_ProgramPage(XNandPsu *InstancePtr, u32 Target, u32 Page, + u32 Col, u8 *Buf); + +static s32 XNandPsu_ReadPage(XNandPsu *InstancePtr, u32 Target, u32 Page, + u32 Col, u8 *Buf); + +static s32 XNandPsu_CheckOnDie(XNandPsu *InstancePtr); + +static void XNandPsu_SetEccAddrSize(XNandPsu *InstancePtr); + +static s32 XNandPsu_ChangeReadColumn(XNandPsu *InstancePtr, u32 Target, + u32 Col, u32 PktSize, u32 PktCount, + u8 *Buf); + +static s32 XNandPsu_ChangeWriteColumn(XNandPsu *InstancePtr, u32 Target, + u32 Col, u32 PktSize, u32 PktCount, + u8 *Buf); + +static s32 XNandPsu_InitExtEcc(XNandPsu *InstancePtr, OnfiExtPrmPage *ExtPrm); + +static s32 XNandPsu_Data_ReadWrite(XNandPsu *InstancePtr, u8* Buf, u32 PktCount, + u32 PktSize, u32 Operation, u8 DmaMode); + +static s32 XNandPsu_WaitFor_Transfer_Complete(XNandPsu *InstancePtr); + +static s32 XNandPsu_Device_Ready(XNandPsu *InstancePtr, u32 Target); + +static void XNandPsu_Fifo_Read(XNandPsu *InstancePtr, u8* Buf, u32 Size); + +static void XNandPsu_Fifo_Write(XNandPsu *InstancePtr, u8* Buf, u32 Size); + +static void XNandPsu_Update_DmaAddr(XNandPsu *InstancePtr, u8* Buf); +/*****************************************************************************/ +/** +* +* This function initializes a specific XNandPsu instance. This function must +* be called prior to using the NAND flash device to read or write any data. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param ConfigPtr points to XNandPsu device configuration structure. +* @param EffectiveAddr is the base address of NAND flash controller. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +* @note The user needs to first call the XNandPsu_LookupConfig() API +* which returns the Configuration structure pointer which is +* passed as a parameter to the XNandPsu_CfgInitialize() API. +* +******************************************************************************/ +s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr, + u32 EffectiveAddr) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + s32 Status = XST_FAILURE; + + /* Initialize InstancePtr Config structure */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + InstancePtr->Config.BaseAddress = EffectiveAddr; + InstancePtr->Config.IsCacheCoherent = ConfigPtr->IsCacheCoherent; +#if defined (XCLOCKING) + InstancePtr->Config.RefClk = ConfigPtr->RefClk; +#endif + /* Operate in Polling Mode */ + InstancePtr->Mode = XNANDPSU_POLLING; + /* Enable MDMA mode by default */ + InstancePtr->DmaMode = XNANDPSU_MDMA; + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + +#ifdef __rtems__ + /* Set page cache to unavailable */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_UNAVAILABLE; +#endif + + /* Initialize the NAND flash targets */ + Status = XNandPsu_FlashInit(InstancePtr); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Flash init failed\r\n",__func__); +#endif + goto Out; + } + /* Set ECC mode */ + if (InstancePtr->Features.EzNand != 0U) { + InstancePtr->EccMode = XNANDPSU_EZNAND; + } else if (InstancePtr->Features.OnDie != 0U) { + InstancePtr->EccMode = XNANDPSU_ONDIE; + } else { + InstancePtr->EccMode = XNANDPSU_HWECC; + } + + /* Initialize Ecc Error flip counters */ + InstancePtr->Ecc_Stat_PerPage_flips = 0U; + InstancePtr->Ecc_Stats_total_flips = 0U; + + /* + * Scan for the bad block table(bbt) stored in the flash & load it in + * memory(RAM). If bbt is not found, create bbt by scanning factory + * marked bad blocks and store it in last good blocks of flash. + */ + XNandPsu_InitBbtDesc(InstancePtr); + Status = XNandPsu_ScanBbt(InstancePtr); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: BBT scan failed\r\n",__func__); +#endif + goto Out; + } + +#ifdef __rtems__ + /* Set page cache to none */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE; +#endif +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function initializes the NAND flash and gets the geometry information. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_FlashInit(XNandPsu *InstancePtr) +{ + u32 Target; + u8 Id[ONFI_SIG_LEN] = {0U}; + OnfiParamPage Param[ONFI_MND_PRM_PGS] = {0U}; + s32 Status = XST_FAILURE; + u32 Index; + u32 Crc; + u32 PrmPgOff; + u32 PrmPgLen; +#ifdef __ICCARM__ +#pragma pack(push, 1) + OnfiExtPrmPage ExtParam = {0U}; +#pragma pack(pop) +#else + OnfiExtPrmPage ExtParam __attribute__ ((aligned(64))) = {0U}; +#endif + + /* Clear Data Interface Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_DATA_INTF_OFFSET, 0U); + + /* Clear DMA Buffer Boundary Register */ + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_DMA_BUF_BND_OFFSET, 0U); + + for (Target = 0U; Target < XNANDPSU_MAX_TARGETS; Target++) { + /* Reset the Target */ + Status = XNandPsu_OnfiReset(InstancePtr, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Read ONFI ID */ + Status = XNandPsu_OnfiReadId(InstancePtr, Target, + ONFI_READ_ID_ADDR, + ONFI_SIG_LEN, + (u8 *)&Id[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + + if (!IS_ONFI(Id)) { + if (Target == 0U) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: ONFI ID doesn't match\r\n", + __func__); +#endif + Status = XST_FAILURE; + goto Out; + } + } + + /* Read Parameter Page */ + Status = XNandPsu_OnfiReadParamPage(InstancePtr, + Target, (u8 *)&Param[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + for(Index = 0U; Index < ONFI_MND_PRM_PGS; Index++){ + /* Check CRC */ + Crc = XNandPsu_OnfiParamPageCrc((u8*)&Param[Index], 0U, + ONFI_CRC_LEN); + if (Crc != Param[Index].Crc) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: ONFI parameter page (%d) crc check failed\r\n", + __func__, Index); +#endif + continue; + } else { + break; + } + } + if (Index >= ONFI_MND_PRM_PGS) { + Status = XST_FAILURE; + goto Out; + } + /* Fill Geometry for the first target */ + if (Target == 0U) { + Status = XNandPsu_InitGeometry(InstancePtr, &Param[Index]); + if (Status != XST_SUCCESS) { + goto Out; + } + XNandPsu_InitDataInterface(InstancePtr, &Param[Index]); + XNandPsu_InitTimingMode(InstancePtr, &Param[Index]); + XNandPsu_InitFeatures(InstancePtr, &Param[Index]); + if ((!InstancePtr->Features.EzNand) != 0U) { + Status =XNandPsu_CheckOnDie(InstancePtr); + if (Status != XST_SUCCESS) { + InstancePtr->Features.OnDie = 0U; + } + } + if ((InstancePtr->Geometry.NumBitsECC == 0xFFU) && + (InstancePtr->Features.ExtPrmPage != 0U)) { + /* ONFI 3.1 section 5.7.1.6 & 5.7.1.7 */ + PrmPgLen = (u32)Param[Index].ExtParamPageLen * 16U; + PrmPgOff = (u32)((u32)Param[Index].NumOfParamPages * + ONFI_PRM_PG_LEN) + (Index * (u32)PrmPgLen); + + Status = XNandPsu_ChangeReadColumn( + InstancePtr, Target, + PrmPgOff, PrmPgLen, 1U, + (u8 *)(void *)&ExtParam); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Check CRC */ + Crc = XNandPsu_OnfiParamPageCrc( + (u8 *)&ExtParam, + 2U, PrmPgLen); + if (Crc != ExtParam.Crc) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: ONFI extended parameter page (%d) crc check failed\r\n", + __func__, Index); +#endif + Status = XST_FAILURE; + goto Out; + } + /* Initialize Extended ECC info */ + Status = XNandPsu_InitExtEcc( + InstancePtr, + &ExtParam); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Init extended ecc failed\r\n",__func__); +#endif + goto Out; + } + } + /* Configure ECC settings */ + XNandPsu_SetEccAddrSize(InstancePtr); + } + InstancePtr->Geometry.NumTargets++; + } + /* Calculate total number of blocks and total size of flash */ + InstancePtr->Geometry.NumPages = InstancePtr->Geometry.NumTargets * + InstancePtr->Geometry.NumTargetPages; + InstancePtr->Geometry.NumBlocks = InstancePtr->Geometry.NumTargets * + InstancePtr->Geometry.NumTargetBlocks; + InstancePtr->Geometry.DeviceSize = + (u64)InstancePtr->Geometry.NumTargets * + InstancePtr->Geometry.TargetSize; + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function initializes the geometry information from ONFI parameter page. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Param is pointer to the ONFI parameter page. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_InitGeometry(XNandPsu *InstancePtr, OnfiParamPage *Param) +{ + s32 Status = XST_FAILURE; + + if (Param->BytesPerPage > XNANDPSU_MAX_PAGE_SIZE) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Invalid Bytes Per Page %d\r\n", + __func__, Param->BytesPerPage); +#endif + goto Out; + } + InstancePtr->Geometry.BytesPerPage = Param->BytesPerPage; + + + if (Param->SpareBytesPerPage > XNANDPSU_MAX_SPARE_SIZE) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Invalid Spare Bytes Per Page %d\r\n", + __func__, Param->SpareBytesPerPage); +#endif + goto Out; + } + InstancePtr->Geometry.SpareBytesPerPage = Param->SpareBytesPerPage; + + if (Param->PagesPerBlock > XNANDPSU_MAX_PAGES_PER_BLOCK) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Invalid Page Count Per Block %d\r\n", + __func__, Param->PagesPerBlock); +#endif + goto Out; + } + InstancePtr->Geometry.PagesPerBlock = Param->PagesPerBlock; + + + if (Param->BlocksPerLun > XNANDPSU_MAX_BLOCKS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Invalid block count per LUN %d\r\n", + __func__, Param->BlocksPerLun); +#endif + goto Out; + } + InstancePtr->Geometry.BlocksPerLun = Param->BlocksPerLun; + + if (Param->NumLuns > XNANDPSU_MAX_LUNS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Invalid LUN count %d\r\n", + __func__, Param->NumLuns); +#endif + goto Out; + } + InstancePtr->Geometry.NumLuns = Param->NumLuns; + + InstancePtr->Geometry.RowAddrCycles = Param->AddrCycles & 0xFU; + InstancePtr->Geometry.ColAddrCycles = (Param->AddrCycles >> 4U) & 0xFU; + InstancePtr->Geometry.NumBitsPerCell = Param->BitsPerCell; + InstancePtr->Geometry.NumBitsECC = Param->EccBits; + InstancePtr->Geometry.BlockSize = (Param->PagesPerBlock * + Param->BytesPerPage); + InstancePtr->Geometry.NumTargetBlocks = (Param->BlocksPerLun * + (u32)Param->NumLuns); + InstancePtr->Geometry.NumTargetPages = (Param->BlocksPerLun * + (u32)Param->NumLuns * + Param->PagesPerBlock); + InstancePtr->Geometry.TargetSize = ((u64)Param->BlocksPerLun * + (u64)Param->NumLuns * + (u64)Param->PagesPerBlock * + (u64)Param->BytesPerPage); + InstancePtr->Geometry.EccCodeWordSize = 9U; /* 2 power of 9 = 512 */ + if (InstancePtr->Geometry.NumTargetBlocks > XNANDPSU_MAX_BLOCKS) + xil_printf("!!! Device contains more blocks than the max defined blocks in driver\r\n"); + +#ifdef XNANDPSU_DEBUG + xil_printf("Manufacturer: %s\r\n", Param->DeviceManufacturer); + xil_printf("Device Model: %s\r\n", Param->DeviceModel); + xil_printf("Jedec ID: 0x%x\r\n", Param->JedecManufacturerId); + xil_printf("Bytes Per Page: 0x%x\r\n", Param->BytesPerPage); + xil_printf("Spare Bytes Per Page: 0x%x\r\n", Param->SpareBytesPerPage); + xil_printf("Pages Per Block: 0x%x\r\n", Param->PagesPerBlock); + xil_printf("Blocks Per LUN: 0x%x\r\n", Param->BlocksPerLun); + xil_printf("Number of LUNs: 0x%x\r\n", Param->NumLuns); + xil_printf("Number of bits per cell: 0x%x\r\n", Param->BitsPerCell); + xil_printf("Number of ECC bits: 0x%x\r\n", Param->EccBits); + xil_printf("Block Size: 0x%x\r\n", InstancePtr->Geometry.BlockSize); + + xil_printf("Number of Target Blocks: 0x%x\r\n", + InstancePtr->Geometry.NumTargetBlocks); + xil_printf("Number of Target Pages: 0x%x\r\n", + InstancePtr->Geometry.NumTargetPages); + +#endif + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function initializes the feature list from ONFI parameter page. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Param is pointer to ONFI parameter page buffer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_InitFeatures(XNandPsu *InstancePtr, OnfiParamPage *Param) +{ + InstancePtr->Features.NvDdr = ((Param->Features & (1U << 5)) != 0U) ? + 1U : 0U; + InstancePtr->Features.EzNand = ((Param->Features & (1U << 9)) != 0U) ? + 1U : 0U; + InstancePtr->Features.ExtPrmPage = ((Param->Features & (1U << 7)) != 0U) ? + 1U : 0U; +} + +/*****************************************************************************/ +/** +* +* This function initializes the Data Interface from ONFI parameter page. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Param is pointer to ONFI parameter page buffer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_InitDataInterface(XNandPsu *InstancePtr, OnfiParamPage *Param) +{ + if (Param->NVDDRTimingMode) + InstancePtr->DataInterface = XNANDPSU_NVDDR; + else if (Param->SDRTimingMode) + InstancePtr->DataInterface = XNANDPSU_SDR; +} + +/*****************************************************************************/ +/** +* +* This function initializes the Timing mode from ONFI parameter page. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Param is pointer to ONFI parameter page buffer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_InitTimingMode(XNandPsu *InstancePtr, OnfiParamPage *Param) +{ + s8 Mode; + u8 TimingMode = (u8)(Param->SDRTimingMode); + + if (InstancePtr->DataInterface == XNANDPSU_NVDDR) + TimingMode = Param->NVDDRTimingMode; + + for(Mode = XNANDPSU_MAX_TIMING_MODE; Mode >= 0; Mode--) { + if (TimingMode & (0x01 << Mode)) { + InstancePtr->TimingMode = Mode; + break; + } else { + continue; + } + } +} + +/*****************************************************************************/ +/** +* +* This function checks if the flash supports on-die ECC. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Param is pointer to ONFI parameter page. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_CheckOnDie(XNandPsu *InstancePtr) +{ + s32 Status = XST_FAILURE; + u8 JedecId[2] = {0U}; + u8 EccSetFeature[4] = {0x08U, 0x00U, 0x00U, 0x00U}; + u8 EccGetFeature[4] ={0U}; + + /* + * Check if this flash supports On-Die ECC. + * For more information, refer to Micron TN2945. + * Micron Flash: MT29F1G08ABADA, MT29F1G08ABBDA + * MT29F1G16ABBDA, + * MT29F2G08ABBEA, MT29F2G16ABBEA, + * MT29F2G08ABAEA, MT29F2G16ABAEA, + * MT29F4G08ABBDA, MT29F4G16ABBDA, + * MT29F4G08ABADA, MT29F4G16ABADA, + * MT29F8G08ADBDA, MT29F8G16ADBDA, + * MT29F8G08ADADA, MT29F8G16ADADA + */ + + /* Read JEDEC ID */ + Status = XNandPsu_OnfiReadId(InstancePtr, 0U, 0x00U, 2U, &JedecId[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + + if ((JedecId[0] == 0x2CU) && + /* 1 Gb flash devices */ + ((JedecId[1] == 0xF1U) || + (JedecId[1] == 0xA1U) || + (JedecId[1] == 0xB1U) || + /* 2 Gb flash devices */ + (JedecId[1] == 0xAAU) || + (JedecId[1] == 0xBAU) || + (JedecId[1] == 0xDAU) || + (JedecId[1] == 0xCAU) || + /* 4 Gb flash devices */ + (JedecId[1] == 0xACU) || + (JedecId[1] == 0xBCU) || + (JedecId[1] == 0xDCU) || + (JedecId[1] == 0xCCU) || + /* 8 Gb flash devices */ + (JedecId[1] == 0xA3U) || + (JedecId[1] == 0xB3U) || + (JedecId[1] == 0xD3U) || + (JedecId[1] == 0xC3U))) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Ondie flash detected, jedec id 0x%x 0x%x\r\n", + __func__, JedecId[0], JedecId[1]); +#endif + /* On-Die Set Feature */ + Status = XNandPsu_SetFeature(InstancePtr, 0U, 0x90U, + &EccSetFeature[0]); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Ondie set_feature failed\r\n", + __func__); +#endif + goto Out; + } + /* Check to see if ECC feature is set */ + Status = XNandPsu_GetFeature(InstancePtr, 0U, 0x90U, + &EccGetFeature[0]); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Ondie get_feature failed\r\n", + __func__); +#endif + goto Out; + } + if ((EccGetFeature[0] & 0x08U) != 0U) { + InstancePtr->Features.OnDie = 1U; + Status = XST_SUCCESS; + } + } else { + /* On-Die flash not found */ + Status = XST_FAILURE; + } +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function enables DMA mode of controller operation. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +void XNandPsu_EnableDmaMode(XNandPsu *InstancePtr) +{ + /* Assert the input arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->DmaMode = XNANDPSU_MDMA; +} + +/*****************************************************************************/ +/** +* +* This function disables DMA mode of driver/controller operation. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +void XNandPsu_DisableDmaMode(XNandPsu *InstancePtr) +{ + /* Assert the input arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->DmaMode = XNANDPSU_PIO; +} + +/*****************************************************************************/ +/** +* +* This function enables ECC mode of driver/controller operation. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +void XNandPsu_EnableEccMode(XNandPsu *InstancePtr) +{ + /* Assert the input arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->EccMode = XNANDPSU_HWECC; +} + +/*****************************************************************************/ +/** +* +* This function disables ECC mode of driver/controller operation. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +void XNandPsu_DisableEccMode(XNandPsu *InstancePtr) +{ + /* Assert the input arguments. */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->EccMode = XNANDPSU_NONE; +} + +#ifdef __rtems__ +#include <rtems/rtems/clock.h> +static void udelay( void ) +{ + uint64_t time = rtems_clock_get_uptime_nanoseconds() + 1000; + while (1) { + uint64_t newtime = rtems_clock_get_uptime_nanoseconds(); + if (newtime > time) { + break; + } + } +} +#define usleep(x) udelay() +#endif + +/*****************************************************************************/ +/** +* +* This function polls for a register bit set status till the timeout. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param RegOffset is the offset of register. +* @param Mask is the bitmask. +* @param Timeout is the timeout value. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_PollRegTimeout(XNandPsu *InstancePtr, u32 RegOffset, + u32 Mask, u32 Timeout) +{ + s32 Status = XST_FAILURE; + volatile u32 RegVal; + u32 TimeoutVar = Timeout; + + while (TimeoutVar > 0U) { + RegVal = XNandPsu_ReadReg(InstancePtr->Config.BaseAddress, + RegOffset) & Mask; + if (RegVal != 0U) { + break; + } + TimeoutVar--; + usleep(1); + } + + if (TimeoutVar <= 0U) { + Status = XST_FAILURE; + } else { + Status = XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sets packet size and packet count values in packet register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param PktSize is the packet size. +* @param PktCount is the packet count. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SetPktSzCnt(XNandPsu *InstancePtr, u32 PktSize, + u32 PktCount) +{ + /* Update Packet Register with pkt size and count */ + XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_PKT_OFFSET, + ((u32)XNANDPSU_PKT_PKT_SIZE_MASK | + (u32)XNANDPSU_PKT_PKT_CNT_MASK), + ((PktSize & XNANDPSU_PKT_PKT_SIZE_MASK) | + ((PktCount << XNANDPSU_PKT_PKT_CNT_SHIFT) & + XNANDPSU_PKT_PKT_CNT_MASK))); +} + +/*****************************************************************************/ +/** +* +* This function sets Page and Column values in the Memory address registers. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Page is the page value. +* @param Col is the column value. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SetPageColAddr(XNandPsu *InstancePtr, u32 Page, u16 Col) +{ + /* Program Memory Address Register 1 */ + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_MEM_ADDR1_OFFSET, + (((u32)Col & XNANDPSU_MEM_ADDR1_COL_ADDR_MASK) | + ((Page << (u32)XNANDPSU_MEM_ADDR1_PG_ADDR_SHIFT) & + XNANDPSU_MEM_ADDR1_PG_ADDR_MASK))); + /* Program Memory Address Register 2 */ + XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_MEM_ADDR2_OFFSET, + XNANDPSU_MEM_ADDR2_MEM_ADDR_MASK, + ((Page >> XNANDPSU_MEM_ADDR1_PG_ADDR_SHIFT) & + XNANDPSU_MEM_ADDR2_MEM_ADDR_MASK)); +} + +/*****************************************************************************/ +/** +* +* This function sets the size of page in Command Register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SetPageSize(XNandPsu *InstancePtr) +{ + u32 PageSizeMask = 0; + u32 PageSize = InstancePtr->Geometry.BytesPerPage; + + /* Calculate page size mask */ + switch(PageSize) { + case XNANDPSU_PAGE_SIZE_512: + PageSizeMask = (0U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + case XNANDPSU_PAGE_SIZE_2K: + PageSizeMask = (1U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + case XNANDPSU_PAGE_SIZE_4K: + PageSizeMask = (2U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + case XNANDPSU_PAGE_SIZE_8K: + PageSizeMask = (3U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + case XNANDPSU_PAGE_SIZE_16K: + PageSizeMask = (4U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + case XNANDPSU_PAGE_SIZE_1K_16BIT: + PageSizeMask = (5U << XNANDPSU_CMD_PG_SIZE_SHIFT); + break; + default: + /* Not supported */ + break; + } + /* Update Command Register */ + XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_CMD_OFFSET, + XNANDPSU_CMD_PG_SIZE_MASK, PageSizeMask); +} + +/*****************************************************************************/ +/** +* +* This function setup the Ecc Register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SetEccAddrSize(XNandPsu *InstancePtr) +{ + u32 PageSize = InstancePtr->Geometry.BytesPerPage; + u32 CodeWordSize = InstancePtr->Geometry.EccCodeWordSize; + u32 NumEccBits = InstancePtr->Geometry.NumBitsECC; + u32 Index; + u32 Found = 0U; + u8 BchModeVal; + + for (Index = 0U; Index < (sizeof(EccMatrix)/sizeof(XNandPsu_EccMatrix)); + Index++) { + if ((EccMatrix[Index].PageSize == PageSize) && + (EccMatrix[Index].CodeWordSize >= CodeWordSize)) { + if (EccMatrix[Index].NumEccBits >= NumEccBits) { + Found = Index; + break; + } + else { + Found = Index; + } + } + } + + if (Found != 0U) { + if(InstancePtr->Geometry.SpareBytesPerPage < 64U) { + InstancePtr->EccCfg.EccAddr = (u16)PageSize; + } + else { + InstancePtr->EccCfg.EccAddr = ((u16)PageSize + + (InstancePtr->Geometry.SpareBytesPerPage + - EccMatrix[Found].EccSize)); + } + InstancePtr->EccCfg.EccSize = EccMatrix[Found].EccSize; + InstancePtr->EccCfg.NumEccBits = EccMatrix[Found].NumEccBits; + InstancePtr->EccCfg.CodeWordSize = + EccMatrix[Found].CodeWordSize; +#ifdef XNANDPSU_DEBUG + xil_printf("ECC: addr 0x%x size 0x%x numbits %d " + "codesz %d\r\n", + InstancePtr->EccCfg.EccAddr, + InstancePtr->EccCfg.EccSize, + InstancePtr->EccCfg.NumEccBits, + InstancePtr->EccCfg.CodeWordSize); +#endif + if (EccMatrix[Found].IsBCH == XNANDPSU_HAMMING) { + InstancePtr->EccCfg.IsBCH = 0U; + } else { + InstancePtr->EccCfg.IsBCH = 1U; + } + /* Write ECC register */ + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + (u32)XNANDPSU_ECC_OFFSET, + ((u32)InstancePtr->EccCfg.EccAddr | + ((u32)InstancePtr->EccCfg.EccSize << (u32)16) | + ((u32)InstancePtr->EccCfg.IsBCH << (u32)27))); + + if (EccMatrix[Found].IsBCH == XNANDPSU_BCH) { + /* Write memory address register 2 */ + switch(InstancePtr->EccCfg.NumEccBits) { + case 16U: + BchModeVal = 0x0U; + break; + case 12U: + BchModeVal = 0x1U; + break; + case 8U: + BchModeVal = 0x2U; + break; + case 4U: + BchModeVal = 0x3U; + break; + case 24U: + BchModeVal = 0x4U; + break; + default: + BchModeVal = 0x0U; + break; + } + XNandPsu_ReadModifyWrite(InstancePtr, + XNANDPSU_MEM_ADDR2_OFFSET, + XNANDPSU_MEM_ADDR2_NFC_BCH_MODE_MASK, + ((u32)BchModeVal << + (u32)XNANDPSU_MEM_ADDR2_NFC_BCH_MODE_SHIFT)); + } + } +} + +/*****************************************************************************/ +/** +* +* This function setup the Ecc Spare Command Register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SetEccSpareCmd(XNandPsu *InstancePtr, u16 SpareCmd, + u8 AddrCycles) +{ + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + (u32)XNANDPSU_ECC_SPR_CMD_OFFSET, + (u32)SpareCmd | ((u32)AddrCycles << 28U)); +} + +/*****************************************************************************/ +/** +* +* This function sets the chip select value in memory address2 register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_SelectChip(XNandPsu *InstancePtr, u32 Target) +{ +#if defined (XCLOCKING) + Xil_ClockEnable(InstancePtr->Config.RefClk); +#endif + /* Update Memory Address2 register with chip select */ + XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_MEM_ADDR2_OFFSET, + XNANDPSU_MEM_ADDR2_CHIP_SEL_MASK, + ((Target << XNANDPSU_MEM_ADDR2_CHIP_SEL_SHIFT) & + XNANDPSU_MEM_ADDR2_CHIP_SEL_MASK)); +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Reset command to the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_OnfiReset(XNandPsu *InstancePtr, u32 Target) +{ + s32 Status = XST_FAILURE; + + /* Enable Transfer Complete Interrupt in Interrupt Status Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK); + /* Program Command Register */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RST, ONFI_CMD_INVALID, 0U, + 0U, 0U); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Reset in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET, XNANDPSU_PROG_RST_MASK); + + /* Poll for Transfer Complete event */ + Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Read Status command to the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param OnfiStatus is the ONFI status value to return. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_OnfiReadStatus(XNandPsu *InstancePtr, u32 Target, + u16 *OnfiStatus) +{ + s32 Status = XST_FAILURE; + + /* Enable Transfer Complete Interrupt in Interrupt Status Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK); + /* Program Command Register */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_STS, ONFI_CMD_INVALID, + 0U, 0U, 0U); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Program Packet Size and Packet Count */ + if(InstancePtr->DataInterface == XNANDPSU_SDR) + XNandPsu_SetPktSzCnt(InstancePtr, 1U, 1U); + else + XNandPsu_SetPktSzCnt(InstancePtr, 2U, 1U); + + /* Set Read Status in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_STS_MASK); + /* Poll for Transfer Complete event */ + Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr); + /* Read Flash Status */ + *OnfiStatus = (u16) XNandPsu_ReadReg(InstancePtr->Config.BaseAddress, + XNANDPSU_FLASH_STS_OFFSET); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Read ID command to the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Buf is the ONFI ID value to return. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_OnfiReadId(XNandPsu *InstancePtr, u32 Target, u8 IdAddr, + u32 IdLen, u8 *Buf) +{ + s32 Status = XST_FAILURE; + u32 Index; + u32 Rem; + u32 RegVal; + u32 RemIdx; + + u32 *BufPtr = (u32 *)(void *)Buf; + + /* + * Enable Buffer Read Ready Interrupt in Interrupt Status Enable + * Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK); + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_ID, ONFI_CMD_INVALID, 0U, + 0U, ONFI_READ_ID_ADDR_CYCLES); + + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0U, IdAddr); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, IdLen, 1U); + /* Set Read ID in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_ID_MASK); + + /* Poll for Buffer Read Ready event */ + Status = XNandPsu_PollRegTimeout( + InstancePtr, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK, + XNANDPSU_INTR_POLL_TIMEOUT); + if (Status != XST_SUCCESS) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Poll for buf read ready timeout\r\n", + __func__); +#endif + goto Out; + } + /* + * Enable Transfer Complete Interrupt in Interrupt + * Status Enable Register + */ + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK); + + /* + * Clear Buffer Read Ready Interrupt in Interrupt Status + * Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK); + /* Read Packet Data from Data Port Register */ + for (Index = 0U; Index < (IdLen/4); Index++) { + *(BufPtr+Index) = XNandPsu_ReadReg( + InstancePtr->Config.BaseAddress, + XNANDPSU_BUF_DATA_PORT_OFFSET); + } + Rem = IdLen % 4; + if (Rem != 0U) { + RegVal = XNandPsu_ReadReg( + InstancePtr->Config.BaseAddress, + XNANDPSU_BUF_DATA_PORT_OFFSET); + for (RemIdx = 0U; RemIdx < Rem; RemIdx++) { + *(Buf + (Index * 4U) + RemIdx) = (u8) (RegVal >> + (RemIdx * 8U)) & 0xFFU; + } + } + + Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr); + +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends the ONFI Read Parameter Page command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param PrmIndex is the index of parameter page. +* @param Buf is the parameter page information to return. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_OnfiReadParamPage(XNandPsu *InstancePtr, u32 Target, + u8 *Buf) +{ + s32 Status = XST_FAILURE; + + /* + * Enable Buffer Read Ready Interrupt in Interrupt Status Enable + * Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK); + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_PRM_PG, ONFI_CMD_INVALID, + 0U, 0U, ONFI_PRM_PG_ADDR_CYCLES); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0U, 0U); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, ONFI_MND_PRM_PGS*ONFI_PRM_PG_LEN, 1U); + /* Set Read Parameter Page in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_PRM_PG_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, 1U, ONFI_MND_PRM_PGS*ONFI_PRM_PG_LEN, 0, 0); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function returns the length including bad blocks from a given offset and +* length. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @param Offset is the flash data address to read from. +* @param Length is number of bytes to read. +* +* @return +* - Return actual length including bad blocks. +* +* @note None. +* +******************************************************************************/ +static s32 XNandPsu_CalculateLength(XNandPsu *InstancePtr, u64 Offset, + u64 Length) +{ + s32 Status; + u32 BlockSize; + u32 BlockLen; + u32 Block; + u64 TempLen = 0; + u64 OffsetVar = Offset; + + BlockSize = InstancePtr->Geometry.BlockSize; + + while (TempLen < Length) { + Block = (u32)(OffsetVar/BlockSize); + BlockLen = BlockSize - (u32)(OffsetVar % BlockSize); + if (OffsetVar >= InstancePtr->Geometry.DeviceSize) { + Status = XST_FAILURE; + goto Out; + } + /* Check if the block is bad */ + Status = XNandPsu_IsBlockBad(InstancePtr, Block); + if (Status != XST_SUCCESS) { + /* Good block */ + TempLen += BlockLen; + } + OffsetVar += BlockLen; + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function writes to the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Offset is the starting offset of flash to write. +* @param Length is the number of bytes to write. +* @param SrcBuf is the source data buffer to write. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_Write(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *SrcBuf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(SrcBuf != NULL); + Xil_AssertNonvoid(Length != 0U); + Xil_AssertNonvoid((Offset + Length) <= + InstancePtr->Geometry.DeviceSize); + + s32 Status = XST_FAILURE; + u32 Page; + u32 Col; + u32 Target; + u32 Block; + u32 PartialBytes = 0; + u32 NumBytes; + u32 RemLen; + u8 *BufPtr; + u8 *SrcBufPtr = (u8 *)SrcBuf; + u64 OffsetVar = Offset; + u64 LengthVar = Length; + + /* + * Check if write operation exceeds flash size when including + * bad blocks. + */ + Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar); + if (Status != XST_SUCCESS) { + goto Out; + } + +#ifdef __rtems__ + if (InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) { + /* All writes invalidate the page cache */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE; + } +#endif + while (LengthVar > 0U) { + Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize); + /* + * Skip the bad blocks. Increment the offset by block size. + * For better results, always program the flash starting at + * a block boundary. + */ + if (XNandPsu_IsBlockBad(InstancePtr, Block) == XST_SUCCESS) { + OffsetVar += (u64)InstancePtr->Geometry.BlockSize; + continue; + } + /* Calculate Page and Column address values */ + Page = (u32) (OffsetVar/InstancePtr->Geometry.BytesPerPage); + Col = (u32) (OffsetVar & + (InstancePtr->Geometry.BytesPerPage - 1U)); + PartialBytes = 0U; + /* + * Check if partial write. + * If column address is > 0 or Length is < page size + */ + if ((Col > 0U) || + (LengthVar < InstancePtr->Geometry.BytesPerPage)) { + RemLen = InstancePtr->Geometry.BytesPerPage - Col; + PartialBytes = (RemLen < (u32)LengthVar) ? + RemLen : (u32)LengthVar; + } + + Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize); +#ifdef __rtems__ + { +#else + if (Page > InstancePtr->Geometry.NumTargetPages) { +#endif + Page %= InstancePtr->Geometry.NumTargetPages; + } + + /* Check if partial write */ + if (PartialBytes > 0U) { + BufPtr = &InstancePtr->PartialDataBuf[0]; + (void)memset(BufPtr, 0xFF, + InstancePtr->Geometry.BytesPerPage); + (void)Xil_MemCpy(BufPtr + Col, SrcBufPtr, PartialBytes); + + NumBytes = PartialBytes; + } else { + BufPtr = (u8 *)SrcBufPtr; + NumBytes = (InstancePtr->Geometry.BytesPerPage < + (u32)LengthVar) ? + InstancePtr->Geometry.BytesPerPage : + (u32)LengthVar; + } + /* Program page */ + Status = XNandPsu_ProgramPage(InstancePtr, Target, Page, 0U, + BufPtr); + if (Status != XST_SUCCESS) + goto Out; + + Status = XNandPsu_Device_Ready(InstancePtr, Target); + if (Status != XST_SUCCESS) + goto Out; + + SrcBufPtr += NumBytes; + OffsetVar += NumBytes; + LengthVar -= NumBytes; + } + +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function reads from the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Offset is the starting offset of flash to read. +* @param Length is the number of bytes to read. +* @param DestBuf is the destination data buffer to fill in. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_Read(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *DestBuf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(DestBuf != NULL); + Xil_AssertNonvoid(Length != 0U); + Xil_AssertNonvoid((Offset + Length) <= + InstancePtr->Geometry.DeviceSize); + + s32 Status = XST_FAILURE; + u32 Page; + u32 Col; + u32 Target; + u32 Block; + u32 PartialBytes = 0U; + u32 RemLen; + u32 NumBytes; + u8 *BufPtr; + u8 *DestBufPtr = (u8 *)DestBuf; + u64 OffsetVar = Offset; + u64 LengthVar = Length; + + /* + * Check if read operation exceeds flash size when including + * bad blocks. + */ + Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar); + if (Status != XST_SUCCESS) { + goto Out; + } + + while (LengthVar > 0U) { + Block = (u32)(OffsetVar/InstancePtr->Geometry.BlockSize); + /* + * Skip the bad block. Increment the offset by block size. + * The flash programming utility must make sure to start + * writing always at a block boundary and skip blocks if any. + */ + if (XNandPsu_IsBlockBad(InstancePtr, Block) == XST_SUCCESS) { + OffsetVar += (u64)InstancePtr->Geometry.BlockSize; + continue; + } + /* Calculate Page and Column address values */ + Page = (u32) (OffsetVar/InstancePtr->Geometry.BytesPerPage); + Col = (u32) (OffsetVar & + (InstancePtr->Geometry.BytesPerPage - 1U)); + PartialBytes = 0U; + /* + * Check if partial write. + * If column address is > 0 or Length is < page size + */ + if ((Col > 0U) || + (LengthVar < InstancePtr->Geometry.BytesPerPage)) { + RemLen = InstancePtr->Geometry.BytesPerPage - Col; + PartialBytes = ((u32)RemLen < (u32)LengthVar) ? + (u32)RemLen : (u32)LengthVar; + } + + Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize); +#ifdef __rtems__ + { +#else + if (Page > InstancePtr->Geometry.NumTargetPages) { +#endif + Page %= InstancePtr->Geometry.NumTargetPages; + } + /* Check if partial read */ + if (PartialBytes > 0U) { + BufPtr = &InstancePtr->PartialDataBuf[0]; + NumBytes = PartialBytes; + } else { + BufPtr = DestBufPtr; + NumBytes = (InstancePtr->Geometry.BytesPerPage < + (u32)LengthVar) ? + InstancePtr->Geometry.BytesPerPage : + (u32)LengthVar; + } +#ifdef __rtems__ + if (Page == InstancePtr->PartialDataPageIndex) { + /* + * This is a whole page read for the currently cached + * page. It will not be taken care of below, so perform + * the copy here. + */ + if (PartialBytes == 0U) { + (void)Xil_MemCpy(DestBufPtr, + &InstancePtr->PartialDataBuf[0], + NumBytes); + } + } else { +#endif + /* Read page */ + Status = XNandPsu_ReadPage(InstancePtr, Target, Page, 0U, + BufPtr); +#ifdef __rtems__ + if (PartialBytes > 0U && + InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) { + /* + * Partial read into page cache. Update the + * cached page index. + */ + InstancePtr->PartialDataPageIndex = Page; + } + } +#endif + if (Status != XST_SUCCESS) { + goto Out; + } + if (PartialBytes > 0U) { + (void)Xil_MemCpy(DestBufPtr, BufPtr + Col, NumBytes); +#ifdef __rtems__ + /* The destination buffer is touched by hardware, synchronize */ + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)DestBufPtr, NumBytes); + } +#endif + } + DestBufPtr += NumBytes; + OffsetVar += NumBytes; + LengthVar -= NumBytes; + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function erases the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Offset is the starting offset of flash to erase. +* @param Length is the number of bytes to erase. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note +* The Offset and Length should be aligned to block size boundary +* to get better results. +* +******************************************************************************/ +s32 XNandPsu_Erase(XNandPsu *InstancePtr, u64 Offset, u64 Length) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Length != 0U); + Xil_AssertNonvoid((Offset + Length) <= + InstancePtr->Geometry.DeviceSize); + + s32 Status = XST_FAILURE; + u32 Target = 0; + u32 StartBlock; + u32 NumBlocks = 0; + u32 Block; + u32 AlignOff; + u32 EraseLen; + u32 BlockRemLen; + u64 OffsetVar = Offset; + u64 LengthVar = Length; + + /* + * Check if erase operation exceeds flash size when including + * bad blocks. + */ + Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Calculate number of blocks to erase */ + StartBlock = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize); + + while (LengthVar > 0U) { + Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize); + if (XNandPsu_IsBlockBad(InstancePtr, Block) == + XST_SUCCESS) { + OffsetVar += (u64)InstancePtr->Geometry.BlockSize; + NumBlocks++; + continue; + } + + AlignOff = (u32)OffsetVar & + (InstancePtr->Geometry.BlockSize - (u32)1); + if (AlignOff > 0U) { + BlockRemLen = InstancePtr->Geometry.BlockSize - + AlignOff; + EraseLen = (BlockRemLen < (u32)LengthVar) ? + BlockRemLen :(u32)LengthVar; + } else { + EraseLen = (InstancePtr->Geometry.BlockSize < + (u32)LengthVar) ? + InstancePtr->Geometry.BlockSize: + (u32)LengthVar; + } + NumBlocks++; + OffsetVar += EraseLen; + LengthVar -= EraseLen; + } + + for (Block = StartBlock; Block < (StartBlock + NumBlocks); Block++) { + Target = Block/InstancePtr->Geometry.NumTargetBlocks; +#ifdef __rtems__ + u32 ModBlock = Block % InstancePtr->Geometry.NumTargetBlocks; +#else + Block %= InstancePtr->Geometry.NumTargetBlocks; +#endif + /* Don't erase bad block */ + if (XNandPsu_IsBlockBad(InstancePtr, Block) == + XST_SUCCESS) + continue; + /* Block Erase */ +#ifdef __rtems__ + Status = XNandPsu_EraseBlock(InstancePtr, Target, ModBlock); +#else + Status = XNandPsu_EraseBlock(InstancePtr, Target, Block); +#endif + if (Status != XST_SUCCESS) + goto Out; + + Status = XNandPsu_Device_Ready(InstancePtr, Target); + if (Status != XST_SUCCESS) + goto Out; + + } +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Program Page command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Page is the page address value to program. +* @param Col is the column address value to program. +* @param Buf is the data buffer to program. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_ProgramPage(XNandPsu *InstancePtr, u32 Target, u32 Page, + u32 Col, u8 *Buf) +{ + u32 PktSize; + u32 PktCount; + s32 Status = XST_FAILURE; + u32 IsrValue; + u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles + + InstancePtr->Geometry.ColAddrCycles; + + if (InstancePtr->EccCfg.CodeWordSize > 9U) { + PktSize = 1024U; + } else { + PktSize = 512U; + } + PktCount = InstancePtr->Geometry.BytesPerPage/PktSize; + + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_PG_PROG1, ONFI_CMD_PG_PROG2, + 1U, 1U, (u8)AddrCycles); + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + IsrValue = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK | + XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK; + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + XNandPsu_Update_DmaAddr(InstancePtr, Buf); + } else { + IsrValue = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, IsrValue); + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, Page, (u16)Col); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set ECC */ + if (InstancePtr->EccMode == XNANDPSU_HWECC) { + XNandPsu_SetEccSpareCmd(InstancePtr, ONFI_CMD_CHNG_WR_COL, + InstancePtr->Geometry.ColAddrCycles); + } + /* Set Page Program in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_PG_PROG_MASK); + + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 1); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Program Page command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Page is the page address value to program. +* @param Buf is the data buffer to program. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_WriteSpareBytes(XNandPsu *InstancePtr, u32 Page, u8 *Buf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Page < InstancePtr->Geometry.NumPages); + Xil_AssertNonvoid(Buf != NULL); + + u32 PktCount = 1U; + u16 PreEccSpareCol = 0U; + u16 PreEccSpareWrCnt = 0U; + u16 PostEccSpareCol = 0U; + u16 PostEccSpareWrCnt = 0U; + u32 PostWrite = 0U; + OnfiCmdFormat Cmd; + s32 Status = XST_FAILURE; + u32 RegVal; + u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles + + InstancePtr->Geometry.ColAddrCycles; + u32 Col = InstancePtr->Geometry.BytesPerPage; + u32 Target = Page/InstancePtr->Geometry.NumTargetPages; + u32 PktSize = InstancePtr->Geometry.SpareBytesPerPage; + u32 *BufPtr = (u32 *)(void *)Buf; + u32 PageVar = Page; + + PageVar %= InstancePtr->Geometry.NumTargetPages; + + if (InstancePtr->EccMode == XNANDPSU_HWECC) { + /* Calculate ECC free positions before and after ECC code */ + PreEccSpareCol = 0x0U; + PreEccSpareWrCnt = InstancePtr->EccCfg.EccAddr - + (u16)InstancePtr->Geometry.BytesPerPage; + + PostEccSpareCol = PreEccSpareWrCnt + + InstancePtr->EccCfg.EccSize; + PostEccSpareWrCnt = InstancePtr->Geometry.SpareBytesPerPage - + PostEccSpareCol; + + PreEccSpareWrCnt = (PreEccSpareWrCnt/4U) * 4U; + PostEccSpareWrCnt = (PostEccSpareWrCnt/4U) * 4U; + + if (PreEccSpareWrCnt > 0U) { + PktSize = PreEccSpareWrCnt; + PktCount = 1U; + Col = InstancePtr->Geometry.BytesPerPage + + PreEccSpareCol; + BufPtr = (u32 *)(void *)Buf; + if (PostEccSpareWrCnt > 0U) { + PostWrite = 1U; + } + } else if (PostEccSpareWrCnt > 0U) { + PktSize = PostEccSpareWrCnt; + PktCount = 1U; + Col = InstancePtr->Geometry.BytesPerPage + + PostEccSpareCol; + BufPtr = (u32 *)(Buf + Col); + } else { + /* No free spare bytes available for writing */ + Status = XST_FAILURE; + goto Out; + } + } + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK; + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)BufPtr, (PktSize * PktCount)); + } + XNandPsu_Update_DmaAddr(InstancePtr, (u8 *)BufPtr); + } else { + RegVal = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, RegVal); + /* Program Command hack for change write column */ + if (PostWrite > 0U) { + Cmd.Command1 = 0x80U; + Cmd.Command2 = 0x00U; + XNandPsu_Prepare_Cmd(InstancePtr, Cmd.Command1, Cmd.Command2, + 0U , 1U, (u8)AddrCycles); + + } else { + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_PG_PROG1, + ONFI_CMD_PG_PROG2, 0U , 1U, (u8)AddrCycles); + } + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, PageVar, (u16)Col); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Page Program in Program Register */ + if (PostWrite > 0U) { + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,((u32)XNANDPSU_PROG_PG_PROG_MASK | + (u32)XNANDPSU_PROG_CHNG_ROW_ADDR_MASK)); + } else { + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_PG_PROG_MASK); + } + + Status = XNandPsu_Data_ReadWrite(InstancePtr, (u8 *)BufPtr, PktCount, + PktSize, 1, 1); + + if (InstancePtr->EccMode == XNANDPSU_HWECC) { + if (PostWrite > 0U) { + BufPtr = (u32 *)(Buf + PostEccSpareCol); + Status = XNandPsu_ChangeWriteColumn(InstancePtr, + Target, + PostEccSpareCol, PostEccSpareWrCnt, 1U, + (u8 *)(void *)BufPtr); + if (Status != XST_SUCCESS) { + goto Out; + } + } + } +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Read Page command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Page is the page address value to read. +* @param Col is the column address value to read. +* @param Buf is the data buffer to fill in. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_ReadPage(XNandPsu *InstancePtr, u32 Target, u32 Page, + u32 Col, u8 *Buf) +{ + u32 PktSize; + u32 PktCount; + s32 Status = XST_FAILURE; + u32 RegVal; + u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles + + InstancePtr->Geometry.ColAddrCycles; + + if (InstancePtr->EccCfg.CodeWordSize > 9U) { + PktSize = 1024U; + } else { + PktSize = 512U; + } + PktCount = InstancePtr->Geometry.BytesPerPage/PktSize; + + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD1, ONFI_CMD_RD2, + 1U, 1U, (u8)AddrCycles); + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK | + XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK; + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + XNandPsu_Update_DmaAddr(InstancePtr, Buf); + } else { + RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK; + } + /* Enable Single bit error and Multi bit error */ + if (InstancePtr->EccMode == XNANDPSU_HWECC) + RegVal |= XNANDPSU_INTR_STS_EN_MUL_BIT_ERR_STS_EN_MASK | + XNANDPSU_INTR_STS_EN_ERR_INTR_STS_EN_MASK; + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, RegVal); + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, Page, (u16)Col); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set ECC */ + if (InstancePtr->EccMode == XNANDPSU_HWECC) { + XNandPsu_SetEccSpareCmd(InstancePtr, + (ONFI_CMD_CHNG_RD_COL1 | + (ONFI_CMD_CHNG_RD_COL2 << (u8)8U)), + InstancePtr->Geometry.ColAddrCycles); + } + + /* Set Read command in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1); + +#ifdef __rtems__ + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + } +#endif + + /* Check ECC Errors */ + if (InstancePtr->EccMode == XNANDPSU_HWECC) { + /* Hamming Multi Bit Errors */ + if (((u32)XNandPsu_ReadReg(InstancePtr->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET) & + (u32)XNANDPSU_INTR_STS_MUL_BIT_ERR_STS_EN_MASK) != 0U) { + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_MUL_BIT_ERR_STS_EN_MASK); + +#ifdef XNANDPSU_DEBUG + xil_printf("%s: ECC Hamming multi bit error\r\n", + __func__); +#endif + InstancePtr->Ecc_Stat_PerPage_flips = + ((XNandPsu_ReadReg( + InstancePtr->Config.BaseAddress, + XNANDPSU_ECC_ERR_CNT_OFFSET) & + 0x1FF00U) >> 8U); + InstancePtr->Ecc_Stats_total_flips += + InstancePtr->Ecc_Stat_PerPage_flips; + Status = XST_FAILURE; + } + /* Hamming Single Bit or BCH Errors */ + if (((u32)XNandPsu_ReadReg(InstancePtr->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET) & + (u32)XNANDPSU_INTR_STS_ERR_INTR_STS_EN_MASK) != 0U) { + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_ERR_INTR_STS_EN_MASK); + + if (InstancePtr->EccCfg.IsBCH == 1U) { + InstancePtr->Ecc_Stat_PerPage_flips = + ((XNandPsu_ReadReg( + InstancePtr->Config.BaseAddress, + XNANDPSU_ECC_ERR_CNT_OFFSET)& + 0x1FF00U) >> 8U); + InstancePtr->Ecc_Stats_total_flips += + InstancePtr->Ecc_Stat_PerPage_flips; + Status = XST_SUCCESS; + } + } + } + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function reads spare bytes from flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Page is the page address value to read. +* @param Buf is the data buffer to fill in. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_ReadSpareBytes(XNandPsu *InstancePtr, u32 Page, u8 *Buf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Page < InstancePtr->Geometry.NumPages); + Xil_AssertNonvoid(Buf != NULL); + + u32 PktCount = 1U; + s32 Status = XST_FAILURE; + u32 RegVal; + u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles + + InstancePtr->Geometry.ColAddrCycles; + u32 Col = InstancePtr->Geometry.BytesPerPage; + u32 Target = Page/InstancePtr->Geometry.NumTargetPages; + u32 PktSize = InstancePtr->Geometry.SpareBytesPerPage; + u32 PageVar = Page; + + PageVar %= InstancePtr->Geometry.NumTargetPages; + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK; + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + XNandPsu_Update_DmaAddr(InstancePtr, Buf); + } else { + RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK; + } + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, RegVal); + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD1, ONFI_CMD_RD2, 0U, + 1U, (u8)AddrCycles); + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, PageVar, (u16)Col); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Read command in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1); + +#ifdef __rtems__ + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + } +#endif + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI block erase command to the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Block is the block to erase. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_EraseBlock(XNandPsu *InstancePtr, u32 Target, u32 Block) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS); +#ifdef __rtems__ + Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumTargetBlocks); +#else + Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks); +#endif + + s32 Status = XST_FAILURE; + u32 Page; + u32 ErasePage; + u32 EraseCol; + u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles; + + Page = Block * InstancePtr->Geometry.PagesPerBlock; + ErasePage = (Page >> 16U) & 0xFFFFU; + EraseCol = Page & 0xFFFFU; + + /* + * Enable Transfer Complete Interrupt in Interrupt Status Enable + * Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK); + + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_BLK_ERASE1, + ONFI_CMD_BLK_ERASE2, 0U , 0U, (u8)AddrCycles); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, ErasePage, (u16)EraseCol); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Block Erase in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_BLK_ERASE_MASK); + /* Poll for Transfer Complete event */ + Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr); + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Get Feature command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Feature is the feature selector. +* @param Buf is the buffer to fill feature value. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_GetFeature(XNandPsu *InstancePtr, u32 Target, u8 Feature, + u8 *Buf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) + Xil_AssertNonvoid(Buf != NULL); + Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS); + + s32 Status; + u32 PktSize = 4; + u32 PktCount = 1; + + if (InstancePtr->DataInterface == XNANDPSU_NVDDR) { + PktSize = 8U; + } + + /* + * Enable Buffer Read Ready Interrupt in Interrupt Status + * Enable Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK); + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_GET_FEATURES, + ONFI_CMD_INVALID, 0U, 0U, 1U); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0x0U, Feature); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Set Read Parameter Page in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_GET_FEATURES_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 0); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sends ONFI Set Feature command to flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Feature is the feature selector. +* @param Buf is the feature value to send. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_SetFeature(XNandPsu *InstancePtr, u32 Target, u8 Feature, + u8 *Buf) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) + Xil_AssertNonvoid(Buf != NULL); + Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS); + + s32 Status; + u32 PktSize = 4U; + u32 PktCount = 1U; + + if (InstancePtr->DataInterface == XNANDPSU_NVDDR) { + PktSize = 8U; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, 0U); + + /* + * Enable Buffer Write Ready Interrupt in Interrupt Status + * Enable Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK); + + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_SET_FEATURES, + ONFI_CMD_INVALID, 0U , 0U, 1U); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0x0U, Feature); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Set Read Parameter Page in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_SET_FEATURES_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 0); + return Status; +} + +/*****************************************************************************/ +/** +* +* This function changes clock frequency of flash controller. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param ClockFreq is the clock frequency to change. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_ChangeClockFreq(XNandPsu *InstancePtr, u32 ClockFreq) +{ + (void) InstancePtr; + (void) ClockFreq; + + /* Not implemented */ +} +/*****************************************************************************/ +/** +* +* This function changes the data interface and timing mode. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param NewIntf is the new data interface. +* @param NewMode is the new timing mode. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +s32 XNandPsu_ChangeTimingMode(XNandPsu *InstancePtr, + XNandPsu_DataInterface NewIntf, + XNandPsu_TimingMode NewMode) +{ + /* Assert the input arguments. */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + s32 Status = XST_SUCCESS; + u32 Target; + u32 RegVal; + u8 Buf[4] = {0U}; + u32 *Feature = (u32 *)(void *)&Buf[0]; + u32 SetFeature = 0U; + u32 NewModeVar = (u32)NewMode; + + /* Check for valid input arguments */ + if(((NewIntf != XNANDPSU_SDR) && (NewIntf != XNANDPSU_NVDDR)) || + (NewModeVar > 5U)){ + Status = XST_FAILURE; + goto Out; + } + + if(NewIntf == XNANDPSU_NVDDR){ + NewModeVar = NewModeVar | (u32)0x10; + } + /* Get current data interface type and timing mode */ + XNandPsu_DataInterface CurIntf = InstancePtr->DataInterface; + XNandPsu_TimingMode CurMode = InstancePtr->TimingMode; + + /* Check if the flash is in same mode */ + if ((CurIntf == NewIntf) && (CurMode == NewModeVar)) { + Status = XST_SUCCESS; + goto Out; + } + + if ((CurIntf == XNANDPSU_NVDDR) && (NewIntf == XNANDPSU_SDR)) { + + NewModeVar = XNANDPSU_SDR0; + + /* Change the clock frequency */ + XNandPsu_ChangeClockFreq(InstancePtr, XNANDPSU_SDR_CLK); + + /* Update Data Interface Register */ + RegVal = ((NewModeVar % 6U) << ((NewIntf == XNANDPSU_NVDDR) ? 3U : 0U)) | + ((u32)NewIntf << XNANDPSU_DATA_INTF_DATA_INTF_SHIFT); + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_DATA_INTF_OFFSET, RegVal); + + for (Target = 0U; Target < InstancePtr->Geometry.NumTargets; + Target++) { + Status = XNandPsu_OnfiReset(InstancePtr, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + /* Set Feature */ + for (Target = 0U; Target < InstancePtr->Geometry.NumTargets; + Target++) { + Status = XNandPsu_SetFeature(InstancePtr, Target, 0x01U, + (u8 *)(void *)&NewModeVar); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + InstancePtr->DataInterface = NewIntf; + InstancePtr->TimingMode = NewModeVar; + + for (Target = 0U; Target < InstancePtr->Geometry.NumTargets; + Target++) { + Status = XNandPsu_GetFeature(InstancePtr, Target, 0x01U, + &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Check if set_feature was successful */ + if (*Feature != NewModeVar) { + Status = XST_FAILURE; + goto Out; + } + } + + goto Out; + } + + SetFeature = NewModeVar; + if((CurIntf == XNANDPSU_NVDDR) && (NewIntf == XNANDPSU_NVDDR)){ + SetFeature |= SetFeature << 8U; + } + /* Set Feature */ + for (Target = 0U; Target < InstancePtr->Geometry.NumTargets; + Target++) { + Status = XNandPsu_SetFeature(InstancePtr, Target, 0x01U, + (u8 *)(void *)&SetFeature); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + InstancePtr->DataInterface = NewIntf; + InstancePtr->TimingMode = NewModeVar; + /* Update Data Interface Register */ + RegVal = ((NewMode % 6U) << ((NewIntf == XNANDPSU_NVDDR) ? 3U : 0U)) | + ((u32)NewIntf << XNANDPSU_DATA_INTF_DATA_INTF_SHIFT); + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_DATA_INTF_OFFSET, RegVal); + + /* Get Feature */ + for (Target = 0U; Target < InstancePtr->Geometry.NumTargets; + Target++) { + Status = XNandPsu_GetFeature(InstancePtr, Target, 0x01U, + &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + + /* Check if set_feature was successful */ + if (*Feature != NewModeVar) { + Status = XST_FAILURE; + goto Out; + } + } + +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function issues change read column and reads the data into buffer +* specified by user. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Col is the coulmn address. +* @param PktSize is the number of bytes to read. +* @param PktCount is the number of transactions to read. +* @param Buf is the data buffer to fill in. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_ChangeReadColumn(XNandPsu *InstancePtr, u32 Target, + u32 Col, u32 PktSize, u32 PktCount, + u8 *Buf) +{ + s32 Status = XST_FAILURE; + u32 RegVal; + u32 AddrCycles = InstancePtr->Geometry.ColAddrCycles; + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK | + XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK; + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + XNandPsu_Update_DmaAddr(InstancePtr, Buf); + } else { + RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, RegVal); + /* Program Command */ + XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_CHNG_RD_COL1, + ONFI_CMD_CHNG_RD_COL2, 0U , 1U, (u8)AddrCycles); + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0U, (u16)Col); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Read command in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1); + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function issues change read column and reads the data into buffer +* specified by user. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chip select value. +* @param Col is the coulmn address. +* @param PktSize is the number of bytes to read. +* @param PktCount is the number of transactions to read. +* @param Buf is the data buffer to fill in. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_ChangeWriteColumn(XNandPsu *InstancePtr, u32 Target, + u32 Col, u32 PktSize, u32 PktCount, + u8 *Buf) +{ + s32 Status = XST_FAILURE; + OnfiCmdFormat OnfiCommand; + u32 RegVal; + u32 AddrCycles = InstancePtr->Geometry.ColAddrCycles; + + if (PktCount == 0U) { + return XST_SUCCESS; + } + + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK | + XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK; +#ifdef __rtems__ + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } +#endif + XNandPsu_Update_DmaAddr(InstancePtr, Buf); + } else { + RegVal = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, RegVal); + /* Change write column hack */ + OnfiCommand.Command1 = 0x85U; + OnfiCommand.Command2 = 0x10U; + XNandPsu_Prepare_Cmd(InstancePtr, OnfiCommand.Command1, + OnfiCommand.Command2, 0U , 0U, (u8)AddrCycles); + + /* Program Page Size */ + XNandPsu_SetPageSize(InstancePtr); + /* Program Column, Page, Block address */ + XNandPsu_SetPageColAddr(InstancePtr, 0U, (u16)Col); + /* Program Packet Size and Packet Count */ + XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount); + /* Program Memory Address Register2 for chip select */ + XNandPsu_SelectChip(InstancePtr, Target); + /* Set Page Program in Program Register */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_CHNG_ROW_ADDR_END_MASK); + + Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 0); + return Status; +} + +/*****************************************************************************/ +/** +* +* This function initializes extended parameter page ECC information. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param ExtPrm is the Extended parameter page buffer. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_InitExtEcc(XNandPsu *InstancePtr, OnfiExtPrmPage *ExtPrm) +{ + s32 Status = XST_FAILURE; + u32 Offset = 0U; + u32 Found = 0U; + OnfiExtEccBlock *EccBlock; + + if (ExtPrm->Section0Type != 0x2U) { + Offset += (u32)ExtPrm->Section0Len; + if (ExtPrm->Section1Type != 0x2U) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Extended ECC section not found\r\n",__func__); +#endif + Status = XST_FAILURE; + } else { + Found = 1U; + } + } else { + Found = 1U; + } + + if (Found != 0U) { + EccBlock = (OnfiExtEccBlock *)&ExtPrm->SectionData[Offset]; + Xil_AssertNonvoid(EccBlock != NULL); + if (EccBlock->CodeWordSize == 0U) { + Status = XST_FAILURE; + } else { + InstancePtr->Geometry.NumBitsECC = + EccBlock->NumEccBits; + InstancePtr->Geometry.EccCodeWordSize = + (u32)EccBlock->CodeWordSize; + Status = XST_SUCCESS; + } + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function prepares command to be written into command register. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Cmd1 is the first Onfi Command. +* @param Cmd2 is the second Onfi Command. +* @param EccState is the flag to set Ecc State. +* @param DmaMode is the flag to set DMA mode. +* @param AddrCycles is the number of Address Cycles. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +void XNandPsu_Prepare_Cmd(XNandPsu *InstancePtr, u8 Cmd1, u8 Cmd2, u8 EccState, + u8 DmaMode, u8 AddrCycles) +{ + Xil_AssertVoid(InstancePtr != NULL); + + u32 RegValue = 0U; + + RegValue = (u32)Cmd1 | (((u32)Cmd2 << (u32)XNANDPSU_CMD_CMD2_SHIFT) & + (u32)XNANDPSU_CMD_CMD2_MASK); + + if ((EccState != 0U) && (InstancePtr->EccMode == XNANDPSU_HWECC)) { + RegValue |= 1U << XNANDPSU_CMD_ECC_ON_SHIFT; + } + + if ((DmaMode != 0U) && (InstancePtr->DmaMode == XNANDPSU_MDMA)) { + RegValue |= XNANDPSU_MDMA << XNANDPSU_CMD_DMA_EN_SHIFT; + } + + if (AddrCycles != 0U) { + RegValue |= (u32)AddrCycles << + (u32)XNANDPSU_CMD_ADDR_CYCLES_SHIFT; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_CMD_OFFSET, RegValue); +} + +/*****************************************************************************/ +/** +* +* This function Read/Writes data from the nand controller. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Buf is the data buffer. +* @param PktCount is the number packet chunks. +* @param PktSize is the size of the packet. +* @param Operation is 1 for write and 0 for read. +* @param DmaMode is 1 for Dma and 0 for PIO. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_Data_ReadWrite(XNandPsu *InstancePtr, u8* Buf, u32 PktCount, + u32 PktSize, u32 Operation, u8 DmaMode) +{ + u32 BufRwCnt = 0U; + s32 Status = XST_FAILURE; + u32 Event = XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK; + + if ((DmaMode != 0U) && (InstancePtr->DmaMode == XNANDPSU_MDMA)) + goto DmaDone; + + if (Operation) + Event = XNANDPSU_INTR_STS_BUFF_WR_RDY_STS_EN_MASK; + + while (BufRwCnt < PktCount) { + /* Poll for Buffer Write Ready event */ + Status = XNandPsu_PollRegTimeout(InstancePtr, + XNANDPSU_INTR_STS_OFFSET, Event, + XNANDPSU_INTR_POLL_TIMEOUT); + if (Status != XST_SUCCESS) { + xil_printf("%s: Poll for buf write ready timeout\r\n", + __func__); + goto Out; + } + + /* Increment Buffer Write Interrupt Count */ + BufRwCnt++; + + if (BufRwCnt == PktCount) + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, + XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK); + + else + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, 0U); + /* + * Clear Buffer Write Ready Interrupt in Interrupt Status + * Register + */ + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET, Event); + /* Write Packet Data to Data Port Register */ + if (Operation) + XNandPsu_Fifo_Write(InstancePtr, Buf, PktSize); + else + XNandPsu_Fifo_Read(InstancePtr, Buf, PktSize); + + Buf += PktSize; + + if (BufRwCnt < PktCount) + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, Event); + else + break; + } + +DmaDone: + Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr); +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function writes data to the fifo. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Buf is the buffer pointer. +* @param Size of the Buffer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_Fifo_Write(XNandPsu *InstancePtr, u8* Buffer, u32 Size) +{ + u32 *BufPtr = (u32 *)(void *)Buffer; + u32 Index; + + for (Index = 0U; Index < Size/4U; Index++) + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_BUF_DATA_PORT_OFFSET, + BufPtr[Index]); +} + +/*****************************************************************************/ +/** +* +* This function reads data from the fifo. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Buf is the buffer pointer. +* @param Size of the Buffer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_Fifo_Read(XNandPsu *InstancePtr, u8* Buf, u32 Size) +{ + u32 *BufPtr = (u32 *)(void *)Buf; + u32 Index; + + for (Index = 0U; Index < Size/4U; Index++) + BufPtr[Index] = XNandPsu_ReadReg(InstancePtr->Config.BaseAddress, + XNANDPSU_BUF_DATA_PORT_OFFSET); +} + +/*****************************************************************************/ +/** +* +* This function configures the given dma address to the controller. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Buf is the buffer pointer. +* +* @return +* None +* +* @note None +* +******************************************************************************/ +static void XNandPsu_Update_DmaAddr(XNandPsu *InstancePtr, u8* Buf) +{ +#if defined(__aarch64__) || defined(__arch64__) + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_DMA_SYS_ADDR1_OFFSET, + (u32) (((INTPTR)Buf >> 32U) & 0xFFFFFFFFU)); +#endif + XNandPsu_WriteReg(InstancePtr->Config.BaseAddress, + XNANDPSU_DMA_SYS_ADDR0_OFFSET, + (u32) ((INTPTR)(void *)Buf & 0xFFFFFFFFU)); + +} + +/*****************************************************************************/ +/** +* +* This function waits for the device ready stataus. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Target is the chipselect value. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note None +* +******************************************************************************/ +static s32 XNandPsu_Device_Ready(XNandPsu *InstancePtr, u32 Target) +{ + s32 Status = XST_SUCCESS; + u16 OnfiStatus = 0U; + + do { + Status = XNandPsu_OnfiReadStatus(InstancePtr, Target, + &OnfiStatus); + if (Status != XST_SUCCESS) + goto Out; + if ((OnfiStatus & (1U << 6U)) != 0U) { + if ((OnfiStatus & (1U << 0U)) != 0U) { + Status = XST_FAILURE; + goto Out; + } + } + } while (((OnfiStatus >> 6U) & 0x1U) == 0U); + +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function waits for the transfer complete event. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if failed. +* +* @note Expects that transfer complete event was set before calling +* this function. +* +******************************************************************************/ +static s32 XNandPsu_WaitFor_Transfer_Complete(XNandPsu *InstancePtr) +{ +s32 Status = XST_FAILURE; + + /* Poll for Transfer Complete event */ + Status = XNandPsu_PollRegTimeout( + InstancePtr, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_TRANS_COMP_STS_EN_MASK, + XNANDPSU_INTR_POLL_TIMEOUT); + if (Status != XST_SUCCESS) { + xil_printf("%s: Poll for xfer complete timeout\r\n", __func__); + goto Out; + } + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_EN_OFFSET, 0U); + + XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress, + XNANDPSU_INTR_STS_OFFSET, + XNANDPSU_INTR_STS_TRANS_COMP_STS_EN_MASK); +#if defined (XCLOCKING) + Xil_ClockDisable(InstancePtr->Config.RefClk); +#endif +Out: + return Status; +} +/** @} */ diff --git a/bsps/shared/dev/nand/xnandpsu_bbm.c b/bsps/shared/dev/nand/xnandpsu_bbm.c new file mode 100644 index 0000000000..40cf798965 --- /dev/null +++ b/bsps/shared/dev/nand/xnandpsu_bbm.c @@ -0,0 +1,1001 @@ +/****************************************************************************** +* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xnandpsu_bbm.c +* @addtogroup Overview +* @{ +* +* This file implements the Bad Block Management (BBM) functionality. +* See xnandpsu_bbm.h for more details. +* +* @note None +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- ---------- ----------------------------------------------- +* 1.0 nm 05/06/2014 First release +* 2.0 sb 01/12/2015 Added support for writing BBT signature and version +* in page section by enabling XNANDPSU_BBT_NO_OOB. +* Modified Bbt Signature and Version Offset value for +* Oob and No-Oob region. +* 1.1 nsk 11/07/16 Change memcpy to Xil_MemCpy to handle word aligned +* data access. +* 1.4 nsk 04/10/18 Added ICCARM compiler support. +* 1.10 akm 01/05/22 Remove assert checks form static and internal APIs. +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include <string.h> /**< For Xil_MemCpy and memset */ +#include "xil_types.h" +#include "xnandpsu.h" +#include "xnandpsu_bbm.h" +#include "xil_mem.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ +static s32 XNandPsu_ReadBbt(XNandPsu *InstancePtr, u32 Target); + +static s32 XNandPsu_SearchBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, + u32 Target); + +static void XNandPsu_CreateBbt(XNandPsu *InstancePtr, u32 Target); + +static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target); + +static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, + XNandPsu_BbtDesc *MirrorDesc, u32 Target); + +static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc, + u32 Target); + +#ifndef __rtems__ +static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target); +#endif + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** +* This function initializes the Bad Block Table(BBT) descriptors with a +* predefined pattern for searching Bad Block Table(BBT) in flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* - NONE +* +******************************************************************************/ +void XNandPsu_InitBbtDesc(XNandPsu *InstancePtr) +{ + u32 Index; + + /* Initialize primary Bad Block Table(BBT) */ + for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) { + InstancePtr->BbtDesc.PageOffset[Index] = + XNANDPSU_BBT_DESC_PAGE_OFFSET; + } + if (InstancePtr->EccMode == XNANDPSU_ONDIE) { + InstancePtr->BbtDesc.SigOffset = XNANDPSU_ONDIE_SIG_OFFSET; + InstancePtr->BbtDesc.VerOffset = XNANDPSU_ONDIE_VER_OFFSET; + } else { + InstancePtr->BbtDesc.SigOffset = XNANDPSU_BBT_DESC_SIG_OFFSET; + InstancePtr->BbtDesc.VerOffset = XNANDPSU_BBT_DESC_VER_OFFSET; + } + InstancePtr->BbtDesc.SigLength = XNANDPSU_BBT_DESC_SIG_LEN; + InstancePtr->BbtDesc.MaxBlocks = XNANDPSU_BBT_DESC_MAX_BLOCKS; + (void)strcpy(&InstancePtr->BbtDesc.Signature[0], "Bbt0"); + for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) { + InstancePtr->BbtDesc.Version[Index] = 0U; + } + InstancePtr->BbtDesc.Valid = 0U; + + /* Assuming that the flash device will have at least 4 blocks. */ + if (InstancePtr->Geometry.NumTargetBlocks <= InstancePtr-> + BbtDesc.MaxBlocks){ + InstancePtr->BbtDesc.MaxBlocks = 4U; + } + + /* Initialize mirror Bad Block Table(BBT) */ + for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) { + InstancePtr->BbtMirrorDesc.PageOffset[Index] = + XNANDPSU_BBT_DESC_PAGE_OFFSET; + } + if (InstancePtr->EccMode == XNANDPSU_ONDIE) { + InstancePtr->BbtMirrorDesc.SigOffset = + XNANDPSU_ONDIE_SIG_OFFSET; + InstancePtr->BbtMirrorDesc.VerOffset = + XNANDPSU_ONDIE_VER_OFFSET; + } else { + InstancePtr->BbtMirrorDesc.SigOffset = + XNANDPSU_BBT_DESC_SIG_OFFSET; + InstancePtr->BbtMirrorDesc.VerOffset = + XNANDPSU_BBT_DESC_VER_OFFSET; + } + InstancePtr->BbtMirrorDesc.SigLength = XNANDPSU_BBT_DESC_SIG_LEN; + InstancePtr->BbtMirrorDesc.MaxBlocks = XNANDPSU_BBT_DESC_MAX_BLOCKS; + (void)strcpy(&InstancePtr->BbtMirrorDesc.Signature[0], "1tbB"); + for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) { + InstancePtr->BbtMirrorDesc.Version[Index] = 0U; + } + InstancePtr->BbtMirrorDesc.Valid = 0U; + + /* Assuming that the flash device will have at least 4 blocks. */ + if (InstancePtr->Geometry.NumTargetBlocks <= InstancePtr-> + BbtMirrorDesc.MaxBlocks){ + InstancePtr->BbtMirrorDesc.MaxBlocks = 4U; + } + + /* Initialize Bad block search pattern structure */ + if (InstancePtr->Geometry.BytesPerPage > 512U) { + /* For flash page size > 512 bytes */ + InstancePtr->BbPattern.Options = XNANDPSU_BBT_SCAN_2ND_PAGE; + InstancePtr->BbPattern.Offset = + XNANDPSU_BB_PTRN_OFF_LARGE_PAGE; + InstancePtr->BbPattern.Length = + XNANDPSU_BB_PTRN_LEN_LARGE_PAGE; + } else { + InstancePtr->BbPattern.Options = XNANDPSU_BBT_SCAN_2ND_PAGE; + InstancePtr->BbPattern.Offset = + XNANDPSU_BB_PTRN_OFF_SML_PAGE; + InstancePtr->BbPattern.Length = + XNANDPSU_BB_PTRN_LEN_SML_PAGE; + } + for(Index = 0U; Index < XNANDPSU_BB_PTRN_LEN_LARGE_PAGE; Index++) { + InstancePtr->BbPattern.Pattern[Index] = XNANDPSU_BB_PATTERN; + } +} + +/*****************************************************************************/ +/** +* This function scans the NAND flash for factory marked bad blocks and creates +* a RAM based Bad Block Table(BBT). +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* - NONE +* +******************************************************************************/ +static void XNandPsu_CreateBbt(XNandPsu *InstancePtr, u32 Target) +{ + u32 BlockIndex; + u32 PageIndex; + u32 Length; + u32 BlockOffset; + u8 BlockShift; + u32 NumPages; + u32 Page; +#ifdef __ICCARM__ +#pragma pack(push, 1) + u8 Buf[XNANDPSU_MAX_SPARE_SIZE] = {0U}; +#pragma pack(pop) +#else + u8 Buf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U}; +#endif + u32 StartBlock = Target * InstancePtr->Geometry.NumTargetBlocks; + u32 NumBlocks = InstancePtr->Geometry.NumTargetBlocks; + s32 Status; + + /* Number of pages to search for bad block pattern */ + if ((InstancePtr->BbPattern.Options & XNANDPSU_BBT_SCAN_2ND_PAGE) != 0U) + { + NumPages = 2U; + } else { + NumPages = 1U; + } + /* Scan all the blocks for factory marked bad blocks */ + for(BlockIndex = StartBlock; BlockIndex < (StartBlock + NumBlocks); + BlockIndex++) { + /* Block offset in Bad Block Table(BBT) entry */ + BlockOffset = BlockIndex >> XNANDPSU_BBT_BLOCK_SHIFT; + /* Block shift value in the byte */ + BlockShift = XNandPsu_BbtBlockShift(BlockIndex); + Page = BlockIndex * InstancePtr->Geometry.PagesPerBlock; + /* Search for the bad block pattern */ + for(PageIndex = 0U; PageIndex < NumPages; PageIndex++) { + Status = XNandPsu_ReadSpareBytes(InstancePtr, + (Page + PageIndex), &Buf[0]); + + if (Status != XST_SUCCESS) { + /* Marking as bad block */ + InstancePtr->Bbt[BlockOffset] |= + (u8)(XNANDPSU_BLOCK_FACTORY_BAD << + BlockShift); + break; + } + /* + * Read the spare bytes to check for bad block + * pattern + */ + for(Length = 0U; Length < + InstancePtr->BbPattern.Length; Length++) { + if (Buf[InstancePtr->BbPattern.Offset + Length] + != + InstancePtr->BbPattern.Pattern[Length]) + { + /* Bad block found */ + InstancePtr->Bbt[BlockOffset] |= + (u8) + (XNANDPSU_BLOCK_FACTORY_BAD << + BlockShift); + break; + } + } + } + } +} + +/*****************************************************************************/ +/** +* This function reads the Bad Block Table(BBT) if present in flash. If not it +* scans the flash for detecting factory marked bad blocks and creates a bad +* block table and write the Bad Block Table(BBT) into the flash. +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +s32 XNandPsu_ScanBbt(XNandPsu *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) + + s32 Status; + u32 Index; + u32 BbtLen; + + /* Zero the RAM based Bad Block Table(BBT) entries */ + BbtLen = InstancePtr->Geometry.NumBlocks >> + XNANDPSU_BBT_BLOCK_SHIFT; + (void)memset(&InstancePtr->Bbt[0], 0, BbtLen); + + for (Index = 0U; Index < InstancePtr->Geometry.NumTargets; Index++) { + + if (XNandPsu_ReadBbt(InstancePtr, Index) != XST_SUCCESS) { + /* Create memory based Bad Block Table(BBT) */ + XNandPsu_CreateBbt(InstancePtr, Index); + /* Write the Bad Block Table(BBT) to the flash */ + Status = XNandPsu_WriteBbt(InstancePtr, + &InstancePtr->BbtDesc, + &InstancePtr->BbtMirrorDesc, Index); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Write the Mirror Bad Block Table(BBT) to the flash */ + Status = XNandPsu_WriteBbt(InstancePtr, + &InstancePtr->BbtMirrorDesc, + &InstancePtr->BbtDesc, Index); + if (Status != XST_SUCCESS) { + goto Out; + } + /* + * Mark the blocks containing Bad Block Table + * (BBT) as Reserved + */ + Status = XNandPsu_MarkBbt(InstancePtr, + &InstancePtr->BbtDesc, + Index); + if (Status != XST_SUCCESS) { + goto Out; + } + Status = XNandPsu_MarkBbt(InstancePtr, + &InstancePtr->BbtMirrorDesc, + Index); + if (Status != XST_SUCCESS) { + goto Out; + } + } + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* This function converts the Bad Block Table(BBT) read from the flash to the +* RAM based Bad Block Table(BBT). +* +* @param InstancePtr is a pointer to the XNandPsu instance. +* @param Buf is the buffer which contains BBT read from flash. +* +* @return +* - NONE. +* +******************************************************************************/ +static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target) +{ +#ifndef __rtems__ + u32 BlockOffset; + u8 BlockShift; + u32 Data; + u8 BlockType; + u32 BlockIndex; +#endif + u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >> + XNANDPSU_BBT_BLOCK_SHIFT; +#ifdef __rtems__ + u32 BbtOffset = Target * InstancePtr->Geometry.NumTargetBlocks / XNANDPSU_BBT_ENTRY_NUM_BLOCKS; + + for(u32 BbtIndex = 0; BbtIndex < BbtLen; BbtIndex++) { + /* Invert the byte to convert from in-flash BBT to in-memory BBT */ + InstancePtr->Bbt[BbtIndex + BbtOffset] = ~Buf[BbtIndex]; + } +#else + u32 StartBlock = Target * InstancePtr->Geometry.NumTargetBlocks; + + for(BlockOffset = StartBlock; BlockOffset < (StartBlock + BbtLen); + BlockOffset++) { + Data = *(Buf + BlockOffset); + /* Clear the RAM based Bad Block Table(BBT) contents */ + InstancePtr->Bbt[BlockOffset] = 0x0U; + /* Loop through the every 4 blocks in the bitmap */ + for(BlockIndex = 0U; BlockIndex < XNANDPSU_BBT_ENTRY_NUM_BLOCKS; + BlockIndex++) { + BlockShift = XNandPsu_BbtBlockShift(BlockIndex); + BlockType = (u8) ((Data >> BlockShift) & + XNANDPSU_BLOCK_TYPE_MASK); + switch(BlockType) { + case XNANDPSU_FLASH_BLOCK_FAC_BAD: + /* Factory bad block */ + InstancePtr->Bbt[BlockOffset] |= + (u8) + (XNANDPSU_BLOCK_FACTORY_BAD << + BlockShift); + break; + case XNANDPSU_FLASH_BLOCK_RESERVED: + /* Reserved block */ + InstancePtr->Bbt[BlockOffset] |= + (u8) + (XNANDPSU_BLOCK_RESERVED << + BlockShift); + break; + case XNANDPSU_FLASH_BLOCK_BAD: + /* Bad block due to wear */ + InstancePtr->Bbt[BlockOffset] |= + (u8)(XNANDPSU_BLOCK_BAD << + BlockShift); + break; + default: + /* Good block */ + /* The BBT entry already defaults to + * zero */ + break; + } + } + } +#endif +} + +/*****************************************************************************/ +/** +* This function searches the Bad Bloock Table(BBT) in flash and loads into the +* memory based Bad Block Table(BBT). +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +static s32 XNandPsu_ReadBbt(XNandPsu *InstancePtr, u32 Target) +{ + u64 Offset; +#ifdef __ICCARM__ +#pragma pack(push, 1) + u8 Buf[XNANDPSU_BBT_BUF_LENGTH]= {0U}; +#pragma pack(pop) +#else + u8 Buf[XNANDPSU_BBT_BUF_LENGTH] __attribute__ ((aligned(64))) = {0U}; +#endif + s32 Status1; + s32 Status2; + s32 Status; + u32 BufLen; + + XNandPsu_BbtDesc *Desc = &InstancePtr->BbtDesc; + XNandPsu_BbtDesc *MirrorDesc = &InstancePtr->BbtMirrorDesc; +#ifdef __rtems__ + BufLen = InstancePtr->Geometry.NumTargetBlocks >> +#else + BufLen = InstancePtr->Geometry.NumBlocks >> +#endif + XNANDPSU_BBT_BLOCK_SHIFT; + /* Search the Bad Block Table(BBT) in flash */ + Status1 = XNandPsu_SearchBbt(InstancePtr, Desc, Target); + Status2 = XNandPsu_SearchBbt(InstancePtr, MirrorDesc, Target); + if ((Status1 != XST_SUCCESS) && (Status2 != XST_SUCCESS)) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Bad block table not found\r\n",__func__); +#endif + Status = XST_FAILURE; + goto Out; + } +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Bad block table found\r\n",__func__); +#endif + /* Bad Block Table found */ + if ((Desc->Valid != 0U) && (MirrorDesc->Valid != 0U)) { + /* Valid BBT & Mirror BBT found */ + if (Desc->Version[Target] > MirrorDesc->Version[Target]) { + Offset = (u64)Desc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Read(InstancePtr, Offset, BufLen, + &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Convert flash BBT to memory based BBT */ + XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target); + MirrorDesc->Version[Target] = Desc->Version[Target]; + + /* Write the BBT to Mirror BBT location in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, MirrorDesc, + Desc, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } else if (Desc->Version[Target] < + MirrorDesc->Version[Target]) { + Offset = (u64)MirrorDesc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Read(InstancePtr, Offset, BufLen, + &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Convert flash BBT to memory based BBT */ + XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target); + Desc->Version[Target] = MirrorDesc->Version[Target]; + + /* Write the Mirror BBT to BBT location in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, Desc, + MirrorDesc, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } else { + /* Both are up-to-date */ + Offset = (u64)Desc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Read(InstancePtr, Offset, BufLen, + &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Convert flash BBT to memory based BBT */ + XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target); + } + } else if (Desc->Valid != 0U) { + /* Valid Primary BBT found */ + Offset = (u64)Desc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Read(InstancePtr, Offset, BufLen, &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Convert flash BBT to memory based BBT */ + XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target); + MirrorDesc->Version[Target] = Desc->Version[Target]; + + /* Write the BBT to Mirror BBT location in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, MirrorDesc, Desc, + Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } else { + /* Valid Mirror BBT found */ + Offset = (u64)MirrorDesc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Read(InstancePtr, Offset, BufLen, &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Convert flash BBT to memory based BBT */ + XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target); + Desc->Version[Target] = MirrorDesc->Version[Target]; + + /* Write the Mirror BBT to BBT location in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, Desc, MirrorDesc, + Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* This function searches the BBT in flash. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @param Desc is the BBT descriptor pattern to search. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +static s32 XNandPsu_SearchBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, + u32 Target) +{ + u32 StartBlock; + u32 SigOffset; + u32 VerOffset; + u32 MaxBlocks; + u32 PageOff; + u32 SigLength; +#ifdef __ICCARM__ +#pragma pack(push, 1) + u8 Buf[XNANDPSU_MAX_SPARE_SIZE] = {0U}; +#pragma pack(pop) +#else + u8 Buf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U}; +#endif + u32 Block; + u32 Offset; + s32 Status; + + StartBlock = ((Target + (u32)1) * + InstancePtr->Geometry.NumTargetBlocks) - (u32)1; + SigOffset = Desc->SigOffset; + VerOffset = Desc->VerOffset; + MaxBlocks = Desc->MaxBlocks; + SigLength = Desc->SigLength; +#ifdef __rtems__ + Desc->Valid = 0; +#endif + + /* Read the last 4 blocks for Bad Block Table(BBT) signature */ + for(Block = 0U; Block < MaxBlocks; Block++) { + PageOff = (StartBlock - Block) * + InstancePtr->Geometry.PagesPerBlock; + + Status = XNandPsu_ReadSpareBytes(InstancePtr, PageOff, &Buf[0]); + if (Status != XST_SUCCESS) { + continue; + } + /* Check the Bad Block Table(BBT) signature */ + for(Offset = 0U; Offset < SigLength; Offset++) { + if (Buf[Offset + SigOffset] != + (u8)(Desc->Signature[Offset])) + { + break; /* Check the next blocks */ + } + } + if (Offset >= SigLength) { + /* Bad Block Table(BBT) found */ + Desc->PageOffset[Target] = PageOff; + Desc->Version[Target] = Buf[VerOffset]; + Desc->Valid = 1U; + + Status = XST_SUCCESS; + goto Out; + } + } + /* Bad Block Table(BBT) not found */ + Status = XST_FAILURE; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* This function writes Bad Block Table(BBT) from RAM to flash. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @param Desc is the BBT descriptor to be written to flash. +* @param MirrorDesc is the mirror BBT descriptor. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, + XNandPsu_BbtDesc *MirrorDesc, u32 Target) +{ + u64 Offset; + u32 Block = {0U}; + u32 EndBlock = ((Target + (u32)1) * + InstancePtr->Geometry.NumTargetBlocks) - (u32)1; +#ifdef __ICCARM__ +#pragma pack(push, 1) + u8 Buf[XNANDPSU_BBT_BUF_LENGTH]= {0U}; + u8 SpareBuf[XNANDPSU_MAX_SPARE_SIZE]= {0U}; +#pragma pack(pop) +#else + u8 Buf[XNANDPSU_BBT_BUF_LENGTH] __attribute__ ((aligned(64))) = {0U}; + u8 SpareBuf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U}; +#endif + +#ifndef __rtems__ + u8 Mask[4] = {0x00U, 0x01U, 0x02U, 0x03U}; + u8 Data; + u32 BlockOffset; + u8 BlockShift; + s32 Status; + u32 BlockIndex; + u32 Index; + u8 BlockType; + u32 BbtLen = InstancePtr->Geometry.NumBlocks >> +#else + s32 Status; + u32 Index; + u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >> +#endif + XNANDPSU_BBT_BLOCK_SHIFT; + /* Find a valid block to write the Bad Block Table(BBT) */ + if ((!Desc->Valid) != 0U) { + for(Index = 0U; Index < Desc->MaxBlocks; Index++) { + Block = (EndBlock - Index); +#ifdef __rtems__ + if (XNandPsu_IsBlockBad(InstancePtr, Block) != XST_FAILURE) { + continue; + } +#else + BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(Block); + BlockType = (InstancePtr->Bbt[BlockOffset] >> + BlockShift) & XNANDPSU_BLOCK_TYPE_MASK; + switch(BlockType) + { + case XNANDPSU_BLOCK_BAD: + case XNANDPSU_BLOCK_FACTORY_BAD: + continue; + default: + /* Good Block */ + break; + } +#endif + Desc->PageOffset[Target] = Block * + InstancePtr->Geometry.PagesPerBlock; + if (Desc->PageOffset[Target] != + MirrorDesc->PageOffset[Target]) { + /* Free block found */ + Desc->Valid = 1U; + break; + } + } + + + /* Block not found for writing Bad Block Table(BBT) */ + if (Index >= Desc->MaxBlocks) { +#ifdef XNANDPSU_DEBUG + xil_printf("%s: Blocks unavailable for writing BBT\r\n", + __func__); +#endif + Status = XST_FAILURE; + goto Out; + } + } else { + Block = Desc->PageOffset[Target] / + InstancePtr->Geometry.PagesPerBlock; + } + /* Convert the memory based BBT to flash based table */ + (void)memset(Buf, 0xff, BbtLen); + +#ifdef __rtems__ + u32 BbtTargetOffset = BbtLen * Target; + /* Loop through the BBT entries */ + for(u32 BbtIndex = 0U; BbtIndex < BbtLen; BbtIndex++) { + /* Invert byte to convert from in-memory BBT to in-flash BBT */ + Buf[BbtIndex] = ~InstancePtr->Bbt[BbtIndex + BbtTargetOffset]; + } +#else + /* Loop through the number of blocks */ + for(BlockOffset = 0U; BlockOffset < BbtLen; BlockOffset++) { + Data = InstancePtr->Bbt[BlockOffset]; + /* Calculate the bit mask for 4 blocks at a time in loop */ + for(BlockIndex = 0U; BlockIndex < XNANDPSU_BBT_ENTRY_NUM_BLOCKS; + BlockIndex++) { + BlockShift = XNandPsu_BbtBlockShift(BlockIndex); + Buf[BlockOffset] &= ~(Mask[Data & + XNANDPSU_BLOCK_TYPE_MASK] << + BlockShift); + Data >>= XNANDPSU_BBT_BLOCK_SHIFT; + } + } +#endif + /* Write the Bad Block Table(BBT) to flash */ +#ifdef __rtems__ + Status = XNandPsu_EraseBlock(InstancePtr, Target, + Block % InstancePtr->Geometry.NumTargetBlocks); +#else + Status = XNandPsu_EraseBlock(InstancePtr, 0U, Block); +#endif + if (Status != XST_SUCCESS) { + goto Out; + } + + /* Write the BBT to page offset */ + Offset = (u64)Desc->PageOffset[Target] * + (u64)InstancePtr->Geometry.BytesPerPage; + Status = XNandPsu_Write(InstancePtr, Offset, BbtLen, &Buf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + /* Write the signature and version in the spare data area */ + (void)memset(SpareBuf, 0xff, InstancePtr->Geometry.SpareBytesPerPage); + Status = XNandPsu_ReadSpareBytes(InstancePtr, Desc->PageOffset[Target], + &SpareBuf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + + (void)Xil_MemCpy(SpareBuf + Desc->SigOffset, &Desc->Signature[0], + Desc->SigLength); + (void)memcpy(SpareBuf + Desc->VerOffset, &Desc->Version[Target], 1U); + + Status = XNandPsu_WriteSpareBytes(InstancePtr, + Desc->PageOffset[Target], &SpareBuf[0]); + if (Status != XST_SUCCESS) { + goto Out; + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* This function updates the primary and mirror Bad Block Table(BBT) in the +* flash. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +#ifdef __rtems__ +s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target) +#else +static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target) +#endif +{ + s32 Status; + u8 Version; + + /* Update the version number */ + Version = InstancePtr->BbtDesc.Version[Target]; + InstancePtr->BbtDesc.Version[Target] = (u8)(((u16)Version + + (u16)1) % (u16)256U); + + Version = InstancePtr->BbtMirrorDesc.Version[Target]; + InstancePtr->BbtMirrorDesc.Version[Target] = (u8)(((u16)Version + + (u16)1) % (u16)256); + /* Update the primary Bad Block Table(BBT) in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, &InstancePtr->BbtDesc, + &InstancePtr->BbtMirrorDesc, + Target); + if (Status != XST_SUCCESS) { + goto Out; + } + + /* Update the mirrored Bad Block Table(BBT) in flash */ + Status = XNandPsu_WriteBbt(InstancePtr, &InstancePtr->BbtMirrorDesc, + &InstancePtr->BbtDesc, + Target); + if (Status != XST_SUCCESS) { + goto Out; + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* This function marks the block containing Bad Block Table as reserved +* and updates the BBT. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @param Desc is the BBT descriptor pointer. +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc, + u32 Target) +{ + u32 BlockIndex; + u32 BlockOffset; + u8 BlockShift; + u8 OldVal; + u8 NewVal; + s32 Status; + u32 UpdateBbt = 0U; + u32 Index; + + /* Mark the last four blocks as Reserved */ + BlockIndex = ((Target + (u32)1) * InstancePtr->Geometry.NumTargetBlocks) - +#ifdef __rtems__ + Desc->MaxBlocks; +#else + Desc->MaxBlocks - (u32)1; +#endif + + for(Index = 0U; Index < Desc->MaxBlocks; Index++) { + + BlockOffset = BlockIndex >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(BlockIndex); + OldVal = InstancePtr->Bbt[BlockOffset]; + NewVal = (u8) (OldVal | (XNANDPSU_BLOCK_RESERVED << + BlockShift)); + InstancePtr->Bbt[BlockOffset] = NewVal; + + if (OldVal != NewVal) { + UpdateBbt = 1U; + } + BlockIndex++; + } + + /* Update the BBT to flash */ + if (UpdateBbt != 0U) { + Status = XNandPsu_UpdateBbt(InstancePtr, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +/*****************************************************************************/ +/** +* +* This function checks whether a block is bad or not. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* +* @param Block is the block number. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +s32 XNandPsu_IsBlockBad(XNandPsu *InstancePtr, u32 Block) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) + Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks); + + u8 Data; + u8 BlockShift; + u8 BlockType; + u32 BlockOffset; + s32 Status; + + BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(Block); + Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */ + BlockType = (Data >> BlockShift) & XNANDPSU_BLOCK_TYPE_MASK; + + if ((BlockType != XNANDPSU_BLOCK_GOOD) && + (BlockType != XNANDPSU_BLOCK_RESERVED)) { + Status = XST_SUCCESS; + } + else { + Status = XST_FAILURE; + } + return Status; +} + +/*****************************************************************************/ +/** +* This function marks a block as bad in the RAM based Bad Block Table(BBT). It +* also updates the Bad Block Table(BBT) in the flash. +* +* @param InstancePtr is the pointer to the XNandPsu instance. +* @param Block is the block number. +* +* @return +* - XST_SUCCESS if successful. +* - XST_FAILURE if fail. +* +******************************************************************************/ +s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block) +#ifdef __rtems__ +{ + return XNandPsu_MarkBlock(InstancePtr, Block, XNANDPSU_BLOCK_BAD ); +} + +s32 XNandPsu_MarkBlock(XNandPsu *InstancePtr, u32 Block, u8 BlockMark) +#endif +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) + Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks); + +#ifdef __rtems__ + BlockMark &= XNANDPSU_BLOCK_TYPE_MASK; +#endif + + u8 Data; + u8 BlockShift; + u32 BlockOffset; + u8 OldVal; + u8 NewVal; + s32 Status; + u32 Target; + + Target = Block / InstancePtr->Geometry.NumTargetBlocks; + + BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(Block); + Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */ + + /* Mark the block as bad in the RAM based Bad Block Table */ + OldVal = Data; + Data &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift); +#ifdef __rtems__ + Data |= (BlockMark << BlockShift); +#else + Data |= (XNANDPSU_BLOCK_BAD << BlockShift); +#endif + NewVal = Data; + InstancePtr->Bbt[BlockOffset] = Data; + + /* Update the Bad Block Table(BBT) in flash */ + if (OldVal != NewVal) { + Status = XNandPsu_UpdateBbt(InstancePtr, Target); + if (Status != XST_SUCCESS) { + goto Out; + } + } + + Status = XST_SUCCESS; +Out: + return Status; +} + +#ifdef __rtems__ +bool XNandPsu_StageBlockMark(XNandPsu *InstancePtr, u32 Block, u8 BlockMark) +{ + u8 BlockShift; + u32 BlockOffset; + u8 OldVal; + + BlockMark &= XNANDPSU_BLOCK_TYPE_MASK; + + BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(Block); + OldVal = InstancePtr->Bbt[BlockOffset] >> BlockShift; + OldVal &= XNANDPSU_BLOCK_TYPE_MASK; + InstancePtr->Bbt[BlockOffset] &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift); + InstancePtr->Bbt[BlockOffset] |= (BlockMark << BlockShift); + return BlockMark != OldVal; +} +#endif + +/** @} */ diff --git a/bsps/shared/dev/nand/xnandpsu_onfi.c b/bsps/shared/dev/nand/xnandpsu_onfi.c new file mode 100644 index 0000000000..0009722bfe --- /dev/null +++ b/bsps/shared/dev/nand/xnandpsu_onfi.c @@ -0,0 +1,91 @@ +/****************************************************************************** +* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xnandpsu_onfi.c +* @addtogroup Overview +* @{ +* +* This file contains the implementation of ONFI specific functions. +* +* @note None +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- ---------- ----------------------------------------------- +* 1.0 nm 05/06/2014 First release +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xnandpsu_onfi.h" +#include "xnandpsu.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* This function calculates ONFI parameter page CRC. +* +* @param ParamBuf is a pointer to the ONFI parameter page buffer. +* @param StartOff is the starting offset in buffer to calculate CRC. +* @param Length is the number of bytes for which CRC is calculated. +* +* @return +* CRC value. +* @note +* None. +* +******************************************************************************/ +u32 XNandPsu_OnfiParamPageCrc(u8 *ParamBuf, u32 StartOff, u32 Length) +{ + const u32 CrcInit = 0x4F4EU; + const u32 Order = 16U; + const u32 Polynom = 0x8005U; + u32 i, j, c, Bit; + u32 Crc = CrcInit; + u32 DataIn; + u32 DataByteCount = 0U; + u32 CrcMask, CrcHighBit; + + CrcMask = ((u32)(((u32)1 << (Order - (u32)1)) -(u32)1) << (u32)1) | (u32)1; + CrcHighBit = (u32)((u32)1 << (Order - (u32)1)); + /* + * CRC covers the data bytes between byte 0 and byte 253 + * (ONFI 1.0, section 5.4.1.36) + */ + for(i = StartOff; i < Length; i++) { + DataIn = *(ParamBuf + i); + c = (u32)DataIn; + DataByteCount++; + j = 0x80U; + while(j != 0U) { + Bit = Crc & CrcHighBit; + Crc <<= 1U; + if ((c & j) != 0U) { + Bit ^= CrcHighBit; + } + if (Bit != 0U) { + Crc ^= Polynom; + } + j >>= 1U; + } + Crc &= CrcMask; + } + return Crc; +} +/** @} */ diff --git a/bsps/shared/dev/rtc/mcp7940m.c b/bsps/shared/dev/rtc/mcp7940m.c new file mode 100644 index 0000000000..1abc5faaad --- /dev/null +++ b/bsps/shared/dev/rtc/mcp7940m.c @@ -0,0 +1,361 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * 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. + */ + +/* + * Note: This driver implements only the basic RTC functionality of the + * MCP7940M. It tries not to touch any register fields except for the basic + * date/time fields in the get/set time functions. That way it should be + * possible to re-use the driver for similar RTCs by just replacing the + * initialization function. Suggested method for that: Add a field to the struct + * mcp7940m_rtc with a function pointer that points to the initialization + * function. + * + * All flags that are considered MCP7940M specific have a MCP7940M in the name. + * + * Only 24 hour format is supported. If this driver is the only ones who write + * the RTC, that shouldn't be a problem. + * + * The weekday register is not used. It has a user-defined representation anyway + * and therefore doesn't really matter. + */ + +#include <dev/i2c/i2c.h> +#include <libchip/mcp7940m-rtc.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/todimpl.h> + +#include <fcntl.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#define REG_RTCSEC 0x00u + +#define RTCSEC_SECBCD_SHIFT 0u +#define RTCSEC_SECBCD_MASK (0x7fu << RTCSEC_SECBCD_SHIFT) +#define RTCSEC_SECBCD(x) (((x) << RTCSEC_SECBCD_SHIFT) & RTCSEC_SECBCD_MASK) +#define RTCSEC_SECBCD_GET(x) (((x) & RTCSEC_SECBCD_MASK) >> RTCSEC_SECBCD_SHIFT) + +#define MCP7940M_RTCSEC_ST (0x01u << 7) + +#define REG_RTCMIN 0x01 + +#define RTCMIN_MINBCD_SHIFT 0u +#define RTCMIN_MINBCD_MASK (0x7fu << RTCMIN_MINBCD_SHIFT) +#define RTCMIN_MINBCD(x) (((x) << RTCMIN_MINBCD_SHIFT) & RTCMIN_MINBCD_MASK) +#define RTCMIN_MINBCD_GET(x) (((x) & RTCMIN_MINBCD_MASK) >> RTCMIN_MINBCD_SHIFT) + +#define REG_RTCHOUR 0x02 + +#define RTCHOUR_HRBCD12_SHIFT 0u +#define RTCHOUR_HRBCD12_MASK (0x1fu << RTCHOUR_HRBCD12_SHIFT) +#define RTCHOUR_HRBCD12(x) (((x) << RTCHOUR_HRBCD12_SHIFT) & RTCHOUR_HRBCD12_MASK) +#define RTCHOUR_HRBCD12_GET(x) (((x) & RTCHOUR_HRBCD12_MASK) >> RTCHOUR_HRBCD12_SHIFT) + +#define RTCHOUR_HRBCD24_SHIFT 0u +#define RTCHOUR_HRBCD24_MASK (0x3fu << RTCHOUR_HRBCD24_SHIFT) +#define RTCHOUR_HRBCD24(x) (((x) << RTCHOUR_HRBCD24_SHIFT) & RTCHOUR_HRBCD24_MASK) +#define RTCHOUR_HRBCD24_GET(x) (((x) & RTCHOUR_HRBCD24_MASK) >> RTCHOUR_HRBCD24_SHIFT) + +#define RTCHOUR_AMPM (0x01u << 5) +#define RTCHOUR_1224 (0x01u << 6) + +#define REG_RTCWKDAY 0x03 + +#define RTCWKDAY_WKDAY_SHIFT 0u +#define RTCWKDAY_WKDAY_MASK (0x7u << RTCWKDAY_WKDAY_SHIFT) +#define RTCWKDAY_WKDAY(x) (((x) << RTCWKDAY_WKDAY_SHIFT) & RTCWKDAY_WKDAY_MASK) +#define RTCWKDAY_WKDAY_GET(x) (((x) & RTCWKDAY_WKDAY_MASK) >> RTCWKDAY_WKDAY_SHIFT) + +#define REG_RTCDATE 0x04 + +#define RTCDATE_DATEBCD_SHIFT 0u +#define RTCDATE_DATEBCD_MASK (0x3fu << RTCDATE_DATEBCD_SHIFT) +#define RTCDATE_DATEBCD(x) (((x) << RTCDATE_DATEBCD_SHIFT) & RTCDATE_DATEBCD_MASK) +#define RTCDATE_DATEBCD_GET(x) (((x) & RTCDATE_DATEBCD_MASK) >> RTCDATE_DATEBCD_SHIFT) + +#define REG_RTCMTH 0x05 + +#define RTCMTH_MTHBCD_SHIFT 0u +#define RTCMTH_MTHBCD_MASK (0x1fu << RTCMTH_MTHBCD_SHIFT) +#define RTCMTH_MTHBCD(x) (((x) << RTCMTH_MTHBCD_SHIFT) & RTCMTH_MTHBCD_MASK) +#define RTCMTH_MTHBCD_GET(x) (((x) & RTCMTH_MTHBCD_MASK) >> RTCMTH_MTHBCD_SHIFT) + +#define MCP7940M_RTCMTH_LPYR (0x01u << 5) + +#define REG_RTCYEAR 0x06 + +#define RTCYEAR_YRBCD_SHIFT 0u +#define RTCYEAR_YRBCD_MASK (0xffu << RTCYEAR_YRBCD_SHIFT) +#define RTCYEAR_YRBCD(x) (((x) << RTCYEAR_YRBCD_SHIFT) & RTCYEAR_YRBCD_MASK) +#define RTCYEAR_YRBCD_GET(x) (((x) & RTCYEAR_YRBCD_MASK) >> RTCYEAR_YRBCD_SHIFT) + +#define REG_MCP7940M_CONTROL 0x07 + +#define MCP7940M_CONTROL_OUT (0x1u << 7) +#define MCP7940M_CONTROL_SQWEN (0x1u << 6) +#define MCP7940M_CONTROL_ALM1EN (0x1u << 5) +#define MCP7940M_CONTROL_ALM0EN (0x1u << 4) +#define MCP7940M_CONTROL_EXTOSC (0x1u << 3) +#define MCP7940M_CONTROL_CRSTRIM (0x1u << 2) +#define MCP7940M_CONTROL_SQWFS1 (0x1u << 1) +#define MCP7940M_CONTROL_SQWFS0 (0x1u << 0) + +static inline uint8_t bcd_to_bin(uint8_t bcd) +{ + uint8_t bin; + bin = bcd & 0x0f; + bin += ((bcd >> 4) & 0x0f) * 10; + return bin; +} + +static inline uint8_t bin_to_bcd(uint8_t bin) +{ + uint8_t bcd; + bcd = bin % 10; + bcd |= (bin / 10) << 4; + return bcd; +} + +static struct mcp7940m_rtc *mcp7940m_get_context(int minor) +{ + return (struct mcp7940m_rtc *) RTC_Table[minor].pDeviceParams; +} + +static int mcp7940m_i2c_read( + struct mcp7940m_rtc *ctx, + uint8_t addr, + uint8_t *buf, + size_t len +) +{ + int fd; + int rv; + struct i2c_msg msgs[] = {{ + .addr = ctx->i2c_addr, + .flags = 0, + .buf = &addr, + .len = 1, + }, { + .addr = ctx->i2c_addr, + .flags = I2C_M_RD, + .buf = buf, + .len = len, + }}; + struct i2c_rdwr_ioctl_data payload = { + .msgs = msgs, + .nmsgs = sizeof(msgs)/sizeof(msgs[0]), + }; + + fd = open(ctx->i2c_bus_path, O_RDWR); + if (fd < 0) { + return fd; + } + + rv = ioctl(fd, I2C_RDWR, &payload); + + close(fd); + + return rv; +} + +static int mcp7940m_i2c_write( + struct mcp7940m_rtc *ctx, + uint8_t addr, + const uint8_t *buf, + size_t len +) +{ + int fd; + int rv; + uint8_t writebuf[len + 1]; + struct i2c_msg msgs[] = {{ + .addr = ctx->i2c_addr, + .flags = 0, + .buf = writebuf, + .len = len + 1, + }}; + struct i2c_rdwr_ioctl_data payload = { + .msgs = msgs, + .nmsgs = sizeof(msgs)/sizeof(msgs[0]), + }; + + writebuf[0] = addr; + memcpy(&writebuf[1], buf, len); + + fd = open(ctx->i2c_bus_path, O_RDWR); + if (fd < 0) { + return fd; + } + + rv = ioctl(fd, I2C_RDWR, &payload); + + close(fd); + + return rv; +} + +static int mcp7940m_initialize_once(struct mcp7940m_rtc *ctx) +{ + uint8_t reg; + ssize_t rv; + + if (ctx->initialized) { + return 0; + } + + /* + * Make sure that all alarms and outputs are disabled. Enable or disable + * oscillator. + * + * This makes sure that we can start with an uninitialized device that has a + * random value in the control register. + */ + reg = 0; + if (!ctx->crystal) { + reg |= MCP7940M_CONTROL_EXTOSC; + } + rv = mcp7940m_i2c_write(ctx, REG_MCP7940M_CONTROL, ®, 1); + + if (rv == 0 && ctx->crystal) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, ®, 1); + if (rv == 0 && (reg & MCP7940M_RTCSEC_ST) == 0) { + reg |= MCP7940M_RTCSEC_ST; + rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, ®, 1); + } + } + + ctx->initialized = true; + + return rv; +} + +static int mcp7940m_get_time(int minor, rtems_time_of_day *time) +{ + int rv = 0; + uint8_t buf[REG_RTCYEAR + 1]; + struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor); + + if (!_System_state_Is_up(_System_state_Get())) { + return -1; + } + + rtems_mutex_lock(&ctx->mutex); + + rv = mcp7940m_initialize_once(ctx); + + if (rv == 0) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + if (rv == 0) { + unsigned year = bcd_to_bin(RTCYEAR_YRBCD_GET(buf[REG_RTCYEAR])) + + (TOD_BASE_YEAR / 100 * 100); + if (year < TOD_BASE_YEAR) { + year += 100; + } + time->year = year; + time->month = bcd_to_bin(RTCMTH_MTHBCD_GET(buf[REG_RTCMTH])); + time->day = bcd_to_bin(RTCDATE_DATEBCD_GET(buf[REG_RTCDATE])); + time->hour = bcd_to_bin(RTCHOUR_HRBCD24_GET(buf[REG_RTCHOUR])); + time->minute = bcd_to_bin(RTCMIN_MINBCD_GET(buf[REG_RTCMIN])); + time->second = bcd_to_bin(RTCSEC_SECBCD_GET(buf[REG_RTCSEC])); + time->ticks = 0; + } + + rtems_mutex_unlock(&ctx->mutex); + + return rv; +} + +static int mcp7940m_set_time(int minor, const rtems_time_of_day *time) +{ + int rv = 0; + uint8_t buf[REG_RTCYEAR + 1]; + struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor); + + if (!_System_state_Is_up(_System_state_Get())) { + return -1; + } + + rtems_mutex_lock(&ctx->mutex); + + rv = mcp7940m_initialize_once(ctx); + + if (rv == 0) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + if (rv == 0) { + /* Make sure weekday is not 0 (out of range). Otherwise it's not used. */ + if (RTCWKDAY_WKDAY_GET(buf[REG_RTCWKDAY]) < 1) { + buf[REG_RTCWKDAY] &= ~RTCWKDAY_WKDAY_MASK; + buf[REG_RTCWKDAY] |= RTCWKDAY_WKDAY(1); + } + + buf[REG_RTCYEAR] &= ~RTCYEAR_YRBCD_MASK; + buf[REG_RTCYEAR] |= RTCYEAR_YRBCD(bin_to_bcd(time->year % 100)); + + buf[REG_RTCMTH] &= ~RTCMTH_MTHBCD_MASK; + buf[REG_RTCMTH] |= RTCMTH_MTHBCD(bin_to_bcd(time->month)); + + buf[REG_RTCDATE] &= ~RTCDATE_DATEBCD_MASK; + buf[REG_RTCDATE] |= RTCDATE_DATEBCD(bin_to_bcd(time->day)); + + buf[REG_RTCHOUR] &= ~(RTCHOUR_HRBCD24_MASK | RTCHOUR_1224); + buf[REG_RTCHOUR] |= RTCHOUR_HRBCD24(bin_to_bcd(time->hour)); + + buf[REG_RTCMIN] &= ~RTCMIN_MINBCD_MASK; + buf[REG_RTCMIN] |= RTCMIN_MINBCD(bin_to_bcd(time->minute)); + + buf[REG_RTCSEC] &= ~RTCSEC_SECBCD_MASK; + buf[REG_RTCSEC] |= RTCSEC_SECBCD(bin_to_bcd(time->second)); + + rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + rtems_mutex_unlock(&ctx->mutex); + + return rv; +} + +static void mcp7940m_init(int minor) +{ + (void) minor; +} + +bool rtc_mcp7940m_probe(int minor) +{ + return true; +} + +const rtc_fns rtc_mcp7940m_fns = { + .deviceInitialize = mcp7940m_init, + .deviceGetTime = mcp7940m_get_time, + .deviceSetTime = mcp7940m_set_time, +}; diff --git a/bsps/shared/dev/serial/arm-pl011.c b/bsps/shared/dev/serial/arm-pl011.c index f0e7031f96..e9a8e3f5a4 100644 --- a/bsps/shared/dev/serial/arm-pl011.c +++ b/bsps/shared/dev/serial/arm-pl011.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-output-char.c b/bsps/shared/dev/serial/console-output-char.c index 14ad05cd8c..477fd1ffde 100644 --- a/bsps/shared/dev/serial/console-output-char.c +++ b/bsps/shared/dev/serial/console-output-char.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-polled.c b/bsps/shared/dev/serial/console-polled.c index 0fc765cb64..37ad5b8f18 100644 --- a/bsps/shared/dev/serial/console-polled.c +++ b/bsps/shared/dev/serial/console-polled.c @@ -113,7 +113,7 @@ rtems_device_driver console_open( NULL, /* setAttributes */ NULL, /* stopRemoteTx */ NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ + TERMIOS_POLLED /* outputUsesInterrupts */ }; assert( minor == 0 ); diff --git a/bsps/shared/dev/serial/console-termios-init.c b/bsps/shared/dev/serial/console-termios-init.c index da3eeaa2a7..c144549cb4 100644 --- a/bsps/shared/dev/serial/console-termios-init.c +++ b/bsps/shared/dev/serial/console-termios-init.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-termios.c b/bsps/shared/dev/serial/console-termios.c index 16d5344be1..bdea1a0284 100644 --- a/bsps/shared/dev/serial/console-termios.c +++ b/bsps/shared/dev/serial/console-termios.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/getserialmouseps2.c b/bsps/shared/dev/serial/getserialmouseps2.c index 22def46749..451a62d716 100644 --- a/bsps/shared/dev/serial/getserialmouseps2.c +++ b/bsps/shared/dev/serial/getserialmouseps2.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/legacy-console.c b/bsps/shared/dev/serial/legacy-console.c index 7da87276b0..698439b247 100644 --- a/bsps/shared/dev/serial/legacy-console.c +++ b/bsps/shared/dev/serial/legacy-console.c @@ -234,7 +234,11 @@ rtems_device_driver console_open( Callbacks.stopRemoteTx = NULL; Callbacks.startRemoteTx = NULL; } - Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts; + if (cptr->pDeviceFns->deviceOutputUsesInterrupts) { + Callbacks.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN; + } else { + Callbacks.outputUsesInterrupts = TERMIOS_POLLED; + } /* XXX what about * Console_Port_Tbl[minor].ulMargin, diff --git a/bsps/shared/dev/serial/uart-output-char.c b/bsps/shared/dev/serial/uart-output-char.c index 632aec26c3..6ec58a6588 100644 --- a/bsps/shared/dev/serial/uart-output-char.c +++ b/bsps/shared/dev/serial/uart-output-char.c @@ -9,7 +9,7 @@ */ /* - * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved. + * Copyright (C) 2010, 2011 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/zynq-uart-kernel-io.c b/bsps/shared/dev/serial/zynq-uart-kernel-io.c new file mode 100644 index 0000000000..61b1043cd2 --- /dev/null +++ b/bsps/shared/dev/serial/zynq-uart-kernel-io.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup zynq_uart + * + * @brief This source file contains the definition of ::BSP_output_char and + * ::BSP_poll_char. + */ + +/* + * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG + * + * 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 <rtems/bspIo.h> + +#include <bsp.h> +#include <dev/serial/zynq-uart-regs.h> +#include <rtems/sysinit.h> + +static void zynq_uart_kernel_output_char(char c) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + zynq_uart_write_char_polled(regs, c); +} + +static int zynq_uart_kernel_poll_char(void) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + return zynq_uart_read_char_polled(regs); +} + +static void zynq_uart_kernel_early_init(char c); + +static void zynq_uart_kernel_init(void) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + if (BSP_output_char != zynq_uart_kernel_early_init) { + return; + } + + zynq_uart_initialize(regs); + BSP_output_char = zynq_uart_kernel_output_char; +} + +static void zynq_uart_kernel_early_init(char c) +{ + zynq_uart_kernel_init(); + zynq_uart_kernel_output_char(c); +} + +BSP_output_char_function_type BSP_output_char = zynq_uart_kernel_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = zynq_uart_kernel_poll_char; + +RTEMS_SYSINIT_ITEM( + zynq_uart_kernel_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST_BUT_5 +); diff --git a/bsps/shared/dev/serial/zynq-uart-polled.c b/bsps/shared/dev/serial/zynq-uart-polled.c index 6865fa8d6f..dbf75539f6 100644 --- a/bsps/shared/dev/serial/zynq-uart-polled.c +++ b/bsps/shared/dev/serial/zynq-uart-polled.c @@ -1,7 +1,16 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file * - * Copyright (C) 2013, 2017 embedded brains GmbH + * @ingroup RTEMSBSPsARMZynq + * + * @brief This source file contains the implementation of the polled Zynq UART + * support. + */ + +/* + * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -115,10 +124,8 @@ int zynq_cal_baud_rate(uint32_t baudrate, return 0; } -void zynq_uart_initialize(rtems_termios_device_context *base) +void zynq_uart_initialize(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; uint32_t brgr = 0x3e; uint32_t bauddiv = 0x6; uint32_t mode_clks = regs->mode & ZYNQ_UART_MODE_CLKS; @@ -145,18 +152,15 @@ void zynq_uart_initialize(rtems_termios_device_context *base) | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8) | mode_clks; - while (zynq_uart_read_polled(base) >= 0) { + while (zynq_uart_read_char_polled(regs) >= 0) { /* Drop */ } - zynq_uart_reset_tx_flush(ctx); + zynq_uart_reset_tx_flush(regs); } -int zynq_uart_read_polled(rtems_termios_device_context *base) +int zynq_uart_read_char_polled(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { return -1; } else { @@ -164,14 +168,8 @@ int zynq_uart_read_polled(rtems_termios_device_context *base) } } -void zynq_uart_write_polled( - rtems_termios_device_context *base, - char c -) +void zynq_uart_write_char_polled(volatile zynq_uart *regs, char c) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TNFUL) != 0) { /* Wait */ } @@ -179,13 +177,12 @@ void zynq_uart_write_polled( regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); } -void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) +void zynq_uart_reset_tx_flush(volatile zynq_uart *regs) { - volatile zynq_uart *regs = ctx->regs; - int c = 4; + int c = 4; while (c-- > 0) - zynq_uart_write_polled(&ctx->base, '\r'); + zynq_uart_write_char_polled(regs, '\r'); while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0 || (regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TACTIVE) != 0) { diff --git a/bsps/shared/dev/serial/zynq-uart.c b/bsps/shared/dev/serial/zynq-uart.c index 8ff1d25da0..0489288271 100644 --- a/bsps/shared/dev/serial/zynq-uart.c +++ b/bsps/shared/dev/serial/zynq-uart.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2013, 2017 embedded brains GmbH + * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,6 +28,7 @@ #include <dev/serial/zynq-uart.h> #include <dev/serial/zynq-uart-regs.h> #include <bsp/irq.h> +#include <rtems/termiostypes.h> #include <bspopts.h> @@ -66,14 +67,14 @@ static bool zynq_uart_first_open( rtems_libio_open_close_args_t *args ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS rtems_status_code sc; #endif rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); - zynq_uart_initialize(base); + zynq_uart_initialize(regs); #ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->rx_fifo_trg_lvl = 1; @@ -108,15 +109,23 @@ static void zynq_uart_last_close( } #endif +#ifndef ZYNQ_CONSOLE_USE_INTERRUPTS +static int zynq_uart_read_polled(rtems_termios_device_context *base) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + return zynq_uart_read_char_polled(ctx->regs); +} +#endif + static void zynq_uart_write_support( rtems_termios_device_context *base, const char *buf, size_t len ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->irq_dis = ZYNQ_UART_TEMPTY; @@ -134,9 +143,9 @@ static void zynq_uart_write_support( regs->irq_en = ZYNQ_UART_TEMPTY; } #else - ssize_t i; + size_t i; for (i = 0; i < len; ++i) { - zynq_uart_write_polled(base, buf[i]); + zynq_uart_write_char_polled(regs, buf[i]); } #endif } diff --git a/bsps/shared/dev/spi/VERSION b/bsps/shared/dev/spi/VERSION new file mode 100644 index 0000000000..a0acb181b6 --- /dev/null +++ b/bsps/shared/dev/spi/VERSION @@ -0,0 +1,29 @@ +The information in this file describes the source of the following files in +bsps/shared/dev/spi/ and bsps/include/dev/spi/: + +- xqspipsu_control.c +- xqspipsu_control.h +- xqspipsu_flash_config.h +- xqspipsu_hw.c +- xqspipsu_hw.h +- xqspipsu_options.c +- xqspipsu.c +- xqspipsu.h + +Import from: + +https://github.com/Xilinx/embeddedsw.git + +commit 8a89579489c88ea5acd23d7d439ac928659c26cf +Author: msreeram <manikanta.sreeram@xilinx.com> +AuthorDate: Wed Apr 6 23:24:38 2022 -0600 +Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com> +CommitDate: Fri Apr 8 16:47:15 2022 +0530 + + update license file for EmbeddedSW 2022.1 release + + Update license file for EmbeddedSW 2022.1 release + + Signed-off-by: Manikanta Sreeram <msreeram@xilinx.com> + + Acked-by : Meena Paleti <meena.paleti@xilinx.com> diff --git a/bsps/shared/dev/spi/xqspipsu-flash-helper.c b/bsps/shared/dev/spi/xqspipsu-flash-helper.c new file mode 100644 index 0000000000..10e1066173 --- /dev/null +++ b/bsps/shared/dev/spi/xqspipsu-flash-helper.c @@ -0,0 +1,2341 @@ +/****************************************************************************** +* Copyright (C) 2018 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/** + * @file xqspipsu_flash_helper.c + * + * This file contains flash helper functions for the QSPIPSU driver. It + * consists of modified functions from Xilinx's flash example in + * examples/xqspipsu_generic_flash_interrupt_example.c of the qspipsu driver. + * + */ + +#include "xqspipsu_flash_config.h" +#include "xqspipsu-flash-helper.h" + +#include <rtems.h> + +/* + * Number of flash pages to be written. + */ +#define PAGE_COUNT 32 + +/* + * Max page size to initialize write and read buffer + */ +#define MAX_PAGE_SIZE 1024 + +#define TEST_ADDRESS 0x000000 + +#define ENTER_4B 1 +#define EXIT_4B 0 + +u8 ReadCmd; +u8 WriteCmd; +u8 StatusCmd; +u8 SectorEraseCmd; +u8 FSRFlag; + +static int FlashReadID(XQspiPsu *QspiPsuPtr); + +static int MultiDieRead( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 Command, + u8 *WriteBfrPtr, + u8 *ReadBfrPtr +); + +static u32 GetRealAddr( + XQspiPsu *QspiPsuPtr, + u32 Address +); + +static int BulkErase( + XQspiPsu *QspiPsuPtr, + u8 *WriteBfrPtr +); + +static int DieErase( + XQspiPsu *QspiPsuPtr, + u8 *WriteBfrPtr +); + +static int QspiPsuSetupIntrSystem( + XQspiPsu *QspiPsuInstancePtr, + u16 QspiPsuIntrId +); + +static void QspiPsuHandler( + void *CallBackRef, + u32 StatusEvent, + unsigned int ByteCount +); + +static int FlashEnterExit4BAddMode( + XQspiPsu *QspiPsuPtr, + unsigned int Enable +); + +static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr); + +u8 TxBfrPtr; +u8 ReadBfrPtr[3]; +u32 FlashMake; +u32 FCTIndex; /* Flash configuration table index */ + +static XQspiPsu_Msg FlashMsg[5]; + +/* + * The following variables are shared between non-interrupt processing and + * interrupt processing such that they must be global. + */ +volatile int TransferInProgress; + +/* + * The following variable tracks any errors that occur during interrupt + * processing + */ +int Error; + +/* + * The following variable allows a test value to be added to the values that + * are written to the Flash such that unique values can be generated to + * guarantee the writes to the Flash were successful + */ +int Test = 1; + +/* + * The following variables are used to read and write to the flash and they + * are global to avoid having large buffers on the stack + * The buffer size accounts for maximum page size and maximum banks - + * for each bank separate read will be performed leading to that many + * (overhead+dummy) bytes + */ +#ifdef __ICCARM__ +#pragma data_alignment = 32 +u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8]; +#else +u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8] __attribute__ ((aligned(64))); +#endif +u8 WriteBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + DATA_OFFSET]; +u8 CmdBfr[8]; + +/* + * The following constants specify the max amount of data and the size of the + * the buffer required to hold the data and overhead to transfer the data to + * and from the Flash. Initialized to single flash page size. + */ +u32 MaxData = PAGE_COUNT*256; + +int QspiPsu_NOR_Initialize( + XQspiPsu *QspiPsuInstancePtr, + u16 QspiPsuIntrId +) +{ + int Status; + + if (QspiPsuInstancePtr == NULL) { + return XST_FAILURE; + } + + /* + * Connect the QspiPsu device to the interrupt subsystem such that + * interrupts can occur. This function is application specific + */ + Status = QspiPsuSetupIntrSystem(QspiPsuInstancePtr, QspiPsuIntrId); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Setup the handler for the QSPIPSU that will be called from the + * interrupt context when an QSPIPSU status occurs, specify a pointer to + * the QSPIPSU driver instance as the callback reference + * so the handler is able to access the instance data + */ + XQspiPsu_SetStatusHandler(QspiPsuInstancePtr, QspiPsuInstancePtr, + (XQspiPsu_StatusHandler) QspiPsuHandler); + + /* + * Set Manual Start + */ + XQspiPsu_SetOptions(QspiPsuInstancePtr, XQSPIPSU_MANUAL_START_OPTION); + + /* + * Set the prescaler for QSPIPSU clock + */ + XQspiPsu_SetClkPrescaler(QspiPsuInstancePtr, XQSPIPSU_CLK_PRESCALE_8); + + XQspiPsu_SelectFlash(QspiPsuInstancePtr, + XQSPIPSU_SELECT_FLASH_CS_LOWER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + + /* + * Read flash ID and obtain all flash related information + * It is important to call the read id function before + * performing proceeding to any operation, including + * preparing the WriteBuffer + */ + + Status = FlashReadID(QspiPsuInstancePtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Some flash needs to enable Quad mode before using + * quad commands. + */ + Status = FlashEnableQuadMode(QspiPsuInstancePtr); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + /* + * Address size and read command selection + * Micron flash on REMUS doesn't support these 4B write/erase commands + */ + if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE) + ReadCmd = FAST_READ_CMD; + else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE) + ReadCmd = DUAL_READ_CMD; + else + ReadCmd = QUAD_READ_CMD; + + WriteCmd = WRITE_CMD; + SectorEraseCmd = SEC_ERASE_CMD; + + if ((Flash_Config_Table[FCTIndex].NumDie > 1) && + (FlashMake == MICRON_ID_BYTE0)) { + StatusCmd = READ_FLAG_STATUS_CMD; + FSRFlag = 1; + } else { + StatusCmd = READ_STATUS_CMD; + FSRFlag = 0; + } + + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + Status = FlashEnterExit4BAddMode(QspiPsuInstancePtr, ENTER_4B); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + if (FlashMake == SPANSION_ID_BYTE0) { + if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE) + ReadCmd = FAST_READ_CMD_4B; + else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE) + ReadCmd = DUAL_READ_CMD_4B; + else + ReadCmd = QUAD_READ_CMD_4B; + + WriteCmd = WRITE_CMD_4B; + SectorEraseCmd = SEC_ERASE_CMD_4B; + } + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Callback handler. + * + * @param CallBackRef is the upper layer callback reference passed back + * when the callback function is invoked. + * @param StatusEvent is the event that just occurred. + * @param ByteCount is the number of bytes transferred up until the event + * occurred. + * + * @return None + * + * @note None. + * + *****************************************************************************/ +static void QspiPsuHandler( + void *CallBackRef, + u32 StatusEvent, + unsigned int ByteCount +) +{ + /* + * Indicate the transfer on the QSPIPSU bus is no longer in progress + * regardless of the status event + */ + TransferInProgress = FALSE; + + /* + * If the event was not transfer done, then track it as an error + */ + if (StatusEvent != XST_SPI_TRANSFER_DONE) { + Error++; + } +} + +int QspiPsu_NOR_RDSFDP( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 **ReadBfrPtr +) +{ + int Status; + + *ReadBfrPtr = ReadBuffer; + + CmdBfr[COMMAND_OFFSET] = READ_SFDP; + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((Address & 0xFF0000) >> 16); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((Address & 0xFF00) >> 8); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)(Address & 0xFF); + + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].TxBfrPtr = CmdBfr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 4; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = DUMMY_CLOCKS; + FlashMsg[1].Flags = 0; + + FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[2].TxBfrPtr = NULL; + FlashMsg[2].RxBfrPtr = *ReadBfrPtr; + FlashMsg[2].ByteCount = ByteCount; + FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 3); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount); + return 0; +} + +int QspiPsu_NOR_RDID(XQspiPsu *QspiPsuPtr, u8 *ReadBfrPtr, u32 ReadLen) +{ + int Status; + + /* + * Read ID + */ + TxBfrPtr = READ_ID; + FlashMsg[0].TxBfrPtr = &TxBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = ReadBfrPtr; + FlashMsg[1].ByteCount = ReadLen; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ReadLen); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Reads the flash ID and identifies the flash in FCT table. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + *****************************************************************************/ +static int FlashReadID(XQspiPsu *QspiPsuPtr) +{ + u32 ReadId = 0; + u32 ReadLen = 3; + int Status; + + Status = QspiPsu_NOR_RDID(QspiPsuPtr, ReadBfrPtr, ReadLen); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* In case of dual, read both and ensure they are same make/size */ + + /* + * Deduce flash make + */ + FlashMake = ReadBfrPtr[0]; + + ReadId = ((ReadBfrPtr[0] << 16) | (ReadBfrPtr[1] << 8) | ReadBfrPtr[2]); + /* + * Assign corresponding index in the Flash configuration table + */ + Status = CalculateFCTIndex(ReadId, &FCTIndex); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + +int QspiPsu_NOR_Write_Page( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr +) +{ + u8 WriteEnableCmd; + u8 ReadStatusCmd; + u8 FlashStatus[2]; + u8 WriteCmdBfr[5]; + u32 RealAddr; + u32 CmdByteCount; + int Status; + + WriteEnableCmd = WRITE_ENABLE_CMD; + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer before + * the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + while (TransferInProgress); + + WriteCmdBfr[COMMAND_OFFSET] = WriteCmd; + + /* To be used only if 4B address program cmd is supported by flash */ + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + WriteCmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + WriteCmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteCmdBfr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteCmdBfr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xFF); + CmdByteCount = 5; + } else { + WriteCmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteCmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteCmdBfr[ADDRESS_3_OFFSET] = + (u8)(RealAddr & 0xFF); + CmdByteCount = 4; + } + + FlashMsg[0].TxBfrPtr = WriteCmdBfr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = CmdByteCount; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = WriteBfrPtr; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = ByteCount; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + while (TransferInProgress); + + /* + * Wait for the write command to the Flash to be completed, it takes + * some time for the data to be written + */ + while (1) { + ReadStatusCmd = StatusCmd; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if (FSRFlag) { + if ((FlashStatus[1] & 0x80) != 0) { + break; + } + } else { + if ((FlashStatus[1] & 0x01) == 0) { + break; + } + } + } + + return 0; +} + +int QspiPsu_NOR_Write( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr +) +{ + int Status; + size_t ByteCountRemaining = ByteCount; + unsigned char *WriteBfrPartial = WriteBfrPtr; + uint32_t AddressPartial = Address; + uint32_t PageSize = Flash_Config_Table[FCTIndex].PageSize; + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + PageSize *= 2; + } + + while (ByteCountRemaining > 0) { + /* Get write boundary */ + size_t WriteChunkLen = RTEMS_ALIGN_UP(AddressPartial + 1, PageSize); + + /* Get offset to write boundary */ + WriteChunkLen -= (size_t)AddressPartial; + + /* Cap short writes */ + if (WriteChunkLen > ByteCountRemaining) { + WriteChunkLen = ByteCountRemaining; + } + + Status = QspiPsu_NOR_Write_Page( + QspiPsuPtr, + AddressPartial, + WriteChunkLen, + WriteBfrPartial + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + ByteCountRemaining -= WriteChunkLen; + AddressPartial += WriteChunkLen; + WriteBfrPartial += WriteChunkLen; + } + return Status; +} + +int QspiPsu_NOR_Erase( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount +) +{ + u8 WriteEnableCmd; + u8 ReadStatusCmd; + u8 FlashStatus[2]; + int Sector; + u32 RealAddr; + u32 NumSect; + int Status; + u32 SectSize; + + WriteEnableCmd = WRITE_ENABLE_CMD; + + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2; + NumSect = (Flash_Config_Table[FCTIndex]).NumSect; + } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) { + NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2; + SectSize = (Flash_Config_Table[FCTIndex]).SectSize; + } else { + SectSize = (Flash_Config_Table[FCTIndex]).SectSize; + NumSect = (Flash_Config_Table[FCTIndex]).NumSect; + } + + /* + * If erase size is same as the total size of the flash, use bulk erase + * command or die erase command multiple times as required + */ + if (ByteCount == NumSect * SectSize) { + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_STACKED) { + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_LOWER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + } + + if (Flash_Config_Table[FCTIndex].NumDie == 1) { + /* + * Call Bulk erase + */ + BulkErase(QspiPsuPtr, CmdBfr); + } + + if (Flash_Config_Table[FCTIndex].NumDie > 1) { + /* + * Call Die erase + */ + DieErase(QspiPsuPtr, CmdBfr); + } + /* + * If stacked mode, bulk erase second flash + */ + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_STACKED) { + + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_UPPER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + + if (Flash_Config_Table[FCTIndex].NumDie == 1) { + /* + * Call Bulk erase + */ + BulkErase(QspiPsuPtr, CmdBfr); + } + + if (Flash_Config_Table[FCTIndex].NumDie > 1) { + /* + * Call Die erase + */ + DieErase(QspiPsuPtr, CmdBfr); + } + } + + return 0; + } + + /* + * If the erase size is less than the total size of the flash, use + * sector erase command + */ + + /* + * Calculate no. of sectors to erase based on byte count + */ + u32 SectorStartBase = RTEMS_ALIGN_DOWN(Address, SectSize); + u32 SectorEndTop = RTEMS_ALIGN_UP(Address + ByteCount, SectSize); + NumSect = (SectorEndTop - SectorStartBase)/SectSize; + + for (Sector = 0; Sector < NumSect; Sector++) { + + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate + * transfer before the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + CmdBfr[COMMAND_OFFSET] = SectorEraseCmd; + + /* + * To be used only if 4B address sector erase cmd is + * supported by flash + */ + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xFF); + FlashMsg[0].ByteCount = 5; + } else { + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)(RealAddr & 0xFF); + FlashMsg[0].ByteCount = 4; + } + + FlashMsg[0].TxBfrPtr = CmdBfr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + /* + * Wait for the erase command to be completed + */ + while (1) { + ReadStatusCmd = StatusCmd; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if (FSRFlag) { + if ((FlashStatus[1] & 0x80) != 0) { + break; + } + } else { + if ((FlashStatus[1] & 0x01) == 0) { + break; + } + } + } + Address += SectSize; + } + + return 0; +} + +int QspiPsu_NOR_Read( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 **ReadBfrPtr +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + int Status; + + *ReadBfrPtr = ReadBuffer; + + /* Check die boundary conditions if required for any flash */ + if (Flash_Config_Table[FCTIndex].NumDie > 1) { + + Status = MultiDieRead(QspiPsuPtr, Address, ByteCount, ReadCmd, + CmdBfr, *ReadBfrPtr); + if (Status != XST_SUCCESS) + return XST_FAILURE; + } else { + /* For Dual Stacked, split and read for boundary crossing */ + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + CmdBfr[COMMAND_OFFSET] = ReadCmd; + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xFF); + DiscardByteCnt = 5; + } else { + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)(RealAddr & 0xFF); + DiscardByteCnt = 4; + } + + FlashMsg[0].TxBfrPtr = CmdBfr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = DiscardByteCnt; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt = 1; + + /* It is recommended to have a separate entry for dummy */ + if (ReadCmd == FAST_READ_CMD || ReadCmd == DUAL_READ_CMD || + ReadCmd == QUAD_READ_CMD || ReadCmd == FAST_READ_CMD_4B || + ReadCmd == DUAL_READ_CMD_4B || + ReadCmd == QUAD_READ_CMD_4B) { + /* Update Dummy cycles as per flash specs for QUAD IO */ + + /* + * It is recommended that Bus width value during dummy + * phase should be same as data phase + */ + if (ReadCmd == FAST_READ_CMD || + ReadCmd == FAST_READ_CMD_4B) { + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + } + + if (ReadCmd == DUAL_READ_CMD || + ReadCmd == DUAL_READ_CMD_4B) { + FlashMsg[1].BusWidth = + XQSPIPSU_SELECT_MODE_DUALSPI; + } + + if (ReadCmd == QUAD_READ_CMD || + ReadCmd == QUAD_READ_CMD_4B) { + FlashMsg[1].BusWidth = + XQSPIPSU_SELECT_MODE_QUADSPI; + } + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = DUMMY_CLOCKS; + FlashMsg[1].Flags = 0; + + FlashMsgCnt++; + } + + /* Dummy cycles need to be changed as per flash specs + * for QUAD IO + */ + if (ReadCmd == FAST_READ_CMD || ReadCmd == FAST_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_SPI; + + if (ReadCmd == DUAL_READ_CMD || ReadCmd == DUAL_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_DUALSPI; + + if (ReadCmd == QUAD_READ_CMD || ReadCmd == QUAD_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_QUADSPI; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = *ReadBfrPtr; + FlashMsg[FlashMsgCnt].ByteCount = ByteCount; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + } + rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount); + return 0; +} + +/*****************************************************************************/ +/** + * + * This function performs a read operation for multi die flash devices. + * Default setting is in DMA mode. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param Address contains the address of the first sector which needs to + * be erased. + * @param ByteCount contains the total size to be erased. + * @param Command is the command used to read data from the flash. + * Supports normal, fast, dual and quad read commands. + * @param WriteBfrPtr is pointer to the write buffer which contains data to be + * transmitted + * @param ReadBfrPtr is pointer to the read buffer to which valid received data + * should be written + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int MultiDieRead( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 Command, + u8 *WriteBfrPtr, + u8 *ReadBfrPtr +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + int Status; + u32 cur_bank = 0; + u32 nxt_bank = 0; + u32 bank_size; + u32 remain_len = ByteCount; + u32 data_len; + u32 transfer_len; + u8 *ReadBuffer = ReadBfrPtr; + + /* + * Some flash devices like N25Q512 have multiple dies + * in it. Read operation in these devices is bounded + * by its die segment. In a continuous read, across + * multiple dies, when the last byte of the selected + * die segment is read, the next byte read is the + * first byte of the same die segment. This is Die + * cross over issue. So to handle this issue, split + * a read transaction, that spans across multiple + * banks, into one read per bank. Bank size is 16MB + * for single and dual stacked mode and 32MB for dual + * parallel mode. + */ + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + bank_size = SIXTEENMB << 1; + else + bank_size = SIXTEENMB; + + while (remain_len) { + cur_bank = Address / bank_size; + nxt_bank = (Address + remain_len) / bank_size; + + if (cur_bank != nxt_bank) { + transfer_len = (bank_size * (cur_bank + 1)) - Address; + if (remain_len < transfer_len) + data_len = remain_len; + else + data_len = transfer_len; + } else { + data_len = remain_len; + } + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + WriteBfrPtr[COMMAND_OFFSET] = Command; + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xFF); + DiscardByteCnt = 5; + } else { + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)(RealAddr & 0xFF); + DiscardByteCnt = 4; + } + + FlashMsg[0].TxBfrPtr = WriteBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = DiscardByteCnt; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt = 1; + + /* It is recommended to have a separate entry for dummy */ + if (Command == FAST_READ_CMD || Command == DUAL_READ_CMD || + Command == QUAD_READ_CMD || Command == FAST_READ_CMD_4B || + Command == DUAL_READ_CMD_4B || + Command == QUAD_READ_CMD_4B) { + /* Update Dummy cycles as per flash specs for QUAD IO */ + + /* + * It is recommended that Bus width value during dummy + * phase should be same as data phase + */ + if (Command == FAST_READ_CMD || + Command == FAST_READ_CMD_4B) { + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + } + + if (Command == DUAL_READ_CMD || + Command == DUAL_READ_CMD_4B) { + FlashMsg[1].BusWidth = + XQSPIPSU_SELECT_MODE_DUALSPI; + } + + if (Command == QUAD_READ_CMD || + Command == QUAD_READ_CMD_4B) { + FlashMsg[1].BusWidth = + XQSPIPSU_SELECT_MODE_QUADSPI; + } + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = DUMMY_CLOCKS; + FlashMsg[1].Flags = 0; + + FlashMsgCnt++; + } + + /* Dummy cycles need to be changed as per flash + * specs for QUAD IO + */ + if (Command == FAST_READ_CMD || Command == FAST_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_SPI; + + if (Command == DUAL_READ_CMD || Command == DUAL_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_DUALSPI; + + if (Command == QUAD_READ_CMD || Command == QUAD_READ_CMD_4B) + FlashMsg[FlashMsgCnt].BusWidth = + XQSPIPSU_SELECT_MODE_QUADSPI; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer; + FlashMsg[FlashMsgCnt].ByteCount = data_len; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + FlashMsg[FlashMsgCnt].Flags |= + XQSPIPSU_MSG_FLAG_STRIPE; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + + ReadBuffer += data_len; + Address += data_len; + remain_len -= data_len; + } + rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ByteCount); + return 0; +} + +/*****************************************************************************/ +/** + * + * This functions performs a bulk erase operation when the + * flash device has a single die. Works for both Spansion and Micron + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param WriteBfrPtr is the pointer to command+address to be sent + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int BulkErase( + XQspiPsu *QspiPsuPtr, + u8 *WriteBfrPtr +) +{ + u8 WriteEnableCmd; + u8 ReadStatusCmd; + u8 FlashStatus[2]; + int Status; + + WriteEnableCmd = WRITE_ENABLE_CMD; + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer before + * the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + WriteBfrPtr[COMMAND_OFFSET] = BULK_ERASE_CMD; + FlashMsg[0].TxBfrPtr = WriteBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + /* + * Wait for the write command to the Flash to be completed, it takes + * some time for the data to be written + */ + while (1) { + ReadStatusCmd = StatusCmd; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if (FSRFlag) { + if ((FlashStatus[1] & 0x80) != 0) { + break; + } + } else { + if ((FlashStatus[1] & 0x01) == 0) { + break; + } + } + } + + return 0; +} + +/*****************************************************************************/ +/** + * + * This functions performs a die erase operation on all the die in + * the flash device. This function uses the die erase command for + * Micron 512Mbit and 1Gbit + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param WriteBfrPtr is the pointer to command+address to be sent + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int DieErase( + XQspiPsu *QspiPsuPtr, + u8 *WriteBfrPtr +) +{ + u8 WriteEnableCmd; + u8 DieCnt; + u8 ReadStatusCmd; + u8 FlashStatus[2]; + int Status; + u32 DieSize = 0; + u32 Address; + u32 RealAddr; + u32 SectSize = 0; + u32 NumSect = 0; + + WriteEnableCmd = WRITE_ENABLE_CMD; + + if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2; + } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) { + NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2; + } else { + SectSize = (Flash_Config_Table[FCTIndex]).SectSize; + NumSect = (Flash_Config_Table[FCTIndex]).NumSect; + } + DieSize = (NumSect * SectSize) / Flash_Config_Table[FCTIndex].NumDie; + + for (DieCnt = 0; + DieCnt < Flash_Config_Table[FCTIndex].NumDie; + DieCnt++) { + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer + * before the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + WriteBfrPtr[COMMAND_OFFSET] = DIE_ERASE_CMD; + + Address = DieSize * DieCnt; + RealAddr = GetRealAddr(QspiPsuPtr, Address); + /* + * To be used only if 4B address sector erase cmd is + * supported by flash + */ + if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) { + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xFF); + FlashMsg[0].ByteCount = 5; + } else { + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)(RealAddr & 0xFF); + FlashMsg[0].ByteCount = 4; + } + FlashMsg[0].TxBfrPtr = WriteBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + /* + * Wait for the write command to the Flash to be completed, + * it takes some time for the data to be written + */ + while (1) { + ReadStatusCmd = StatusCmd; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if (FSRFlag) { + if ((FlashStatus[1] & 0x80) != 0) { + break; + } + } else { + if ((FlashStatus[1] & 0x01) == 0) { + break; + } + } + } + } + + return 0; +} + +/*****************************************************************************/ +/** + * + * This functions translates the address based on the type of interconnection. + * In case of stacked, this function asserts the corresponding slave select. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param Address which is to be accessed (for erase, write or read) + * + * @return RealAddr is the translated address - for single it is unchanged; + * for stacked, the lower flash size is subtracted; + * for parallel the address is divided by 2. + * + * @note In addition to get the actual address to work on flash this + * function also selects the CS and BUS based on the configuration + * detected. + * + ******************************************************************************/ +static u32 GetRealAddr( + XQspiPsu *QspiPsuPtr, + u32 Address +) +{ + u32 RealAddr = 0; + + switch (QspiPsuPtr->Config.ConnectionMode) { + case XQSPIPSU_CONNECTION_MODE_SINGLE: + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_LOWER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + RealAddr = Address; + break; + case XQSPIPSU_CONNECTION_MODE_STACKED: + /* Select lower or upper Flash based on sector address */ + if (Address & Flash_Config_Table[FCTIndex].FlashDeviceSize) { + + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_UPPER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + /* + * Subtract first flash size when accessing second flash + */ + RealAddr = Address & + (~Flash_Config_Table[FCTIndex].FlashDeviceSize); + }else{ + /* + * Set selection to L_PAGE + */ + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_LOWER, + XQSPIPSU_SELECT_FLASH_BUS_LOWER); + + RealAddr = Address; + + } + break; + case XQSPIPSU_CONNECTION_MODE_PARALLEL: + /* + * The effective address in each flash is the actual + * address / 2 + */ + XQspiPsu_SelectFlash(QspiPsuPtr, + XQSPIPSU_SELECT_FLASH_CS_BOTH, + XQSPIPSU_SELECT_FLASH_BUS_BOTH); + RealAddr = Address / 2; + break; + default: + /* RealAddr wont be assigned in this case; */ + break; + + } + + return(RealAddr); +} + +/*****************************************************************************/ +/** + * + * This function setups the interrupt system for a QspiPsu device. + * + * @param QspiPsuInstancePtr is a pointer to the instance of the + * QspiPsu device. + * @param QspiPsuIntrId is the interrupt Id for an QSPIPSU device. + * + * @return XST_SUCCESS if successful, otherwise XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int QspiPsuSetupIntrSystem( + XQspiPsu *QspiPsuInstancePtr, + u16 QspiPsuIntrId +) +{ + return rtems_interrupt_handler_install( + QspiPsuIntrId, + NULL, + RTEMS_INTERRUPT_UNIQUE, + (rtems_interrupt_handler) XQspiPsu_InterruptHandler, + QspiPsuInstancePtr + ); +} + +/*****************************************************************************/ +/** + * @brief + * This API enters the flash device into 4 bytes addressing mode. + * As per the Micron and ISSI spec, before issuing the command + * to enter into 4 byte addr mode, a write enable command is issued. + * For Macronix and Winbond flash parts write + * enable is not required. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param Enable is a either 1 or 0 if 1 then enters 4 byte if 0 exits. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if it fails. + * + * + ******************************************************************************/ +static int FlashEnterExit4BAddMode( + XQspiPsu *QspiPsuPtr, + unsigned int Enable +) +{ + int Status; + u8 WriteEnableCmd; + u8 Cmd; + u8 WriteDisableCmd; + u8 ReadStatusCmd; + u8 WriteBuffer[2] = {0}; + u8 FlashStatus[2] = {0}; + + if (Enable) { + Cmd = ENTER_4B_ADDR_MODE; + } else { + if (FlashMake == ISSI_ID_BYTE0) + Cmd = EXIT_4B_ADDR_MODE_ISSI; + else + Cmd = EXIT_4B_ADDR_MODE; + } + + switch (FlashMake) { + case ISSI_ID_BYTE0: + case MICRON_ID_BYTE0: + WriteEnableCmd = WRITE_ENABLE_CMD; + GetRealAddr(QspiPsuPtr, TEST_ADDRESS); + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer + * before the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + break; + + case SPANSION_ID_BYTE0: + + /* Read Extended Addres Register */ + WriteBuffer[0] = BANK_REG_RD; + FlashMsg[0].TxBfrPtr = &WriteBuffer[0]; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = &WriteBuffer[1]; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + if (Enable) { + WriteBuffer[0] = BANK_REG_WR; + WriteBuffer[1] |= 1 << 7; + } else { + WriteBuffer[0] = BANK_REG_WR; + WriteBuffer[1] &= ~(0x01 << 7); + } + + FlashMsg[0].TxBfrPtr = &WriteBuffer[0]; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[0].ByteCount = 1; + FlashMsg[1].TxBfrPtr = &WriteBuffer[1]; + FlashMsg[2].RxBfrPtr = NULL; + FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[2].ByteCount = 1; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + WriteBuffer[0] = BANK_REG_RD; + FlashMsg[0].TxBfrPtr = &WriteBuffer[0]; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = &FlashStatus[0]; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + return Status; + + default: + /* + * For Macronix and Winbond flash parts + * Write enable command is not required. + */ + break; + } + + GetRealAddr(QspiPsuPtr, TEST_ADDRESS); + + FlashMsg[0].TxBfrPtr = &Cmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + while (1) { + ReadStatusCmd = StatusCmd; + + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if (FSRFlag) { + if ((FlashStatus[1] & 0x80) != 0) { + break; + } + } else { + if ((FlashStatus[1] & 0x01) == 0) { + break; + } + } + } + + switch (FlashMake) { + case ISSI_ID_BYTE0: + case MICRON_ID_BYTE0: + WriteDisableCmd = WRITE_DISABLE_CMD; + GetRealAddr(QspiPsuPtr, TEST_ADDRESS); + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer + * before the write + */ + FlashMsg[0].TxBfrPtr = &WriteDisableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + break; + + default: + /* + * For Macronix and Winbond flash parts + * Write disable command is not required. + */ + break; + } + return Status; +} + +/*****************************************************************************/ +/** + * @brief + * This API enables Quad mode for the flash parts which require to enable quad + * mode before using Quad commands. + * For S25FL-L series flash parts this is required as the default configuration + * is x1/x2 mode. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if it fails. + * + * + ******************************************************************************/ +static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr) +{ + int Status; + u8 WriteEnableCmd; + u8 ReadStatusCmd; + u8 FlashStatus[2]; + u8 StatusRegVal; + u8 WriteBuffer[3] = {0}; + + switch (FlashMake) { + case SPANSION_ID_BYTE0: + TxBfrPtr = READ_CONFIG_CMD; + FlashMsg[0].TxBfrPtr = &TxBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = &WriteBuffer[2]; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + WriteEnableCmd = WRITE_ENABLE_CMD; + /* + * Send the write enable command to the Flash + * so that it can be written to, this needs + * to be sent as a separate transfer before + * the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + GetRealAddr(QspiPsuPtr, TEST_ADDRESS); + + WriteBuffer[0] = WRITE_CONFIG_CMD; + WriteBuffer[1] |= 0x02; + WriteBuffer[2] |= 0x01 << 1; + + FlashMsg[0].TxBfrPtr = &WriteBuffer[0]; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[0].ByteCount = 1; + FlashMsg[1].TxBfrPtr = &WriteBuffer[1]; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + while (1) { + TxBfrPtr = READ_STATUS_CMD; + FlashMsg[0].TxBfrPtr = &TxBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, + FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + }else { + FlashStatus[1] |= FlashStatus[0]; + } + } + + if ((FlashStatus[1] & 0x01) == 0x00) + break; + } + TxBfrPtr = READ_CONFIG_CMD; + FlashMsg[0].TxBfrPtr = &TxBfrPtr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = ReadBfrPtr; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + break; + case ISSI_ID_BYTE0: + /* + * Read Status Register to a buffer + */ + ReadStatusCmd = READ_STATUS_CMD; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + /* + * Set Quad Enable Bit in the buffer + */ + StatusRegVal = FlashStatus[1]; + StatusRegVal |= 0x1 << QUAD_MODE_ENABLE_BIT; + + /* + * Write enable + */ + WriteEnableCmd = WRITE_ENABLE_CMD; + /* + * Send the write enable command to the Flash so that it can be + * written to, this needs to be sent as a separate transfer + * before the write + */ + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + /* + * Write Status register + */ + WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_CMD; + FlashMsg[0].TxBfrPtr = WriteBuffer; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = &StatusRegVal; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX; + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + /* + * Write Disable + */ + WriteEnableCmd = WRITE_DISABLE_CMD; + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + break; + + case WINBOND_ID_BYTE0: + ReadStatusCmd = READ_STATUS_REG_2_CMD; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + /* + * Set Quad Enable Bit in the buffer + */ + StatusRegVal = FlashStatus[1]; + StatusRegVal |= 0x1 << WB_QUAD_MODE_ENABLE_BIT; + /* + * Write Enable + */ + WriteEnableCmd = WRITE_ENABLE_CMD; + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + /* + * Write Status register + */ + WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_REG_2_CMD; + FlashMsg[0].TxBfrPtr = WriteBuffer; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].TxBfrPtr = &StatusRegVal; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = 1; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + while (1) { + ReadStatusCmd = READ_STATUS_CMD; + FlashMsg[0].TxBfrPtr = &ReadStatusCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = FlashStatus; + FlashMsg[1].ByteCount = 2; + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + if (FSRFlag) { + FlashStatus[1] &= FlashStatus[0]; + } else { + FlashStatus[1] |= FlashStatus[0]; + } + } + if ((FlashStatus[1] & 0x01) == 0x00) { + break; + } + } + /* + * Write Disable + */ + WriteEnableCmd = WRITE_DISABLE_CMD; + FlashMsg[0].TxBfrPtr = &WriteEnableCmd; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 1; + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + while (TransferInProgress); + break; + + default: + /* + * Currently only S25FL-L series requires the + * Quad enable bit to be set to 1. + */ + Status = XST_SUCCESS; + break; + } + + return Status; +} + +static int MultiDieReadEcc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr, + u8 *ReadBfrPtr +); + +int QspiPsu_NOR_Read_Ecc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u8 *ReadBfrPtr +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + u8 EccBuffer[16]; + int ByteCount = sizeof(EccBuffer); + int Status; + + /* Check die boundary conditions if required for any flash */ + if (Flash_Config_Table[FCTIndex].NumDie > 1) { + + Status = MultiDieReadEcc(QspiPsuPtr, Address, ByteCount, + CmdBfr, EccBuffer); + if (Status == XST_SUCCESS) { + /* All bytes are the same, so copy one return byte into the output buffer */ + *ReadBfrPtr = EccBuffer[0]; + } + return Status; + } + + /* For Dual Stacked, split and read for boundary crossing */ + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + CmdBfr[COMMAND_OFFSET] = READ_ECCSR; + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xF0); + DiscardByteCnt = 5; + + FlashMsgCnt = 0; + + FlashMsg[FlashMsgCnt].TxBfrPtr = CmdBfr; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS; + FlashMsg[FlashMsgCnt].Flags = 0; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = EccBuffer; + FlashMsg[FlashMsgCnt].ByteCount = ByteCount; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status == XST_SUCCESS) { + while (TransferInProgress); + + /* All bytes are the same, so copy one return byte into the output buffer */ + *ReadBfrPtr = EccBuffer[0]; + } + + return Status; +} + +/*****************************************************************************/ +/** + * + * This function performs an ECC read operation for multi die flash devices. + * Default setting is in DMA mode. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param Address contains the address of the first sector which needs to + * be erased. + * @param ByteCount contains the total size to be erased. + * @param WriteBfrPtr is pointer to the write buffer which contains data to be + * transmitted + * @param ReadBfrPtr is pointer to the read buffer to which valid received data + * should be written + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int MultiDieReadEcc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr, + u8 *ReadBuffer +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + int Status; + u32 cur_bank = 0; + u32 nxt_bank = 0; + u32 bank_size; + u32 remain_len = ByteCount; + u32 data_len; + u32 transfer_len; + + /* + * Some flash devices like N25Q512 have multiple dies + * in it. Read operation in these devices is bounded + * by its die segment. In a continuous read, across + * multiple dies, when the last byte of the selected + * die segment is read, the next byte read is the + * first byte of the same die segment. This is Die + * cross over issue. So to handle this issue, split + * a read transaction, that spans across multiple + * banks, into one read per bank. Bank size is 16MB + * for single and dual stacked mode and 32MB for dual + * parallel mode. + */ + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + bank_size = SIXTEENMB << 1; + else + bank_size = SIXTEENMB; + + while (remain_len) { + cur_bank = Address / bank_size; + nxt_bank = (Address + remain_len) / bank_size; + + if (cur_bank != nxt_bank) { + transfer_len = (bank_size * (cur_bank + 1)) - Address; + if (remain_len < transfer_len) + data_len = remain_len; + else + data_len = transfer_len; + } else { + data_len = remain_len; + } + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + WriteBfrPtr[COMMAND_OFFSET] = READ_ECCSR; + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xF0); + DiscardByteCnt = 5; + + FlashMsgCnt = 0; + + FlashMsg[FlashMsgCnt].TxBfrPtr = WriteBfrPtr; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS; + FlashMsg[FlashMsgCnt].Flags = 0; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer; + FlashMsg[FlashMsgCnt].ByteCount = data_len; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + FlashMsg[FlashMsgCnt].Flags |= + XQSPIPSU_MSG_FLAG_STRIPE; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + ReadBuffer += data_len; + Address += data_len; + remain_len -= data_len; + } + return 0; +} + +u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + return Flash_Config_Table[FCTIndex].SectSize * 2; + } + return Flash_Config_Table[FCTIndex].SectSize; +} + +u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED + || QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + return Flash_Config_Table[FCTIndex].FlashDeviceSize * 2; + } + return Flash_Config_Table[FCTIndex].FlashDeviceSize; +} diff --git a/bsps/shared/dev/spi/xqspipsu.c b/bsps/shared/dev/spi/xqspipsu.c new file mode 100644 index 0000000000..93d3fa4c98 --- /dev/null +++ b/bsps/shared/dev/spi/xqspipsu.c @@ -0,0 +1,1086 @@ +/****************************************************************************** +* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*****************************************************************************/ +/** + * + * @file xqspipsu.c + * @addtogroup Overview + * @{ + * + * This file implements the functions required to use the QSPIPSU hardware to + * perform a transfer. These are accessible to the user via xqspipsu.h. + * + * <pre> + * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- --- -------- ----------------------------------------------- + * 1.0 hk 08/21/14 First release + * sk 03/13/15 Added IO mode support. + * hk 03/18/15 Switch to I/O mode before clearing RX FIFO. + * Clear and disable DMA interrupts/status in abort. + * Use DMA DONE bit instead of BUSY as recommended. + * sk 04/24/15 Modified the code according to MISRAC-2012. + * sk 06/17/15 Removed NULL checks for Rx/Tx buffers. As + * writing/reading from 0x0 location is permitted. + * 1.1 sk 04/12/16 Added debug message prints. + * 1.2 nsk 07/01/16 Changed XQspiPsu_Select to support GQSPI and LQSPI + * selection. + * rk 07/15/16 Added support for TapDelays at different frequencies. + * nsk 08/05/16 Added example support PollData and PollTimeout + * 1.3 nsk 09/16/16 Update PollData and PollTimeout support for dual + * parallel configurations, modified XQspiPsu_PollData() + * and XQspiPsu_Create_PollConfigData() + * 1,5 nsk 08/14/17 Added CCI support + * 1.7 tjs 01/16/18 Removed the check for DMA MSB to be written. (CR#992560) + * 1.7 tjs 01/17/18 Added a support to toggle WP pin of the flash. + * 1.7 tjs 03/14/18 Added support in EL1 NS mode (CR#974882) + * 1.8 tjs 06/26/18 Added an example for accessing 64bit dma within + * 32 bit application. CR#1004701 + * 1.8 tjs 06/26/18 Removed checkpatch warnings. + * 1.8 tjs 07/09/18 Fixed cppcheck and doxygen warnings. (CR#1006336) + * 1.8 tjs 07/18/18 Setup64BRxDma() should be called only if the RxAddress is + * greater than 32 bit address space. (CR#1006862) + * 1.8 tjs 09/06/18 Fixed the code in XQspiPsu_GenFifoEntryData() for data + * transfer length up to 255 for reducing the extra loop. + * 1.8 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform. + * 1.9 tjs 11/22/17 Added the check for A72 and R5 processors (CR-987075) + * 1.9 tjs 04/17/18 Updated register addresses as per the latest revision + * of versal (CR#999610) + * 1.9 aru 01/17/19 Fixes violations according to MISRAC-2012 + * in safety mode and modified the code such as + * Added UNITPTR inplace of INTPTR,Declared the pointer param + * as Pointer to const . + * 1.9 nsk 02/01/19 Clear DMA_DST_ADDR_MSB register on 32bit machine, if the + * address is of only 32bit (CR#1020031) + * 1.9 nsk 02/01/19 Added QSPI idling support. + * 1.9 rama 03/13/19 Fixed MISRA violations related to UR data anamoly, + * expression is not a boolean + * 1.9 nsk 03/27/19 Update 64bit dma support + * 1.10 sk 08/20/19 Fixed issues in poll timeout feature. + * 1.11 akm 02/19/20 Added XQspiPsu_StartDmaTransfer() and XQspiPsu_CheckDmaDone() + * APIs for non-blocking transfer. + * 1.11 sd 01/02/20 Added clocking support + * 1.11 akm 03/09/20 Reorganize the source code, enable qspi controller and + * interrupts in XQspiPsu_CfgInitialize() API. + * 1.11 akm 03/26/20 Fixed issue by updating XQspiPsu_CfgInitialize to return + * XST_DEVICE_IS_STARTED instead of asserting, when the + * instance is already configured. + * 1.13 akm 01/04/21 Fix MISRA-C violations. + * 1.14 akm 06/24/21 Allow enough time for the controller to reset the FIFOs. + * 1.14 akm 08/12/21 Perform Dcache invalidate at the end of the DMA transfer. + * 1.15 akm 10/21/21 Fix MISRA-C violations. + * + * </pre> + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspipsu.h" +#include "xqspipsu_control.h" +#include "sleep.h" +#ifdef __rtems__ +#include <rtems/rtems/cache.h> +#endif + +/************************** Constant Definitions *****************************/ +#define MAX_DELAY_CNT 10000000U /**< Max delay count */ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** + * + * Initializes a specific XQspiPsu instance as such the driver is ready to use. + * + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param ConfigPtr is a reference to a structure containing information + * about a specific QSPIPSU device. This function initializes an + * InstancePtr object for a specific device specified by the + * contents of Config. + * @param EffectiveAddr is the device base address in the virtual memory + * address space. The caller is responsible for keeping the address + * mapping from EffectiveAddr to the device physical base address + * unchanged once this function is invoked. Unexpected errors may + * occur if the address mapping changes after this function is + * called. If address translation is not used, use + * ConfigPtr->Config.BaseAddress for this device. + * + * @return + * - XST_SUCCESS if successful. + * - XST_DEVICE_IS_STARTED if the device is already started. + * It must be stopped to re-initialize. + * + * @note None. + * + ******************************************************************************/ +s32 XQspiPsu_CfgInitialize(XQspiPsu *InstancePtr, + const XQspiPsu_Config *ConfigPtr, + UINTPTR EffectiveAddr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + s32 Status; + + /* + * If the device is busy, disallow the initialize and return a status + * indicating it is already started. This allows the user to stop the + * device and re-initialize, but prevents a user from inadvertently + * initializing. This assumes the busy flag is cleared at startup. + */ + if ((InstancePtr->IsBusy == (u32)TRUE) || + (InstancePtr->IsReady == XIL_COMPONENT_IS_READY)) { + Status = (s32)XST_DEVICE_IS_STARTED; + } else { + /* Set some default values. */ + InstancePtr->IsBusy = (u32)FALSE; + InstancePtr->Config.BaseAddress = + EffectiveAddr + XQSPIPSU_OFFSET; + InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode; + InstancePtr->StatusHandler = StubStatusHandler; + InstancePtr->Config.BusWidth = ConfigPtr->BusWidth; + InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz; +#if defined (XCLOCKING) + InstancePtr->Config.RefClk = ConfigPtr->RefClk; +#endif + InstancePtr->Config.IsCacheCoherent = + ConfigPtr->IsCacheCoherent; + /* Other instance variable initializations */ + InstancePtr->SendBufferPtr = NULL; + InstancePtr->RecvBufferPtr = NULL; + InstancePtr->GenFifoBufferPtr = NULL; + InstancePtr->TxBytes = 0; + InstancePtr->RxBytes = 0; + InstancePtr->GenFifoEntries = 0; + InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA; + InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER; + InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER; + InstancePtr->IsUnaligned = 0; + InstancePtr->IsManualstart = (u8)TRUE; + + /* Select QSPIPSU */ + XQspiPsu_Select(InstancePtr, XQSPIPSU_SEL_GQSPI_MASK); + /* + * Reset the QSPIPSU device to get it into its initial state. + * It is expected that device configuration will take place + * after this initialization is done, but before the device + * is started. + */ + XQspiPsu_Reset(InstancePtr); + /* Enable */ + XQspiPsu_Enable(InstancePtr); + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + Status = (s32)XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** + * + * Stops the transfer of data to internal DST FIFO from stream interface and + * also stops the issuing of new write commands to memory. + * + * By calling this API, any ongoing Dma transfers will be paused and DMA will + * not issue AXI write commands to memory + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_Idle(const XQspiPsu *InstancePtr) +{ + u32 RegEn; + u32 DmaStatus; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Check for QSPI enable */ + RegEn = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_EN_OFFSET); + if ((RegEn & XQSPIPSU_EN_MASK) != 0U) { + DmaStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET); + DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_MASK; + DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_MASK; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET, DmaStatus); + } +#if defined (XCLOCKING) + Xil_ClockDisable(InstancePtr->Config.RefClk); +#endif +} + +/*****************************************************************************/ +/** + * + * Resets the QSPIPSU device. Reset must only be called after the driver has + * been initialized. Any data transfer that is in progress is aborted. + * + * The upper layer software is responsible for re-configuring (if necessary) + * and restarting the QSPIPSU device after the reset. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_Reset(XQspiPsu *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); +#ifdef DEBUG + xil_printf("\nXQspiPsu_Reset\r\n"); +#endif + + /* Abort any transfer that is in progress */ + XQspiPsu_Abort(InstancePtr); + + /* Default value to config register */ + XQspiPsu_SetDefaultConfig(InstancePtr); + +} + +/*****************************************************************************/ +/** + * + * Aborts a transfer in progress. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_Abort(XQspiPsu *InstancePtr) +{ + u32 IntrStatus, ConfigReg, FifoStatus; + u32 DelayCount = 0U; + +#ifdef __rtems__ + u32 FifoStatusMask = XQSPIPSU_ISR_RXEMPTY_MASK; + FifoStatusMask |= XQSPIPSU_ISR_TXEMPTY_MASK; + FifoStatusMask |= XQSPIPSU_ISR_GENFIFOEMPTY_MASK; +#endif + + Xil_AssertVoid(InstancePtr != NULL); +#ifdef DEBUG + xil_printf("\nXQspiPsu_Abort\r\n"); +#endif + IntrStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_ISR_OFFSET); + + /* Clear and disable interrupts */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_ISR_OFFSET, IntrStatus | XQSPIPSU_ISR_WR_TO_CLR_MASK); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, + XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET)); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_STS_OFFSET, + XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_STS_OFFSET) | + XQSPIPSU_QSPIDMA_DST_STS_WTC); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_IDR_OFFSET, XQSPIPSU_IDR_ALL_MASK); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET, + XQSPIPSU_QSPIDMA_DST_INTR_ALL_MASK); + + /* + * Clear GEN FIFO, TX FIFO & RX FIFO. Switch to IO mode to Clear + * RX FIFO. This is because of DMA behaviour where it waits on + * RX empty and goes busy assuming there is data to be transferred + * even if there is no request. + */ + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET, ConfigReg); + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_FIFO_CTRL_OFFSET, + XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_MASK | + XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_MASK | + XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_MASK); + /* + * QSPI Controller takes few clock cycles to update the RX_FIFO_Empty, + * TX_FIFO_Empty and GEN_FIFO_Empty status bit. Checking the GQSPI FIFO + * Control register bits gives enough time for the QSPI controller to + * update the status bit. The opeartion timesout, if the status bit are + * not updated after 10secs. + */ + + FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, +#ifdef __rtems__ + XQSPIPSU_ISR_OFFSET) & FifoStatusMask; + while(FifoStatus != FifoStatusMask) { +#else + XQSPIPSU_FIFO_CTRL_OFFSET); + while(FifoStatus != 0U) { +#endif + if (DelayCount == MAX_DELAY_CNT) { +#ifdef DEBUG + xil_printf("Timeout error, FIFO reset failed.\r\n"); +#endif + } else { + /* Wait for 1 usec */ + usleep(1); + DelayCount++; + FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, +#ifdef __rtems__ + XQSPIPSU_ISR_OFFSET) & FifoStatusMask; +#else + XQSPIPSU_FIFO_CTRL_OFFSET); +#endif + } + } + + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET, ConfigReg); + } + + + InstancePtr->TxBytes = 0; + InstancePtr->RxBytes = 0; + InstancePtr->GenFifoEntries = 0; + InstancePtr->IsBusy = (u32)FALSE; +} + +/*****************************************************************************/ +/** + * This is the handler for polling functionality of controller. It reads data + * from RXFIFO, since when data from the flash device (status data) matched + * with configured value in poll_cfg, then controller writes the matched data + * into RXFIFO. + * + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param StatusReg is the Interrupt status Register value. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_PollDataHandler(XQspiPsu *InstancePtr, u32 StatusReg) +{ + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_PollDataHandler\r\n"); +#endif + + if ((StatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK) != (u32)FALSE) { + /* + * Read data from RXFIFO, since when data from the + * flash device (status data) matched with configured + * value in poll_cfg, then controller writes the + * matched data into RXFIFO. + */ + (void)XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_RXD_OFFSET); + + InstancePtr->StatusHandler(InstancePtr->StatusRef, + XST_SPI_POLL_DONE, 0); + } + if ((StatusReg & XQSPIPSU_ISR_POLL_TIME_EXPIRE_MASK) != (u32)FALSE) { + InstancePtr->StatusHandler(InstancePtr->StatusRef, + XST_FLASH_TIMEOUT_ERROR, 0); + } + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET, + (u32)XQSPIPSU_IER_RXNEMPTY_MASK | + (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK); + InstancePtr->IsBusy = (u32)FALSE; + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + XQspiPsu_SetReadMode(InstancePtr, XQSPIPSU_READMODE_DMA); + } + /* De-select slave */ + XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr); + XQspiPsu_ManualStartEnable(InstancePtr); +} + +/*****************************************************************************/ +/** + * + * This function performs a transfer on the bus in polled mode. The messages + * passed are all transferred on the bus between one CS assert and de-assert. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param NumMsg is the number of messages to be transferred. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * + ******************************************************************************/ +s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 NumMsg) +{ + s32 Index; + u32 QspiPsuStatusReg; + u32 IOPending = (u32)FALSE; + u32 DmaIntrSts; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Msg != NULL); + Xil_AssertNonvoid(NumMsg > 0U); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + for (Index = 0; Index < (s32)NumMsg; Index++) { + Xil_AssertNonvoid(Msg[Index].ByteCount > 0U); +#ifdef __rtems__ + if (Msg[Index].TxBfrPtr != NULL) { + rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount); + } +#endif + } +#ifdef __rtems__ + rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg)); +#endif + + /* + * Check whether there is another transfer in progress. + * Not thread-safe + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + goto END; + } + /* Check for ByteCount upper limit - 2^28 for DMA */ + for (Index = 0; Index < (s32)NumMsg; Index++) { + if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) && + ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + Status = (s32)XST_FAILURE; + goto END; + } + } + /* + * Set the busy flag, which will be cleared when the transfer is + * entirely done. + */ + InstancePtr->IsBusy = (u32)TRUE; + +#if defined (XCLOCKING) + Xil_ClockEnable(InstancePtr->Config.RefClk); +#endif + /* Select slave */ + XQspiPsu_GenFifoEntryCSAssert(InstancePtr); + + /* list */ + Index = 0; + while (Index < (s32)NumMsg) { + XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]); + XQspiPsu_ManualStartEnable(InstancePtr); + /* Use thresholds here */ + /* If there is more data to be transmitted */ + do { + QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_ISR_OFFSET); + /* Transmit more data if left */ + if (((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) && + ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) && + (InstancePtr->TxBytes > 0)) { + XQspiPsu_FillTxFifo(InstancePtr, &Msg[Index], + (u32)XQSPIPSU_TXD_DEPTH); + } + + if ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE) { + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + /* Check if DMA RX is complete and update RxBytes */ + DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET); + if ((DmaIntrSts & + XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts); + /* DMA transfer done, Invalidate Data Cache */ + if (!((Msg[Index].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) || + (Msg[Index].Xfer64bit != (u8)0U)) && + (InstancePtr->Config.IsCacheCoherent == 0U)) { + Xil_DCacheInvalidateRange((INTPTR)Msg[Index].RxBfrPtr, + (INTPTR)Msg[Index].ByteCount); + } + IOPending = XQspiPsu_SetIOMode(InstancePtr, &Msg[Index]); + InstancePtr->RxBytes = 0; + if (IOPending == (u32)TRUE) { + break; + } + } + } else { + XQspiPsu_IORead(InstancePtr, &Msg[Index], QspiPsuStatusReg); + } + } + } while (((QspiPsuStatusReg & + XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) || + (InstancePtr->TxBytes != 0) || + ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE) || + (InstancePtr->RxBytes != 0)); + + if ((InstancePtr->IsUnaligned != 0) && (IOPending == (u32)FALSE)) { + InstancePtr->IsUnaligned = 0; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) | + XQSPIPSU_CFG_MODE_EN_DMA_MASK)); + InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA; + } + if (IOPending == (u32)TRUE) { + IOPending = (u32)FALSE; + } else { + Index++; + } + } + /* De-select slave */ + XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr); + XQspiPsu_ManualStartEnable(InstancePtr); + do { + QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET); + } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE); + + /* Clear the busy flag. */ + InstancePtr->IsBusy = (u32)FALSE; + + Status = (s32)XST_SUCCESS; + +#if defined (XCLOCKING) + Xil_ClockDisable(InstancePtr->Config.RefClk); +#endif + END: + return Status; +} + +/*****************************************************************************/ +/** + * + * This function initiates a transfer on the bus and enables interrupts. + * The transfer is completed by the interrupt handler. The messages passed are + * all transferred on the bus between one CS assert and de-assert. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param NumMsg is the number of messages to be transferred. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * + ******************************************************************************/ +s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 NumMsg) +{ + s32 Index; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + for (Index = 0; Index < (s32)NumMsg; Index++) +#ifdef __rtems__ + { +#endif + Xil_AssertNonvoid(Msg[Index].ByteCount > 0U); +#ifdef __rtems__ + if (Msg[Index].TxBfrPtr != NULL) { + rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount); + } + } + rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg)); +#endif + + /* + * Check whether there is another transfer in progress. + * Not thread-safe + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + goto END; + } +#if defined (XCLOCKING) + Xil_ClockEnable(InstancePtr->Config.RefClk); +#endif + + if ((Msg[0].Flags & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) { + InstancePtr->IsBusy = (u32)TRUE; + XQspiPsu_PollDataConfig(InstancePtr, Msg); + } else { + /* Check for ByteCount upper limit - 2^28 for DMA */ + for (Index = 0; Index < (s32)NumMsg; Index++) { + if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) && + ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + Status = (s32)XST_FAILURE; + goto END; + } + } + /* + * Set the busy flag, which will be cleared when the transfer is + * entirely done. + */ + InstancePtr->IsBusy = (u32)TRUE; + + InstancePtr->Msg = Msg; + InstancePtr->NumMsg = (s32)NumMsg; + InstancePtr->MsgCnt = 0; + + /* Select slave */ + XQspiPsu_GenFifoEntryCSAssert(InstancePtr); + /* This might not work if not manual start */ + /* Put first message in FIFO along with the above slave select */ + XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[0]); + XQspiPsu_ManualStartEnable(InstancePtr); + + /* Enable interrupts */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET, + (u32)XQSPIPSU_IER_TXNOT_FULL_MASK | + (u32)XQSPIPSU_IER_TXEMPTY_MASK | + (u32)XQSPIPSU_IER_RXNEMPTY_MASK | + (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK | + (u32)XQSPIPSU_IER_RXEMPTY_MASK); + + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_EN_OFFSET, + XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK); + } + } + Status = (s32)XST_SUCCESS; + + END: + return Status; +} + +/*****************************************************************************/ +/** + * + * Handles interrupt based transfers by acting on GENFIFO and DMA interurpts. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * + * @note None. + * + ******************************************************************************/ +s32 XQspiPsu_InterruptHandler(XQspiPsu *InstancePtr) +{ + u32 QspiPsuStatusReg, DmaIntrStatusReg = 0; + XQspiPsu_Msg *Msg; + s32 NumMsg; + s32 MsgCnt; + u8 DeltaMsgCnt = 0; + u32 TxRxFlag; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(InstancePtr->NumMsg > 0); + Xil_AssertNonvoid(InstancePtr->Msg != NULL); + + Msg = InstancePtr->Msg; + NumMsg = InstancePtr->NumMsg; + MsgCnt = InstancePtr->MsgCnt; + TxRxFlag = Msg[MsgCnt].Flags; + + /* QSPIPSU Intr cleared on read */ + QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET); + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + /* DMA Intr write to clear */ + DmaIntrStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, + DmaIntrStatusReg); + } + if (((DmaIntrStatusReg & XQSPIPSU_QSPIDMA_DST_INTR_ERR_MASK) != (u32)FALSE)) { + /* Call status handler to indicate error */ + InstancePtr->StatusHandler(InstancePtr->StatusRef, + XST_SPI_COMMAND_ERROR, 0); + } + /* Fill more data to be txed if required */ + if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) && + ((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) && + (InstancePtr->TxBytes > 0)) { + XQspiPsu_FillTxFifo(InstancePtr, &Msg[MsgCnt], (u32)XQSPIPSU_TXD_DEPTH); + } + /* + * Check if the entry is ONLY TX and increase MsgCnt. + * This is to allow TX and RX together in one entry - corner case. + */ + if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) && + ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) != (u32)FALSE) && + ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) && + (InstancePtr->TxBytes == 0) && + ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) { + MsgCnt += 1; + DeltaMsgCnt = 1U; + } + + if ((MsgCnt < NumMsg) && + ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + if ((DmaIntrStatusReg & + XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) { + /* DMA transfer done, Invalidate Data Cache */ + if (!((Msg[MsgCnt].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) || + (Msg[MsgCnt].Xfer64bit != (u8)0U)) && + (InstancePtr->Config.IsCacheCoherent == 0U)) { + Xil_DCacheInvalidateRange((INTPTR)Msg[MsgCnt].RxBfrPtr, (INTPTR)Msg[MsgCnt].ByteCount); + } + if (XQspiPsu_SetIOMode(InstancePtr, &Msg[MsgCnt]) == (u32)TRUE) { + XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]); + XQspiPsu_ManualStartEnable(InstancePtr); + } else { + InstancePtr->RxBytes = 0; + MsgCnt += 1; + DeltaMsgCnt = 1U; + } + } + } else { + if (InstancePtr->RxBytes != 0) { + XQspiPsu_IORead(InstancePtr, &Msg[MsgCnt], QspiPsuStatusReg); + if (InstancePtr->RxBytes == 0) { + MsgCnt += 1; + DeltaMsgCnt = 1U; + } + } + } + } + + /* + * Dummy byte transfer + * MsgCnt < NumMsg check is to ensure is it a valid dummy cycle message + * If one of the above conditions increased MsgCnt, then + * the new message is yet to be placed in the FIFO; hence !DeltaMsgCnt. + */ + if ((MsgCnt < NumMsg) && (DeltaMsgCnt == (u8)FALSE) && + ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE) && + ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE) && + ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) == (u32)FALSE) && + ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE)) { + MsgCnt += 1; + DeltaMsgCnt = 1U; + } + InstancePtr->MsgCnt = MsgCnt; + /* + * DeltaMsgCnt is to handle conditions where genfifo empty can be set + * while tx is still not empty or rx dma is not yet done. + * MsgCnt > NumMsg indicates CS de-assert entry was also executed. + */ + if (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) && + ((DeltaMsgCnt != (u8)FALSE) || (MsgCnt > NumMsg))) { + if (MsgCnt < NumMsg) { + if (InstancePtr->IsUnaligned != 0) { + InstancePtr->IsUnaligned = 0; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg( + InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) | + XQSPIPSU_CFG_MODE_EN_DMA_MASK)); + InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA; + } + /* This might not work if not manual start */ + XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]); + XQspiPsu_ManualStartEnable(InstancePtr); + } else if (MsgCnt == NumMsg) { + /* This is just to keep track of the de-assert entry */ + MsgCnt += 1; + InstancePtr->MsgCnt = MsgCnt; + /* De-select slave */ + XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr); + XQspiPsu_ManualStartEnable(InstancePtr); + } else { + /* Disable interrupts */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET, + (u32)XQSPIPSU_IER_TXNOT_FULL_MASK | + (u32)XQSPIPSU_IER_TXEMPTY_MASK | + (u32)XQSPIPSU_IER_RXNEMPTY_MASK | + (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK | + (u32)XQSPIPSU_IER_RXEMPTY_MASK); + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET, + XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK); + } + /* Clear the busy flag. */ + InstancePtr->IsBusy = (u32)FALSE; +#if defined (XCLOCKING) + Xil_ClockDisable(InstancePtr->Config.RefClk); +#endif + /* Call status handler to indicate completion */ + InstancePtr->StatusHandler(InstancePtr->StatusRef, + XST_SPI_TRANSFER_DONE, 0); + } + } + if ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) { + XQspiPsu_PollDataHandler(InstancePtr, QspiPsuStatusReg); + } + return (s32)XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Sets the status callback function, the status handler, which the driver + * calls when it encounters conditions that should be reported to upper + * layer software. The handler executes in an interrupt context, so it must + * minimize the amount of processing performed. One of the following status + * events is passed to the status handler. + * + * <pre> + * + * XST_SPI_TRANSFER_DONE The requested data transfer is done + * + * XST_SPI_TRANSMIT_UNDERRUN As a slave device, the master clocked data + * but there were none available in the transmit + * register/FIFO. This typically means the slave + * application did not issue a transfer request + * fast enough, or the processor/driver could not + * fill the transmit register/FIFO fast enough. + * + * XST_SPI_RECEIVE_OVERRUN The QSPIPSU device lost data. Data was received + * but the receive data register/FIFO was full. + * + * </pre> + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param CallBackRef is the upper layer callback reference passed back + * when the callback function is invoked. + * @param FuncPointer is the pointer to the callback function. + * + * @return None. + * + * @note + * + * The handler is called within interrupt context, so it should do its work + * quickly and queue potentially time-consuming work to a task-level thread. + * + ******************************************************************************/ +void XQspiPsu_SetStatusHandler(XQspiPsu *InstancePtr, void *CallBackRef, + XQspiPsu_StatusHandler FuncPointer) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPointer != NULL); + Xil_AssertVoid(CallBackRef != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->StatusHandler = FuncPointer; + InstancePtr->StatusRef = CallBackRef; +} + +/*****************************************************************************/ +/** + * @brief + * This API enables/ disables Write Protect pin on the flash parts. + * + * @param InstancePtr is a pointer to the QSPIPSU driver component to use. + * + * @param Toggle is a value of the GPIO pin + * + * @return None + * + * @note By default WP pin as per the QSPI controller is driven High + * which means no write protection. Calling this function once + * will enable the protection. + * + ******************************************************************************/ +void XQspiPsu_WriteProtectToggle(const XQspiPsu *InstancePtr, u32 Toggle) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + /* For Single and Stacked flash configuration with x1 or x2 mode*/ + if (InstancePtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_SINGLE) { + /* Select slave */ + XQspiPsu_GenFifoEntryCSAssert(InstancePtr); + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_GPIO_OFFSET, Toggle); + + } else { +#ifdef DEBUG + xil_printf("Dual Parallel/Stacked configuration "); + xil_printf("is not supported by this API\r\n"); +#endif + } +} + +/*****************************************************************************/ +/** +* +* This function start a DMA transfer. +* + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param NumMsg is the number of messages to be transferred. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if ByteCount is greater than + * XQSPIPSU_DMA_BYTES_MAX. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * +* +******************************************************************************/ +s32 XQspiPsu_StartDmaTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 NumMsg) +{ + s32 Index; + u32 QspiPsuStatusReg = 0; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Msg != NULL); + Xil_AssertNonvoid(NumMsg > 0U); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + for (Index = 0; Index < (s32)NumMsg; Index++) { + Xil_AssertNonvoid(Msg[Index].ByteCount > 0U); + } + + /* + * Check whether there is another transfer in progress. + * Not thread-safe + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + return (s32)XST_DEVICE_BUSY; + } + + /* Check for ByteCount upper limit - 2^28 for DMA */ + for (Index = 0; Index < (s32)NumMsg; Index++) { + if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) && + ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + return (s32)XST_FAILURE; + } + } + + /* + * Set the busy flag, which will be cleared when the transfer is + * entirely done. + */ + InstancePtr->IsBusy = (u32)TRUE; + + /* Select slave */ + XQspiPsu_GenFifoEntryCSAssert(InstancePtr); + /* list */ + Index = 0; + while (Index < (s32)NumMsg) { + InstancePtr->Msg = &Msg[Index]; + XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]); + if (InstancePtr->IsManualstart == (u32)TRUE) { +#ifdef DEBUG + xil_printf("\nManual Start\r\n"); +#endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET) | + XQSPIPSU_CFG_START_GEN_FIFO_MASK); + } + do { + if((InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) && + ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + break; + } + QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET); + + } while (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) || + (InstancePtr->TxBytes != 0) || + ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE)); + + if(InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg( + InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) | + XQSPIPSU_CFG_MODE_EN_DMA_MASK)); + InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA; + } + Index++; + } + return (s32)XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function check for DMA transfer complete. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* +* @return +* - XST_SUCCESS if DMA transfer complete. +* - XST_FAILURE if DMA transfer is not completed. +* +* @note None. +* +******************************************************************************/ +s32 XQspiPsu_CheckDmaDone(XQspiPsu *InstancePtr) +{ + u32 QspiPsuStatusReg; + u32 DmaIntrSts; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET); + if ((DmaIntrSts & XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts); + /* DMA transfer done, Invalidate Data Cache */ + if (!((InstancePtr->Msg->RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) || + (InstancePtr->Msg->Xfer64bit != (u8)0U)) && + (InstancePtr->Config.IsCacheCoherent == 0U)) { + Xil_DCacheInvalidateRange((INTPTR)InstancePtr->Msg->RxBfrPtr, (INTPTR)InstancePtr->RxBytes); + } + /* De-select slave */ + XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr); + if (InstancePtr->IsManualstart == (u8)TRUE) { +#ifdef DEBUG + xil_printf("\nManual Start\r\n"); +#endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) | + XQSPIPSU_CFG_START_GEN_FIFO_MASK); + } + do { + QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET); + } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE); + + /* Clear the busy flag. */ + InstancePtr->IsBusy = (u32)FALSE; + + return (s32)XST_SUCCESS; + } + else { + return (s32)XST_FAILURE; + } + +} +/** @} */ diff --git a/bsps/shared/dev/spi/xqspipsu_control.c b/bsps/shared/dev/spi/xqspipsu_control.c new file mode 100644 index 0000000000..af2400bf4c --- /dev/null +++ b/bsps/shared/dev/spi/xqspipsu_control.c @@ -0,0 +1,282 @@ +/****************************************************************************** +* Copyright (C) 2020 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*****************************************************************************/ +/** + * + * @file xqspipsu_control.c + * @addtogroup Overview + * @{ + * + * This file contains intermediate control functions used by functions + * in xqspipsu.c and xqspipsu_options.c files. + * + * <pre> + * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- --- -------- ----------------------------------------------- + * 1.11 akm 03/09/20 First release + * 1.13 akm 01/04/21 Fix MISRA-C violations. + * 1.15 akm 10/21/21 Fix MISRA-C violations. + * 1.15 akm 03/03/22 Enable tapdelay settings for applications on + * Microblaze platform. + * </pre> + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspipsu_control.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ + +/*****************************************************************************/ +/** + * + * This function writes the GENFIFO entries to transmit the messages requested. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_GenFifoEntryData(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg) +{ + u32 GenFifoEntry; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_GenFifoEntryData\r\n"); +#endif + + GenFifoEntry = 0x0U; + /* Bus width */ + GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_MODE_MASK; + GenFifoEntry |= XQspiPsu_SelectSpiMode((u8)Msg->BusWidth); + + GenFifoEntry |= InstancePtr->GenFifoCS; + GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_BUS_MASK; + GenFifoEntry |= InstancePtr->GenFifoBus; + + /* Data */ + if (((Msg->Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != (u32)FALSE) { + GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE; + } else { + GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE; + } + /* If Byte Count is less than 8 bytes do the transfer in IO mode */ + if ((Msg->ByteCount < 8U) && + (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA)) { + InstancePtr->ReadMode = XQSPIPSU_READMODE_IO; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) & + ~XQSPIPSU_CFG_MODE_EN_MASK)); + InstancePtr->IsUnaligned = 1; + } + + XQspiPsu_TXRXSetup(InstancePtr, Msg, &GenFifoEntry); + + XQspiPsu_GenFifoEntryDataLen(InstancePtr, Msg, &GenFifoEntry); + + /* One dummy GenFifo entry in case of IO mode */ + if ((InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) && + ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + GenFifoEntry = 0x0U; +#ifdef DEBUG + xil_printf("\nDummy FifoEntry=%08x\r\n", GenFifoEntry); +#endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry); + } +} + +/*****************************************************************************/ +/** + * + * This function enables the polling functionality of controller + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * + * @param FlashMsg is a pointer to the structure containing transfer data + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_PollDataConfig(XQspiPsu *InstancePtr, XQspiPsu_Msg *FlashMsg) +{ + + u32 GenFifoEntry; + u32 Value; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FlashMsg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_PollDataConfig\r\n"); +#endif + + Value = XQspiPsu_CreatePollDataConfig(InstancePtr, FlashMsg); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_POLL_CFG_OFFSET, Value); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_P_TO_OFFSET, FlashMsg->PollTimeout); + + XQspiPsu_GenFifoEntryCSAssert(InstancePtr); + + GenFifoEntry = (u32)0; + GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_TX; + GenFifoEntry |= InstancePtr->GenFifoBus; + GenFifoEntry |= InstancePtr->GenFifoCS; + GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI; + GenFifoEntry |= (u32)FlashMsg->PollStatusCmd; + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry); + + GenFifoEntry = (u32)0; + GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_POLL; + GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_RX; + GenFifoEntry |= InstancePtr->GenFifoBus; + GenFifoEntry |= InstancePtr->GenFifoCS; + GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI; + if (((FlashMsg->Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != (u32)FALSE) { + GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE; + } else { + GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE; + } + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, + GenFifoEntry); + + /* One Dummy entry required for IO mode */ + GenFifoEntry = 0x0U; + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, + GenFifoEntry); + + InstancePtr->Msg = FlashMsg; + InstancePtr->NumMsg = (s32)1; + InstancePtr->MsgCnt = 0; + + Value = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + Value &= ~XQSPIPSU_CFG_MODE_EN_MASK; + Value |= (XQSPIPSU_CFG_START_GEN_FIFO_MASK | + XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK | + XQSPIPSU_CFG_EN_POLL_TO_MASK); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + Value); + + /* Enable interrupts */ + Value = ((u32)XQSPIPSU_IER_RXNEMPTY_MASK | + (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK); + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET, + Value); + +} + +#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__) +/*****************************************************************************/ +/** +* +* Configures the clock according to the prescaler passed. +* +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Prescaler - clock prescaler. +* +* @return +* - XST_SUCCESS if successful. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting Tapdelay. +* +* @note None. +* +******************************************************************************/ +s32 XQspipsu_Calculate_Tapdelay(const XQspiPsu *InstancePtr, u8 Prescaler) +{ + u32 FreqDiv, Divider; + u32 Tapdelay = 0; + u32 LBkModeReg = 0; + u32 delayReg = 0; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM); + + /* + * Do not allow the slave select to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + goto END; + } else { + + Divider = (u32)1U << (Prescaler+1U); + + FreqDiv = (InstancePtr->Config.InputClockHz)/Divider; + +#if defined (versal) + if (FreqDiv <= XQSPIPSU_FREQ_37_5MHZ) { +#else + if (FreqDiv <= XQSPIPSU_FREQ_40MHZ) { +#endif + Tapdelay |= (TAPDLY_BYPASS_VALVE_40MHZ << + IOU_TAPDLY_BYPASS_LQSPI_RX_SHIFT); + } else if (FreqDiv <= XQSPIPSU_FREQ_100MHZ) { + Tapdelay |= (TAPDLY_BYPASS_VALVE_100MHZ << + IOU_TAPDLY_BYPASS_LQSPI_RX_SHIFT); + LBkModeReg |= (USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT); +#if defined (versal) + delayReg |= (u32)USE_DATA_DLY_ADJ << + XQSPIPSU_DATA_DLY_ADJ_USE_DATA_DLY_SHIFT; +#else + delayReg |= ((u32)USE_DATA_DLY_ADJ << + XQSPIPSU_DATA_DLY_ADJ_USE_DATA_DLY_SHIFT) | + ((u32)DATA_DLY_ADJ_DLY << XQSPIPSU_DATA_DLY_ADJ_DLY_SHIFT); +#endif + } else if (FreqDiv <= XQSPIPSU_FREQ_150MHZ) { +#if defined (versal) + LBkModeReg |= (USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT) | + (LPBK_DLY_ADJ_DLY1 << XQSPIPSU_LPBK_DLY_ADJ_DLY1_SHIFT); +#else + LBkModeReg |= USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT; +#endif + } else { + Status = (s32)XST_FAILURE; + goto END; + } + + Status = XQspipsu_Set_TapDelay(InstancePtr, Tapdelay, LBkModeReg, delayReg); + } + + END: + return Status; +} +#endif +/** @} */ diff --git a/bsps/shared/dev/spi/xqspipsu_hw.c b/bsps/shared/dev/spi/xqspipsu_hw.c new file mode 100644 index 0000000000..6f7708893f --- /dev/null +++ b/bsps/shared/dev/spi/xqspipsu_hw.c @@ -0,0 +1,768 @@ +/****************************************************************************** +* Copyright (C) 2020 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*****************************************************************************/ +/** + * + * @file xqspipsu_hw.c + * @addtogroup Overview + * @{ + * + * This file contains functions to reads RXFifo, writes TXFifo and setup + * RX DMA operation, used by xqspipsu_control.c and xqspipsu_lowlevel.c files. + * + * <pre> + * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- --- -------- ----------------------------------------------- + * 1.11 akm 03/09/20 First release + * mn 03/30/20 Add xil_smc.h include for Xil_Smc calls + * 1.13 akm 01/04/21 Fix MISRA-C violations. + * 1.15 akm 10/21/21 Fix MISRA-C violations. + * 1.15 akm 11/16/21 Typecast function parameter with appropriate + * data type. + * 1.15 akm 11/30/21 Fix compilation warnings reported with -Wundef flag + * 1.15 akm 03/03/22 Enable tapdelay settings for applications on + * Microblaze platform. + * + * </pre> + ******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspipsu.h" +#include "xqspipsu_control.h" +#if defined (__aarch64__) +#include "xil_smc.h" +#endif +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ + +/*****************************************************************************/ +/** + * + * Fills the TX FIFO as long as there is room in the FIFO or the bytes required + * to be transmitted. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param Size is the number of bytes to be transmitted. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_FillTxFifo(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, u32 Size) +{ + u32 Count = 0; + u32 Data = 0U; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(Size != 0U); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_FillTxFifo\r\n"); +#endif + while ((InstancePtr->TxBytes > 0) && (Count < Size)) { + if (InstancePtr->TxBytes >= 4) { + (void)Xil_MemCpy((u8 *)&Data, Msg->TxBfrPtr, 4); + Msg->TxBfrPtr += 4; + InstancePtr->TxBytes -= 4; + Count += 4U; + } else { + (void)Xil_MemCpy((u8 *)&Data, Msg->TxBfrPtr, + (u32)InstancePtr->TxBytes); + Msg->TxBfrPtr += InstancePtr->TxBytes; + Count += (u32)InstancePtr->TxBytes; + InstancePtr->TxBytes = 0; + } + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_TXD_OFFSET, Data); +#ifdef DEBUG + xil_printf("\nData is %08x\r\n", Data); +#endif + + } + if (InstancePtr->TxBytes < 0) { + InstancePtr->TxBytes = 0; + } +} + +/*****************************************************************************/ +/** + * + * This function checks the TX buffer in the message and setup the + * TX FIFO as required. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_TXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_TXSetup\r\n"); +#endif + InstancePtr->TxBytes = (s32)Msg->ByteCount; + InstancePtr->SendBufferPtr = Msg->TxBfrPtr; + + XQspiPsu_FillTxFifo(InstancePtr, Msg, (u32)XQSPIPSU_TXD_DEPTH); +} + +/*****************************************************************************/ +/** + * + * This function sets up the RX DMA operation. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_SetupRxDma(const XQspiPsu *InstancePtr, + XQspiPsu_Msg *Msg) +{ + s32 Remainder; + s32 DmaRxBytes; + UINTPTR AddrTemp; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_SetupRxDma\r\n"); +#endif + + AddrTemp = ((UINTPTR)(Msg->RxBfrPtr) & XQSPIPSU_QSPIDMA_DST_ADDR_MASK); + /* Check for RXBfrPtr to be word aligned */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET, (u32)AddrTemp); + +#if defined(__aarch64__) || defined(__arch64__) + AddrTemp = ((UINTPTR)(Msg->RxBfrPtr) >> 32U); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, (u32)AddrTemp & + XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK); +#else + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, 0U); +#endif + + Remainder = InstancePtr->RxBytes % 4; + DmaRxBytes = InstancePtr->RxBytes; + if (Remainder != 0) { + /* This is done to make Dma bytes aligned */ + DmaRxBytes = InstancePtr->RxBytes - Remainder; + Msg->ByteCount = (u32)DmaRxBytes; + } + if (InstancePtr->Config.IsCacheCoherent == 0U) { + Xil_DCacheInvalidateRange((INTPTR)Msg->RxBfrPtr, (INTPTR)Msg->ByteCount); + } + /* Write no. of words to DMA DST SIZE */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET, (u32)DmaRxBytes); +} + +/*****************************************************************************/ +/** + * + * This function sets up the RX DMA operation on a 32bit Machine + * For 64bit Dma transfers. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_Setup64BRxDma(const XQspiPsu *InstancePtr, + XQspiPsu_Msg *Msg) +{ + s32 Remainder; + s32 DmaRxBytes; + u64 AddrTemp; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_Setup64BRxDma\r\n"); +#endif + AddrTemp = Msg->RxAddr64bit & XQSPIPSU_QSPIDMA_DST_ADDR_MASK; + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET, (u32)AddrTemp); + + AddrTemp = (Msg->RxAddr64bit >> 32); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, (u32)AddrTemp & + XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK); + + Remainder = InstancePtr->RxBytes % 4; + DmaRxBytes = InstancePtr->RxBytes; + if (Remainder != 0) { + /* This is done to make Dma bytes aligned */ + DmaRxBytes = InstancePtr->RxBytes - Remainder; + Msg->ByteCount = (u32)DmaRxBytes; + } + + /* Write no. of words to DMA DST SIZE */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET, (u32)DmaRxBytes); + +} + +/*****************************************************************************/ +/** + * + * This function reads remaining bytes, after the completion of a DMA transfer, + * using IO mode + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * + ******************************************************************************/ +u32 XQspiPsu_SetIOMode(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(Msg != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_DMARXComplete\r\n"); +#endif + + /* Read remaining bytes using IO mode */ + if ((InstancePtr->RxBytes % 4) != 0) { + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) & + ~XQSPIPSU_CFG_MODE_EN_MASK)); + InstancePtr->ReadMode = XQSPIPSU_READMODE_IO; + Msg->ByteCount = (u32)InstancePtr->RxBytes % 4U; + Msg->RxBfrPtr += (InstancePtr->RxBytes - (InstancePtr->RxBytes % 4)); + InstancePtr->IsUnaligned = 1; + return (u32) TRUE; + } + return (u32) FALSE; +} + +/*****************************************************************************/ +/** + * + * This function checks the RX buffers in the message and setup the + * RX DMA as required. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_RXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_RXSetup\r\n"); +#endif + InstancePtr->RxBytes = (s32)Msg->ByteCount; + + if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) { + if ((Msg->RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) || + (Msg->Xfer64bit != (u8)0U)) { + XQspiPsu_Setup64BRxDma(InstancePtr, Msg); + } else { + XQspiPsu_SetupRxDma(InstancePtr, Msg); + } + } +} + +/*****************************************************************************/ +/** + * + * This function checks the TX/RX buffers in the message and setups up the + * GENFIFO entries, TX FIFO or RX DMA as required. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param GenFifoEntry is pointer to the variable in which GENFIFO mask + * is returned to calling function + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_TXRXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 *GenFifoEntry) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(GenFifoEntry != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_TXRXSetup\r\n"); +#endif + /* Transmit */ + if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) && + ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) { + + *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER; + *GenFifoEntry |= XQSPIPSU_GENFIFO_TX; + /* Discard RX data */ + *GenFifoEntry &= ~XQSPIPSU_GENFIFO_RX; + + /* Setup data to be TXed */ + XQspiPsu_TXSetup(InstancePtr, Msg); + + InstancePtr->RecvBufferPtr = NULL; + InstancePtr->RxBytes = 0; + } + /*Receive*/ + if (((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE) && + ((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE)) { + + /* TX auto fill */ + *GenFifoEntry &= ~XQSPIPSU_GENFIFO_TX; + /* Setup RX */ + *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER; + *GenFifoEntry |= XQSPIPSU_GENFIFO_RX; + + /* Setup DMA for data to be RXed */ + XQspiPsu_RXSetup(InstancePtr, Msg); + + InstancePtr->SendBufferPtr = NULL; + InstancePtr->TxBytes = 0; + } + /* If only dummy is requested as a separate entry */ + if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE) && + ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) { + + *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER; + *GenFifoEntry &= ~(XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX); + InstancePtr->TxBytes = 0; + InstancePtr->RxBytes = 0; + InstancePtr->SendBufferPtr = NULL; + InstancePtr->RecvBufferPtr = NULL; + } + /* Dummy and cmd sent by upper layer to received data */ + if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) && + ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) { + *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER; + *GenFifoEntry |= (XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX); + + /* Setup data to be TXed */ + XQspiPsu_TXSetup(InstancePtr, Msg); + /* Setup DMA for data to be RXed */ + XQspiPsu_RXSetup(InstancePtr, Msg); + } +} +/*****************************************************************************/ +/** + * + * This function writes the Data length to GENFIFO entries that need to be + * transmitted or received. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param GenFifoEntry is index of the current message to be handled. + * + * @return + * - XST_SUCCESS if successful. + * - XST_FAILURE if transfer fails. + * - XST_DEVICE_BUSY if a transfer is already in progress. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_GenFifoEntryDataLen(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 *GenFifoEntry) +{ + u32 TempCount; + u32 ImmData; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(GenFifoEntry != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_GenFifoEntryDataLen\r\n"); +#endif + + if (Msg->ByteCount <= XQSPIPSU_GENFIFO_IMM_DATA_MASK) { + *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK; + *GenFifoEntry |= Msg->ByteCount; + #ifdef DEBUG + xil_printf("\nFifoEntry=%08x\r\n", *GenFifoEntry); + #endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, + *GenFifoEntry); + } else { + TempCount = Msg->ByteCount; + u32 Exponent = 8; /* 2^8 = 256 */ + ImmData = TempCount & 0xFFU; + /* Exponent entries */ + *GenFifoEntry |= XQSPIPSU_GENFIFO_EXP; + while (TempCount != 0U) { + if ((TempCount & XQSPIPSU_GENFIFO_EXP_START) != (u32)FALSE) { + *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK; + *GenFifoEntry |= Exponent; + #ifdef DEBUG + xil_printf("\nFifoEntry=%08x\r\n", + *GenFifoEntry); + #endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, + *GenFifoEntry); + } + TempCount = TempCount >> 1; + Exponent++; + } + /* Immediate entry */ + *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_EXP; + if ((ImmData & 0xFFU) != (u32)FALSE) { + *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK; + *GenFifoEntry |= ImmData & 0xFFU; + #ifdef DEBUG + xil_printf("\nFifoEntry=%08x\r\n", *GenFifoEntry); + #endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, + *GenFifoEntry); + } + } +} + +/*****************************************************************************/ +/** + * + * This function creates Poll config register data to write + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @param FlashMsg is a pointer to the structure containing transfer data. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +u32 XQspiPsu_CreatePollDataConfig(const XQspiPsu *InstancePtr, + const XQspiPsu_Msg *FlashMsg) +{ + u32 ConfigData = 0; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(FlashMsg != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_CreatePollDataConfig\r\n"); +#endif + + if ((InstancePtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_UPPER) != (u32)FALSE) { + ConfigData = (u32)XQSPIPSU_SELECT_FLASH_BUS_LOWER << + XQSPIPSU_POLL_CFG_EN_MASK_UPPER_SHIFT; + } + if ((InstancePtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_LOWER) != (u32)FALSE) { + ConfigData |= (u32)XQSPIPSU_SELECT_FLASH_BUS_LOWER << + XQSPIPSU_POLL_CFG_EN_MASK_LOWER_SHIFT; + } + ConfigData |= (u32)(((u32)FlashMsg->PollBusMask << + XQSPIPSU_POLL_CFG_MASK_EN_SHIFT) & XQSPIPSU_POLL_CFG_MASK_EN_MASK); + ConfigData |= (u32)(((u32)FlashMsg->PollData << + XQSPIPSU_POLL_CFG_DATA_VALUE_SHIFT) + & XQSPIPSU_POLL_CFG_DATA_VALUE_MASK); + return ConfigData; +} + +/*****************************************************************************/ +/** + * + * Selects SPI mode - x1 or x2 or x4. + * + * @param SpiMode - spi or dual or quad. + * @return Mask to set desired SPI mode in GENFIFO entry. + * + * @note None. + * + ******************************************************************************/ +u32 XQspiPsu_SelectSpiMode(u8 SpiMode) +{ + u32 Mask; + + Xil_AssertNonvoid(SpiMode > 0U); +#ifdef DEBUG + xil_printf("\nXQspiPsu_SelectSpiMode\r\n"); +#endif + + switch (SpiMode) { + case XQSPIPSU_SELECT_MODE_DUALSPI: + Mask = XQSPIPSU_GENFIFO_MODE_DUALSPI; + break; + case XQSPIPSU_SELECT_MODE_QUADSPI: + Mask = XQSPIPSU_GENFIFO_MODE_QUADSPI; + break; + case XQSPIPSU_SELECT_MODE_SPI: + Mask = XQSPIPSU_GENFIFO_MODE_SPI; + break; + default: + Mask = XQSPIPSU_GENFIFO_MODE_SPI; + break; + } +#ifdef DEBUG + xil_printf("\nSPIMode is %08x\r\n", SpiMode); +#endif + return Mask; +} + +/*****************************************************************************/ +/** + * + * Enable and initialize DMA Mode, set little endain, disable poll timeout, + * clear prescalar bits and reset thresholds + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_SetDefaultConfig(XQspiPsu *InstancePtr) +{ + u32 ConfigReg; + + Xil_AssertVoid(InstancePtr != NULL); +#ifdef DEBUG + xil_printf("\nXQspiPsu_SetDefaultConfig\r\n"); +#endif + + /* Default value to config register */ + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + + /* DMA mode */ + ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK; + ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK; + /* Manual start */ + ConfigReg |= XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK; + /* Little endain by default */ + ConfigReg &= ~XQSPIPSU_CFG_ENDIAN_MASK; + /* Disable poll timeout */ + ConfigReg &= ~XQSPIPSU_CFG_EN_POLL_TO_MASK; + /* Set hold bit */ + ConfigReg |= XQSPIPSU_CFG_WP_HOLD_MASK; + /* Clear prescalar by default */ + ConfigReg &= ~(u32)XQSPIPSU_CFG_BAUD_RATE_DIV_MASK; + /* CPOL CPHA 00 */ + ConfigReg &= ~(u32)XQSPIPSU_CFG_CLK_PHA_MASK; + ConfigReg &= ~(u32)XQSPIPSU_CFG_CLK_POL_MASK; + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET, ConfigReg); + + /* Set by default to allow for high frequencies */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_LPBK_DLY_ADJ_OFFSET, + XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_LPBK_DLY_ADJ_OFFSET) | + XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_MASK); + + /* Reset thresholds */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_TX_THRESHOLD_OFFSET, XQSPIPSU_TX_FIFO_THRESHOLD_RESET_VAL); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_RX_THRESHOLD_OFFSET, XQSPIPSU_RX_FIFO_THRESHOLD_RESET_VAL); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_GF_THRESHOLD_OFFSET, XQSPIPSU_GEN_FIFO_THRESHOLD_RESET_VAL); + + /* DMA init */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET, + XQSPIPSU_QSPIDMA_DST_CTRL_RESET_VAL); +} + +/*****************************************************************************/ +/** + * + * Read the specified number of bytes from RX FIFO + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param Size is the number of bytes to be read. + * + * @return None + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_ReadRxFifo(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, s32 Size) +{ + s32 Count = 0; + u32 Data; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(Size > 0); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_ReadRxFifo\r\n"); +#endif + while ((InstancePtr->RxBytes != 0) && (Count < Size)) { + Data = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_RXD_OFFSET); +#ifdef DEBUG + xil_printf("\nData is %08x\r\n", Data); +#endif + if (InstancePtr->RxBytes >= 4) { + (void)Xil_MemCpy(Msg->RxBfrPtr, (u8 *)&Data, 4); + InstancePtr->RxBytes -= 4; + Msg->RxBfrPtr += 4; + Count += 4; + } else { + /* Read unaligned bytes (< 4 bytes) */ + (void)Xil_MemCpy(Msg->RxBfrPtr, (u8 *)&Data, + (u32)InstancePtr->RxBytes); + Msg->RxBfrPtr += InstancePtr->RxBytes; + Count += InstancePtr->RxBytes; + InstancePtr->RxBytes = 0; + } + } +} + +/*****************************************************************************/ +/** + * + * This function reads data from RXFifo in IO mode. + * + * @param InstancePtr is a pointer to the XQspiPsu instance. + * @param Msg is a pointer to the structure containing transfer data. + * @param StatusReg is the Interrupt status Register value. + * + * @return None. + * + * @note None. + * + ******************************************************************************/ +void XQspiPsu_IORead(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, + u32 StatusReg) +{ + s32 RxThr; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(Msg != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); +#ifdef DEBUG + xil_printf("\nXQspiPsu_IORXComplete\r\n"); +#endif + + if ((StatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK) != 0U) { + /* + * Check if PIO RX is complete and + * update RxBytes + */ + RxThr = (s32)XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_RX_THRESHOLD_OFFSET); + RxThr = RxThr*4; + XQspiPsu_ReadRxFifo(InstancePtr, Msg, RxThr); + + return; + } + + if ((StatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != 0U) { + XQspiPsu_ReadRxFifo(InstancePtr, Msg, InstancePtr->RxBytes); + } +} + +#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__) +/*****************************************************************************/ +/** +* +* This function sets the Tapdelay values for the QSPIPSU device driver.The device +* must be idle rather than busy transferring data before setting Tapdelay. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param TapdelayBypss contains the IOU_TAPDLY_BYPASS register value. +* @param LPBKDelay contains the GQSPI_LPBK_DLY_ADJ register value. +* @param Datadelay contains the QSPI_DATA_DLY_ADJ register value. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting TapDelay. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspipsu_Set_TapDelay(const XQspiPsu *InstancePtr, u32 TapdelayBypass, + u32 LPBKDelay, u32 Datadelay) +{ + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow to modify the Control Register while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { +#if defined (__aarch64__) && (EL1_NONSECURE == 1) && !defined (versal) + Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR + + IOU_TAPDLY_BYPASS_OFFSET) | ((u64)(0x4) << 32), + (u64)TapdelayBypass, 0, 0, 0, 0, 0); +#elif defined (versal) + XQspiPsu_WriteReg(XQSPIPS_BASEADDR, IOU_TAPDLY_BYPASS_OFFSET, + TapdelayBypass); +#else + XQspiPsu_WriteReg(XPS_SYS_CTRL_BASEADDR, IOU_TAPDLY_BYPASS_OFFSET, + TapdelayBypass); +#endif + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_LPBK_DLY_ADJ_OFFSET, LPBKDelay); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_DATA_DLY_ADJ_OFFSET, Datadelay); + + Status = (s32)XST_SUCCESS; + } + return Status; +} +#endif +/** @} */ diff --git a/bsps/shared/dev/spi/xqspipsu_options.c b/bsps/shared/dev/spi/xqspipsu_options.c new file mode 100644 index 0000000000..c889d64abb --- /dev/null +++ b/bsps/shared/dev/spi/xqspipsu_options.c @@ -0,0 +1,532 @@ +/****************************************************************************** +* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xqspipsu_options.c +* @addtogroup Overview +* @{ +* +* This file implements functions to configure the QSPIPSU component, +* specifically some optional settings, clock and flash related information. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- --- -------- ----------------------------------------------- +* 1.0 hk 08/21/14 First release +* sk 03/13/15 Added IO mode support. +* sk 04/24/15 Modified the code according to MISRAC-2012. +* 1.1 sk 04/12/16 Added debug message prints. +* 1.2 nsk 07/01/16 Modified XQspiPsu_SetOptions() to support +* LQSPI options and updated OptionsTable +* rk 07/15/16 Added support for TapDelays at different frequencies. +* 1.7 tjs 01/17/18 Added support to toggle the WP pin of flash. (PR#2448) +* 1.7 tjs 03/14/18 Added support in EL1 NS mode. (CR#974882) +* 1.8 tjs 05/02/18 Added support for IS25LP064 and IS25WP064. +* 1.8 tjs 07/26/18 Resolved cppcheck errors. (CR#1006336) +* 1.9 tjs 04/17/18 Updated register addresses as per the latest revision +* of versal (CR#999610) +* 1.9 aru 01/17/19 Fixes violations according to MISRAC-2012 +* in safety mode and modified the code such as +* Added Xil_MemCpy inplace of memcpy,Declared the pointer param +* as Pointer to const, declared XQspi_Set_TapDelay() as static. +* 1.9 akm 03/08/19 Set recommended clock and data tap delay values for 40MHZ, +* 100MHZ and 150MHZ frequencies(CR#1023187) +* 1.10 akm 08/22/19 Set recommended tap delay values for 37.5MHZ, 100MHZ and +* 150MHZ frequencies in Versal. +* 1.11 akm 11/07/19 Removed LQSPI register access in Versal. +* 1.11 akm 11/15/19 Fixed Coverity deadcode warning in +* XQspipsu_Calculate_Tapdelay(). +* 1.11 akm 03/09/20 Reorganize the source code, enable qspi controller and +* interrupts in XQspiPsu_CfgInitialize() API. +* 1.13 akm 01/04/21 Fix MISRA-C violations. +* 1.15 akm 03/03/22 Enable tapdelay settings for applications on Microblaze +* platform. +* +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xqspipsu_control.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/** + * Create the table of options which are processed to get/set the device + * options. These options are table driven to allow easy maintenance and + * expansion of the options. + */ +typedef struct { + u32 Option; /**< Get/Set the device option */ + u32 Mask; /**< Mask */ +} OptionsMap; + +static OptionsMap OptionsTable[] = { + {XQSPIPSU_CLK_ACTIVE_LOW_OPTION, XQSPIPSU_CFG_CLK_POL_MASK}, + {XQSPIPSU_CLK_PHASE_1_OPTION, XQSPIPSU_CFG_CLK_PHA_MASK}, + {XQSPIPSU_MANUAL_START_OPTION, XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK}, +#if !defined (versal) + {XQSPIPSU_LQSPI_MODE_OPTION, XQSPIPSU_CFG_WP_HOLD_MASK}, +#endif +}; + +/** + * Number of options in option table + */ +#define XQSPIPSU_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap)) + +/*****************************************************************************/ +/** +* +* This function sets the options for the QSPIPSU device driver.The options +* control how the device behaves relative to the QSPIPSU bus. The device must be +* idle rather than busy transferring data before setting these device options. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Options contains the specified options to be set. This is a bit +* mask where a 1 indicates the option should be turned ON and +* a 0 indicates no action. One or more bit values may be +* contained in the mask. See the bit definitions named +* XQSPIPSU_*_OPTIONS in the file xqspipsu.h. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting options. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspiPsu_SetOptions(XQspiPsu *InstancePtr, u32 Options) +{ + u32 ConfigReg; + u32 Index; +#if !defined (versal) + u32 QspiPsuOptions; +#endif + s32 Status; + u32 OptionsVal; + OptionsVal = Options; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow to modify the Control Register while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); +#if !defined (versal) + QspiPsuOptions = OptionsVal & XQSPIPSU_LQSPI_MODE_OPTION; + OptionsVal &= (~XQSPIPSU_LQSPI_MODE_OPTION); +#endif + /* + * Loop through the options table, turning the option on + * depending on whether the bit is set in the incoming options flag. + */ + for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) { + if ((OptionsVal & OptionsTable[Index].Option) == + OptionsTable[Index].Option) { + /* Turn it on */ + ConfigReg |= OptionsTable[Index].Mask; + } else { + /* Turn it off */ + ConfigReg &= ~(OptionsTable[Index].Mask); + } + } + /* + * Now write the control register. Leave it to the upper layers + * to restart the device. + */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + ConfigReg); + + if ((OptionsVal & XQSPIPSU_MANUAL_START_OPTION) != (u32)FALSE) { + InstancePtr->IsManualstart = (u8)TRUE; + } +#if !defined (versal) + if ((QspiPsuOptions & XQSPIPSU_LQSPI_MODE_OPTION) != (u32)FALSE) { + if ((Options & XQSPIPSU_LQSPI_LESS_THEN_SIXTEENMB) != (u32)FALSE) { + XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET,XQSPIPS_LQSPI_CR_RST_STATE); + } else { + XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET,XQSPIPS_LQSPI_CR_4_BYTE_STATE); + } + XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_CFG_OFFSET,XQSPIPS_LQSPI_CFG_RST_STATE); + /* Enable the QSPI controller */ + XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_EN_OFFSET,XQSPIPSU_EN_MASK); + } else { + /* + * Check for the LQSPI configuration options. + */ + ConfigReg = XQspiPsu_ReadReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET); + ConfigReg &= ~(XQSPIPSU_LQSPI_CR_LINEAR_MASK); + XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET, ConfigReg); + } +#endif + Status = (s32)XST_SUCCESS; + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function resets the options for the QSPIPSU device driver.The options +* control how the device behaves relative to the QSPIPSU bus. The device must be +* idle rather than busy transferring data before setting these device options. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Options contains the specified options to be set. This is a bit +* mask where a 1 indicates the option should be turned OFF and +* a 0 indicates no action. One or more bit values may be +* contained in the mask. See the bit definitions named +* XQSPIPSU_*_OPTIONS in the file xqspipsu.h. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting options. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspiPsu_ClearOptions(XQspiPsu *InstancePtr, u32 Options) +{ + u32 ConfigReg; + u32 Index; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Do not allow to modify the Control Register while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + + /* + * Loop through the options table, turning the option on + * depending on whether the bit is set in the incoming options flag. + */ + for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) { + if ((Options & OptionsTable[Index].Option) != (u32)FALSE) { + /* Turn it off */ + ConfigReg &= ~OptionsTable[Index].Mask; + } + } + /* + * Now write the control register. Leave it to the upper layers + * to restart the device. + */ + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + ConfigReg); + + if ((Options & XQSPIPSU_MANUAL_START_OPTION) != (u32)FALSE) { + InstancePtr->IsManualstart = (u8)FALSE; + } + + Status = (s32)XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** +* +* This function gets the options for the QSPIPSU device. The options control how +* the device behaves relative to the QSPIPSU bus. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* +* @return +* +* Options contains the specified options currently set. This is a bit value +* where a 1 means the option is on, and a 0 means the option is off. +* See the bit definitions named XQSPIPSU_*_OPTIONS in file xqspipsu.h. +* +* @note None. +* +******************************************************************************/ +u32 XQspiPsu_GetOptions(const XQspiPsu *InstancePtr) +{ + u32 OptionsFlag = 0; + u32 ConfigReg; + u32 Index; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Loop through the options table to grab options */ + for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) { + /* + * Get the current options from QSPIPSU configuration register. + */ + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + if ((ConfigReg & OptionsTable[Index].Mask) != (u32)FALSE) { + OptionsFlag |= OptionsTable[Index].Option; + } + } + return OptionsFlag; +} + +/*****************************************************************************/ +/** +* +* Configures the clock according to the prescaler passed. +* +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Prescaler - clock prescaler to be set. +* +* @return +* - XST_SUCCESS if successful. +* - XST_DEVICE_IS_STARTED if the device is already started. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* It must be stopped to re-initialize. +* +* @note None. +* +******************************************************************************/ +s32 XQspiPsu_SetClkPrescaler(const XQspiPsu *InstancePtr, u8 Prescaler) +{ + u32 ConfigReg; + s32 Status; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM); + + /* + * Do not allow the slave select to change while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + /* + * Read the configuration register, mask out the relevant bits, and set + * them with the shifted value passed into the function. Write the + * results back to the configuration register. + */ + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + + ConfigReg &= ~(u32)XQSPIPSU_CFG_BAUD_RATE_DIV_MASK; + ConfigReg |= (u32) ((u32)Prescaler & (u32)XQSPIPSU_CR_PRESC_MAXIMUM) << + XQSPIPSU_CFG_BAUD_RATE_DIV_SHIFT; + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + ConfigReg); + +#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__) + Status = XQspipsu_Calculate_Tapdelay(InstancePtr,Prescaler); +#else + Status = (s32)XST_SUCCESS; +#endif + } + return Status; +} + +/*****************************************************************************/ +/** +* +* This function should be used to tell the QSPIPSU driver the HW flash +* configuration being used. This API should be called at least once in the +* application. If desired, it can be called multiple times when switching +* between communicating to different flahs devices/using different configs. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param FlashCS - Flash Chip Select. +* @param FlashBus - Flash Bus (Upper, Lower or Both). +* +* @return +* - XST_SUCCESS if successful. +* - XST_DEVICE_IS_STARTED if the device is already started. +* It must be stopped to re-initialize. +* +* @note If this function is not called at least once in the application, +* the driver assumes there is a single flash connected to the +* lower bus and CS line. +* +******************************************************************************/ +void XQspiPsu_SelectFlash(XQspiPsu *InstancePtr, u8 FlashCS, u8 FlashBus) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FlashCS > 0U); + Xil_AssertVoid(FlashBus > 0U); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + +#ifdef DEBUG + xil_printf("\nXQspiPsu_SelectFlash\r\n"); +#endif + + /* + * Bus and CS lines selected here will be updated in the instance and + * used for subsequent GENFIFO entries during transfer. + */ + + /* Choose slave select line */ + switch (FlashCS) { + case XQSPIPSU_SELECT_FLASH_CS_BOTH: + InstancePtr->GenFifoCS = (u32)XQSPIPSU_GENFIFO_CS_LOWER | + (u32)XQSPIPSU_GENFIFO_CS_UPPER; + break; + case XQSPIPSU_SELECT_FLASH_CS_UPPER: + InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_UPPER; + break; + case XQSPIPSU_SELECT_FLASH_CS_LOWER: + InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER; + break; + default: + InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER; + break; + } + + /* Choose bus */ + switch (FlashBus) { + case XQSPIPSU_SELECT_FLASH_BUS_BOTH: + InstancePtr->GenFifoBus = (u32)XQSPIPSU_GENFIFO_BUS_LOWER | + (u32)XQSPIPSU_GENFIFO_BUS_UPPER; + break; + case XQSPIPSU_SELECT_FLASH_BUS_UPPER: + InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_UPPER; + break; + case XQSPIPSU_SELECT_FLASH_BUS_LOWER: + InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER; + break; + default: + InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER; + break; + } +#ifdef DEBUG + xil_printf("\nGenFifoCS is %08x and GenFifoBus is %08x\r\n", + InstancePtr->GenFifoCS, InstancePtr->GenFifoBus); +#endif + +} + +/*****************************************************************************/ +/** +* +* This function sets the Read mode for the QSPIPSU device driver.The device +* must be idle rather than busy transferring data before setting Read mode +* options. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Mode contains the specified Mode to be set. See the +* bit definitions named XQSPIPSU_READMODE_* in the file xqspipsu.h. +* +* @return +* - XST_SUCCESS if options are successfully set. +* - XST_DEVICE_BUSY if the device is currently transferring data. +* The transfer must complete or be aborted before setting Mode. +* +* @note +* This function is not thread-safe. +* +******************************************************************************/ +s32 XQspiPsu_SetReadMode(XQspiPsu *InstancePtr, u32 Mode) +{ + u32 ConfigReg; + s32 Status; + +#ifdef DEBUG + xil_printf("\nXQspiPsu_SetReadMode\r\n"); +#endif + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((Mode == XQSPIPSU_READMODE_DMA) || (Mode == XQSPIPSU_READMODE_IO)); + + /* + * Do not allow to modify the Control Register while a transfer is in + * progress. Not thread-safe. + */ + if (InstancePtr->IsBusy == (u32)TRUE) { + Status = (s32)XST_DEVICE_BUSY; + } else { + + InstancePtr->ReadMode = Mode; + + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + + if (Mode == XQSPIPSU_READMODE_DMA) { + ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK; + ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK; + } else { + ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK; + } + + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + ConfigReg); + + Status = (s32)XST_SUCCESS; + } +#ifdef DEBUG + xil_printf("\nRead Mode is %08x\r\n", InstancePtr->ReadMode); +#endif + return Status; +} + +/*****************************************************************************/ +/** +* +* This function sets the Write Protect and Hold options for the QSPIPSU device +* driver.The device must be idle rather than busy transferring data before +* setting Write Protect and Hold options. +* +* @param InstancePtr is a pointer to the XQspiPsu instance. +* @param Value of the WP_HOLD bit in configuration register +* +* @return None +* +* @note +* This function is not thread-safe. This function can only be used with single +* flash configuration and x1/x2 data mode. This function cannot be used with +* x4 data mode and dual parallel and stacked flash configuration. +* +******************************************************************************/ +void XQspiPsu_SetWP(const XQspiPsu *InstancePtr, u8 Value) +{ + u32 ConfigReg; + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(InstancePtr->IsBusy != TRUE); + + ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, + XQSPIPSU_CFG_OFFSET); + ConfigReg |= (u32)((u32)Value << XQSPIPSU_CFG_WP_HOLD_SHIFT); + XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET, + ConfigReg); +} +/** @} */ diff --git a/bsps/shared/doxygen.h b/bsps/shared/doxygen.h index d3679c2f3d..be681673d0 100644 --- a/bsps/shared/doxygen.h +++ b/bsps/shared/doxygen.h @@ -1,4 +1,12 @@ /** + * @file + * + * @ingroup RTEMSImplDoxygen + * + * @brief This header file defines BSP-specific groups. + */ + +/** * @defgroup RTEMSBSPs Board Support Packages * * @brief This group contains the Board Support Packages (BSPs). diff --git a/bsps/shared/freebsd/stand/efi/include/README b/bsps/shared/freebsd/stand/efi/include/README new file mode 100644 index 0000000000..bf821fae7e --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/README @@ -0,0 +1,36 @@ +/* $FreeBSD$ */ +/*- + +Files in this directory and subdirectories are subject to the following +copyright unless superceded or supplemented by additional specific license +terms found in the file headers of individual files. + +Copyright (c) 1998-2000 Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +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 ``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 INTEL 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. THE EFI SPECIFICATION AND ALL +OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO +WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE. + +*/ diff --git a/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h new file mode 100644 index 0000000000..97b4a04865 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h @@ -0,0 +1,275 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + + +#ifdef __FreeBSD__ +#include <sys/stdint.h> +#elif __rtems__ +#include <stdint.h> +#else +// +// Basic int types of various widths +// + +#if (__STDC_VERSION__ < 199901L ) + + // No ANSI C 1999/2000 stdint.h integer width declarations + + #ifdef _MSC_EXTENSIONS + + // Use Microsoft C compiler integer width declarations + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + #ifdef UNIX_LP64 + + // Use LP64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + + // Assume P64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + #endif +#endif +#endif /* __FreeBSD__ */ + +// +// Basic EFI types of various widths +// + +#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ +#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + +#endif + +#undef VOID +#define VOID void + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() __asm { int 3 } + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifdef __amd64__ +#define EFIAPI __attribute__((ms_abi)) +#endif + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif + +#define BOOTSERVICE +//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a +//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NO_INTERFACE_DECL + #define EFI_FORWARD_DECLARATION(x) + #define EFI_INTERFACE_DECL(x) +#else + #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x + #define EFI_INTERFACE_DECL(x) typedef struct x +#endif + +#ifdef EFI_NT_EMULATOR + +// +// To help ensure proper coding of integrated drivers, they are +// compiled as DLLs. In NT they require a dll init entry pointer. +// The macro puts a stub entry point into the DLL so it will load. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + EFI_STATUS \ + InitFunction ( \ + EFI_HANDLE ImageHandle, \ + EFI_SYSTEM_TABLE *SystemTable \ + ); \ + \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + __declspec( dllexport ) \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else // EFI_NT_EMULATOR + +// +// When building similar to FW, link everything together as +// one big module. +// + + #define EFI_DRIVER_ENTRY_POINT(InitFunction) + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif // EFI_FW_NT + +#ifdef __FreeBSD__ +#define INTERFACE_DECL(x) struct x +#elif __rtems__ +#define INTERFACE_DECL(x) struct x +#else +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +// +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif /* __FreeBSD__ */ + +#ifdef _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP +#endif + diff --git a/bsps/shared/freebsd/stand/efi/include/efi.h b/bsps/shared/freebsd/stand/efi/include/efi.h new file mode 100644 index 0000000000..5b4743d44b --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efi.h @@ -0,0 +1,87 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efi.h + +Abstract: + + Public EFI header files + + + +Revision History + +--*/ + +// +// Build flags on input +// EFI32 +// EFI_DEBUG - Enable debugging code +// EFI_NT_EMULATOR - Building for running under NT +// + + +#ifndef _EFI_INCLUDE_ +#define _EFI_INCLUDE_ + +#define EFI_FIRMWARE_VENDOR L"INTEL" +#define EFI_FIRMWARE_MAJOR_REVISION 14 +#define EFI_FIRMWARE_MINOR_REVISION 62 +#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) + +#include "efibind.h" +#include "efidef.h" +#include "efidevp.h" +#ifndef __rtems__ +#include "efipciio.h" +#include "efiprot.h" +#endif /* __rtems__ */ +#include "eficon.h" +#include "eficonsctl.h" +#ifndef __rtems__ +#include "efiser.h" +#include "efi_nii.h" +#include "efipxebc.h" +#include "efinet.h" +#endif /* __rtems__ */ +#include "efiapi.h" +#ifndef __rtems__ +#include "efifs.h" +#endif /* __rtems__ */ +#include "efierr.h" +#include "efigop.h" +#ifndef __rtems__ +#include "efiip.h" +#include "efiudp.h" +#include "efitcp.h" +#include "efipoint.h" +#include "efiuga.h" +#endif /* __rtems__ */ +#include <sys/types.h> +#ifdef __rtems__ +#include <stdbool.h> +#endif +/* + * Global variables + */ +extern EFI_LOADED_IMAGE *boot_img; +extern bool boot_services_active; + +/* + * FreeBSD UUID + */ +#define FREEBSD_BOOT_VAR_GUID \ + { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} } + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efiapi.h b/bsps/shared/freebsd/stand/efi/include/efiapi.h new file mode 100644 index 0000000000..fb5c861b38 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efiapi.h @@ -0,0 +1,1204 @@ +/* $FreeBSD$ */ +#ifndef _EFI_API_H +#define _EFI_API_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efiapi.h + +Abstract: + + Global EFI runtime & boot service interfaces + + + + +Revision History + +--*/ + +// +// EFI Specification Revision +// + +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 10 + +// +// Declare forward referenced data structures +// + +INTERFACE_DECL(_EFI_SYSTEM_TABLE); + +// +// EFI Memory +// + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_PAGES) ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NoPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_PAGES) ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_MAP) ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) + + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_POOL) ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_POOL) ( + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + + +#define EFI_OPTIONAL_PTR 0x00000001 +#define EFI_INTERNAL_FNC 0x00000002 // Pointer to internal runtime fnc +#define EFI_INTERNAL_PTR 0x00000004 // Pointer to internal runtime data + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + + +// +// EFI Events +// + + + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_RUNTIME_CONTEXT 0x20000000 + +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 + +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define EVT_EFI_SIGNAL_MASK 0x000000FF +#define EVT_EFI_SIGNAL_MAX 2 + +typedef +VOID +(EFIAPI *EFI_EVENT_NOTIFY) ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event + ); + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} EFI_TIMER_DELAY; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIMER) ( + IN EFI_EVENT Event, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIGNAL_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_WAIT_FOR_EVENT) ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *Event, + OUT UINTN *Index + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CHECK_EVENT) ( + IN EFI_EVENT Event + ); + +// +// Task priority level +// + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +typedef +EFI_TPL +(EFIAPI *EFI_RAISE_TPL) ( + IN EFI_TPL NewTpl + ); + +typedef +VOID +(EFIAPI *EFI_RESTORE_TPL) ( + IN EFI_TPL OldTpl + ); + + +// +// EFI platform varibles +// + +#define EFI_GLOBAL_VARIABLE \ + { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} } + +// Variable attributes +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 + +// Variable size limitation +#define EFI_MAXIMUM_VARIABLE_SIZE 1024 + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN const CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +// +// EFI Time +// + +typedef struct { + UINT32 Resolution; // 1e-6 parts per million + UINT32 Accuracy; // hertz + BOOLEAN SetsToZero; // Set clears sub-second time +} EFI_TIME_CAPABILITIES; + + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + + +// +// Image functions +// + + +// PE32+ Subsystem type for EFI images + +#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION) +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#endif + +// PE32+ Machine type for EFI images + +#if !defined(EFI_IMAGE_MACHINE_IA32) +#define EFI_IMAGE_MACHINE_IA32 0x014c +#endif + +#if !defined(EFI_IMAGE_MACHINE_EBC) +#define EFI_IMAGE_MACHINE_EBC 0x0EBC +#endif + +// Image Entry prototype + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_ENTRY_POINT) ( + IN EFI_HANDLE ImageHandle, + IN struct _EFI_SYSTEM_TABLE *SystemTable + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_LOAD) ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_START) ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT) ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +#ifndef __rtems__ + __dead2 +#endif + ; + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_UNLOAD) ( + IN EFI_HANDLE ImageHandle + ); + + +// Image handle +#define LOADED_IMAGE_PROTOCOL \ + { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } + +#define EFI_LOADED_IMAGE_INFORMATION_REVISION 0x1000 +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + // Source location of image + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + // Images load options + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + // Location of where image was loaded + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + EFI_IMAGE_UNLOAD Unload; + +} EFI_LOADED_IMAGE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT_BOOT_SERVICES) ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +// +// Misc +// + + +typedef +EFI_STATUS +(EFIAPI *EFI_STALL) ( + IN UINTN Microseconds + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WATCHDOG_TIMER) ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown +} EFI_RESET_TYPE; + +typedef +VOID +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ) +#ifndef __rtems__ + __dead2 +#endif + ; + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) ( + OUT UINT64 *Count + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT UINT32 *HighCount + ); + +// +// Protocol handler functions +// + +typedef enum { + EFI_NATIVE_INTERFACE +} EFI_INTERFACE_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) ( + IN OUT EFI_HANDLE *Handle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HANDLE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} EFI_LOCATE_SEARCH_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_DEVICE_PATH) ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT EFI_HANDLE *Device + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RESERVED_SERVICE) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CONNECT_CONTROLLER) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISCONNECT_CONTROLLER)( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle, OPTIONAL + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, OPTIONAL + IN UINT32 Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE DeviceHandle + ); + +typedef struct { + EFI_HANDLE AgentHandle; + EFI_HANDLE ControllerHandle; + UINT32 Attributes; + UINT32 OpenCount; +} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY; + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_PROTOCOL) ( + EFI_GUID *Protocol, + VOID *Registration, OPTIONAL + VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN EFI_HANDLE Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CALCULATE_CRC32) ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +typedef +VOID +(EFIAPI *EFI_COPY_MEM) ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ); + +typedef +VOID +(EFIAPI *EFI_SET_MEM) ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ); + +// +// Standard EFI table header +// + +typedef struct _EFI_TABLE_HEARDER { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + + +// +// EFI Runtime Serivces Table +// + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Time services + // + + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + // + // Virtual memory services + // + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + // + // Variable serviers + // + + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + // + // Misc + // + + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + +} EFI_RUNTIME_SERVICES; + + +// +// EFI Boot Services Table +// + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) + +typedef struct { + + EFI_TABLE_HEADER Hdr; + + // + // Task priority functions + // + + EFI_RAISE_TPL RaiseTPL; + EFI_RESTORE_TPL RestoreTPL; + + // + // Memory functions + // + + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + EFI_ALLOCATE_POOL AllocatePool; + EFI_FREE_POOL FreePool; + + // + // Event & timer functions + // + + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + + // + // Protocol handler functions + // + + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; + EFI_HANDLE_PROTOCOL HandleProtocol; + VOID *Reserved; + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; + EFI_LOCATE_HANDLE LocateHandle; + EFI_LOCATE_DEVICE_PATH LocateDevicePath; + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; + + // + // Image functions + // + + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; + EFI_EXIT_BOOT_SERVICES ExitBootServices; + + // + // Misc functions + // + + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + + // + // DriverSupport Services + // + EFI_CONNECT_CONTROLLER ConnectController; + EFI_DISCONNECT_CONTROLLER DisconnectController; + + // + // Open and Close Protocol Services + // + EFI_OPEN_PROTOCOL OpenProtocol; + EFI_CLOSE_PROTOCOL CloseProtocol; + EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; + + // + // Library Services to reduce size of drivers + // + EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; + EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; + EFI_LOCATE_PROTOCOL LocateProtocol; + + EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces; + EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces; + + // + // CRC32 services + // + EFI_CALCULATE_CRC32 CalculateCrc32; + + // + // Memory Utility Services + // + EFI_COPY_MEM CopyMem; + EFI_SET_MEM SetMem; + +} EFI_BOOT_SERVICES; + + +// +// EFI Configuration Table and GUID definitions +// + +#define MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +#define SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define SMBIOS3_TABLE_GUID \ + { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} } + +#define SAL_SYSTEM_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define FDT_TABLE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} } + +#define DXE_SERVICES_TABLE_GUID \ + { 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9} } + +#define HOB_LIST_TABLE_GUID \ + { 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define LZMA_DECOMPRESSION_GUID \ + { 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x3, 0xcf} } + +#define ARM_MP_CORE_INFO_TABLE_GUID \ + { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} } + +#define ESRT_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80} } + +#define MEMORY_TYPE_INFORMATION_TABLE_GUID \ + { 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} } + +#define DEBUG_IMAGE_INFO_TABLE_GUID \ + { 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b} } + +typedef struct _EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + + +// +// EFI System Table +// + + + + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | 10) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | 02) + +typedef struct _EFI_SYSTEM_TABLE { + EFI_TABLE_HEADER Hdr; + + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + SIMPLE_INPUT_INTERFACE *ConIn; + + EFI_HANDLE ConsoleOutHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut; + + EFI_HANDLE StandardErrorHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + +} EFI_SYSTEM_TABLE; + +/* + * unlisted GUID's.. + */ +#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \ +{ 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7} } + +#define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \ +{ 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe} } + +#define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \ +{ 0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { 0x18A031AB, 0xB443, 0x4D1A, \ + { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ + } + +#define EFI_TAPE_IO_PROTOCOL_GUID \ + { 0x1e93e633, 0xd65a, 0x459e, \ + { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ + } + +#define EFI_SCSI_IO_PROTOCOL_GUID \ + { 0x932f47e6, 0x2362, 0x4002, \ + { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ + } + +#define EFI_USB2_HC_PROTOCOL_GUID \ + { 0x3e745226, 0x9818, 0x45b6, \ + { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ + } + +#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { 0x2755590C, 0x6F3C, 0x42FA, \ + { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ + } + +#define EFI_DEBUGPORT_PROTOCOL_GUID \ + { 0xEBA4E8D2, 0x3858, 0x41EC, \ + { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ + } + +#define EFI_DECOMPRESS_PROTOCOL_GUID \ + { 0xd8117cfe, 0x94a6, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define EFI_ACPI_TABLE_PROTOCOL_GUID \ + { 0xffe06bdd, 0x6107, 0x46a6, \ + { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ + } + +#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + { 0x587e72d7, 0xcc50, 0x4f79, \ + { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ + } + +#define EFI_HII_DATABASE_PROTOCOL_GUID \ + { 0xef9fc172, 0xa1b2, 0x4693, \ + { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ + } + +#define EFI_HII_STRING_PROTOCOL_GUID \ + { 0xfd96974, 0x23aa, 0x4cdc, \ + { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ + } + +#define EFI_HII_IMAGE_PROTOCOL_GUID \ + { 0x31a6406a, 0x6bdf, 0x4e46, \ + { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ + } + +#define EFI_HII_FONT_PROTOCOL_GUID \ + { 0xe9ca4775, 0x8657, 0x47fc, \ + { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ + } +#define EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ + { 0x330d4706, 0xf2a0, 0x4e4f, \ + { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ + } + +#define EFI_COMPONENT_NAME_PROTOCOL_GUID \ +{ 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \ + { 0x6a7a5cff, 0xe8d9, 0x4f70, \ + { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ + } + +#define EFI_USB_IO_PROTOCOL_GUID \ + { 0x2B2F68D6, 0x0CD2, 0x44cf, \ + { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ + } +#define EFI_HCDP_TABLE_GUID \ + { 0xf951938d, 0x620b, 0x42ef, \ + { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ + } + +#define EFI_DEVICE_TREE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, \ + { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ + } + +#define EFI_VENDOR_APPLE_GUID \ + { 0x2B0585EB, 0xD8B8, 0x49A9, \ + { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ + } + +#define EFI_CONSOLE_IN_DEVICE_GUID \ +{ 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_CONSOLE_OUT_DEVICE_GUID \ +{ 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_STANDARD_ERROR_DEVICE_GUID \ +{ 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_UNICODE_COLLATION2_PROTOCOL_GUID \ +{ 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49} } + +#define EFI_FORM_BROWSER2_PROTOCOL_GUID \ +{ 0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58} } + +#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3} } + +#define EFI_ARP_PROTOCOL_GUID \ +{ 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c} } + +#define EFI_IP4_CONFIG_PROTOCOL_GUID \ +{ 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e} } + +#define EFI_IP6_CONFIG_PROTOCOL_GUID \ +{ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a} } + +#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c} } + +#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \ +{ 0x7ab33a91, 0xace5, 0x4326, {0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16} } + +#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F} } + +#define EFI_MTFTP4_PROTOCOL_GUID \ +{ 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b} } + +#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23} } + +#define EFI_MTFTP6_PROTOCOL_GUID \ +{ 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51} } + +#define EFI_DHCP4_PROTOCOL_GUID \ +{ 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56} } + +#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80} } + +#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5} } + +#define EFI_DHCP6_PROTOCOL_GUID \ +{ 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b} } + +#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \ +{ 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77} } + +#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \ +{ 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe} } + +#define EFI_DISK_INFO_PROTOCOL_GUID \ +{ 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27} } + +#define EFI_ISA_IO_PROTOCOL_GUID \ +{ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_VLAN_CONFIG_PROTOCOL_GUID \ +{ 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74} } + +#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \ +{ 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9} } + +#define EFI_ISA_ACPI_PROTOCOL_GUID \ +{ 0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55} } + +#define EFI_PCI_ENUMERATION_COMPLETE_GUID \ +{ 0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93} } + +#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \ +{ 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \ +{ 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63} } + +#define EFI_CAPSULE_ARCH_PROTOCOL_GUID \ +{ 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54} } + +#define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \ +{0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} } + +#define EFI_REALTIME_CLOCK_ARCH_PROTOCOL_GUID \ +{0x27cfac87, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_MP_SERVICES_PROTOCOL_GUID \ +{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} } + +#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \ +{ 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_ACPI_SUPPORT_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_BDS_ARCH_PROTOCOL_GUID \ +{ 0x665e3ff6, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_METRONOME_ARCH_PROTOCOL_GUID \ +{ 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_TIMER_ARCH_PROTOCOL_GUID \ +{ 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_DPC_PROTOCOL_GUID \ +{ 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6} } + +#define EFI_PRINT2_PROTOCOL_GUID \ +{ 0xf05976ef, 0x83f1, 0x4f3d, {0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38} } + +#define EFI_RESET_ARCH_PROTOCOL_GUID \ +{ 0x27cfac88, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_CPU_ARCH_PROTOCOL_GUID \ +{ 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_CPU_IO2_PROTOCOL_GUID \ +{ 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} } + +#define EFI_LEGACY_8259_PROTOCOL_GUID \ +{ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1} } + +#define EFI_SECURITY_ARCH_PROTOCOL_GUID \ +{ 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39} } + +#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \ +{ 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68} } + +#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \ +{ 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33} } + +#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \ +{ 0xd2b2b828, 0x826, 0x48a7, {0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0} } + +#define EFI_DATA_HUB_PROTOCOL_GUID \ +{ 0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +#define PCD_PROTOCOL_GUID \ +{ 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7} } + +#define EFI_PCD_PROTOCOL_GUID \ +{ 0x13a3f0f6, 0x264a, 0x3ef0, {0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34} } + +#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \ +{ 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } + +#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \ +{ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a } } + +#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \ +{ 0x7aa35a69, 0x506c, 0x444f, {0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8} } + +#define LZMA_COMPRESS_GUID \ +{ 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf} } +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/eficon.h b/bsps/shared/freebsd/stand/efi/include/eficon.h new file mode 100644 index 0000000000..ba80114eb9 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/eficon.h @@ -0,0 +1,527 @@ +/* $FreeBSD$ */ +#ifndef _EFI_CON_H +#define _EFI_CON_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + eficon.h + +Abstract: + + EFI console protocols + + + +Revision History + +--*/ + +// +// Text output protocol +// + +#define SIMPLE_TEXT_OUTPUT_PROTOCOL \ + { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_RESET) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_OUTPUT_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_TEST_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_QUERY_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Attribute + ); + +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN (EFI_BLUE | EFI_GREEN) +#define EFI_RED 0x04 +#define EFI_MAGENTA (EFI_BLUE | EFI_RED) +#define EFI_BROWN (EFI_GREEN | EFI_RED) +#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY (EFI_BRIGHT) +#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) +#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) +#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) +#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) +#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) +#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) +#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) + +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) + + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_CLEAR_SCREEN) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Column, + IN UINTN Row + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_ENABLE_CURSOR) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN Enable + ); + +typedef struct { + INT32 MaxMode; + // current settings + INT32 Mode; + INT32 Attribute; + INT32 CursorColumn; + INT32 CursorRow; + BOOLEAN CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE { + EFI_TEXT_RESET Reset; + + EFI_TEXT_OUTPUT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + + // Current mode + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} SIMPLE_TEXT_OUTPUT_INTERFACE; + +// +// Define's for required EFI Unicode Box Draw character +// + +#define BOXDRAW_HORIZONTAL 0x2500 +#define BOXDRAW_VERTICAL 0x2502 +#define BOXDRAW_DOWN_RIGHT 0x250c +#define BOXDRAW_DOWN_LEFT 0x2510 +#define BOXDRAW_UP_RIGHT 0x2514 +#define BOXDRAW_UP_LEFT 0x2518 +#define BOXDRAW_VERTICAL_RIGHT 0x251c +#define BOXDRAW_VERTICAL_LEFT 0x2524 +#define BOXDRAW_DOWN_HORIZONTAL 0x252c +#define BOXDRAW_UP_HORIZONTAL 0x2534 +#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c + +#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 +#define BOXDRAW_DOUBLE_VERTICAL 0x2551 +#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 +#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 +#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 + +#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 +#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 +#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 + +#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 +#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 +#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a + +#define BOXDRAW_UP_LEFT_DOUBLE 0x255b +#define BOXDRAW_UP_DOUBLE_LEFT 0x255c +#define BOXDRAW_DOUBLE_UP_LEFT 0x255d + +#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e +#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f +#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 + +#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 +#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 +#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 + +#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 +#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 +#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 + +#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 +#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 +#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 + +#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a +#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b +#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c + +// +// EFI Required Block Elements Code Chart +// + +#define BLOCKELEMENT_FULL_BLOCK 0x2588 +#define BLOCKELEMENT_LIGHT_SHADE 0x2591 +// +// EFI Required Geometric Shapes Code Chart +// + +#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 +#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba +#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc +#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 + +// +// EFI Required Arrow shapes +// + +#define ARROW_UP 0x2191 +#define ARROW_DOWN 0x2193 + +// +// Text input protocol +// + +#define SIMPLE_TEXT_INPUT_PROTOCOL \ + { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE); + +typedef struct { + UINT16 ScanCode; + CHAR16 UnicodeChar; +} EFI_INPUT_KEY; + +// +// Baseline unicode control chars +// + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +// +// Scan codes for base line keys +// + +#define SCAN_NULL 0x0000 +#define SCAN_UP 0x0001 +#define SCAN_DOWN 0x0002 +#define SCAN_RIGHT 0x0003 +#define SCAN_LEFT 0x0004 +#define SCAN_HOME 0x0005 +#define SCAN_END 0x0006 +#define SCAN_INSERT 0x0007 +#define SCAN_DELETE 0x0008 +#define SCAN_PAGE_UP 0x0009 +#define SCAN_PAGE_DOWN 0x000A +#define SCAN_F1 0x000B +#define SCAN_F2 0x000C +#define SCAN_F3 0x000D +#define SCAN_F4 0x000E +#define SCAN_F5 0x000F +#define SCAN_F6 0x0010 +#define SCAN_F7 0x0011 +#define SCAN_F8 0x0012 +#define SCAN_F9 0x0013 +#define SCAN_F10 0x0014 +#define SCAN_ESC 0x0017 + +// +// EFI Scan code Ex +// +#define SCAN_F11 0x0015 +#define SCAN_F12 0x0016 +#define SCAN_F13 0x0068 +#define SCAN_F14 0x0069 +#define SCAN_F15 0x006A +#define SCAN_F16 0x006B +#define SCAN_F17 0x006C +#define SCAN_F18 0x006D +#define SCAN_F19 0x006E +#define SCAN_F20 0x006F +#define SCAN_F21 0x0070 +#define SCAN_F22 0x0071 +#define SCAN_F23 0x0072 +#define SCAN_F24 0x0073 +#define SCAN_MUTE 0x007F +#define SCAN_VOLUME_UP 0x0080 +#define SCAN_VOLUME_DOWN 0x0081 +#define SCAN_BRIGHTNESS_UP 0x0100 +#define SCAN_BRIGHTNESS_DOWN 0x0101 +#define SCAN_SUSPEND 0x0102 +#define SCAN_HIBERNATE 0x0103 +#define SCAN_TOGGLE_DISPLAY 0x0104 +#define SCAN_RECOVERY 0x0105 +#define SCAN_EJECT 0x0106 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + OUT EFI_INPUT_KEY *Key + ); + +typedef struct _SIMPLE_INPUT_INTERFACE { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} SIMPLE_INPUT_INTERFACE; + +#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + {0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, \ + 0x17, 0xa6, 0x25, 0xaa} } + +INTERFACE_DECL(_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL); + +typedef UINT8 EFI_KEY_TOGGLE_STATE; +// +// Any Shift or Toggle State that is valid should have +// high order bit set. +// +typedef struct EFI_KEY_STATE { + UINT32 KeyShiftState; + EFI_KEY_TOGGLE_STATE KeyToggleState; +} EFI_KEY_STATE; + +typedef struct { + EFI_INPUT_KEY Key; + EFI_KEY_STATE KeyState; +} EFI_KEY_DATA; + +// +// Shift state +// +#define EFI_SHIFT_STATE_VALID 0x80000000 +#define EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define EFI_RIGHT_ALT_PRESSED 0x00000010 +#define EFI_LEFT_ALT_PRESSED 0x00000020 +#define EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define EFI_LEFT_LOGO_PRESSED 0x00000080 +#define EFI_MENU_KEY_PRESSED 0x00000100 +#define EFI_SYS_REQ_PRESSED 0x00000200 + +// +// Toggle state +// +#define EFI_TOGGLE_STATE_VALID 0x80 +#define EFI_KEY_STATE_EXPOSED 0x40 +#define EFI_SCROLL_LOCK_ACTIVE 0x01 +#define EFI_NUM_LOCK_ACTIVE 0x02 +#define EFI_CAPS_LOCK_ACTIVE 0x04 + +// +// EFI Key Notfication Function +// +typedef +EFI_STATUS +(EFIAPI *EFI_KEY_NOTIFY_FUNCTION) ( + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Reset the input device and optionaly run diagnostics + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + EFI_DEVICE_ERROR - The device is not functioning properly and could + not be reset. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + + Returns: + EFI_SUCCESS - The keystroke information was returned. + EFI_NOT_READY - There was no keystroke data availiable. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_STATE) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +/*++ + + Routine Description: + Set certain state for the input device. + + Arguments: + This - Protocol instance pointer. + KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the + state for the input device. + + Returns: + EFI_SUCCESS - The device state was set successfully. + EFI_DEVICE_ERROR - The device is not functioning correctly and could + not have the setting adjusted. + EFI_UNSUPPORTED - The device does not have the ability to set its state. + EFI_INVALID_PARAMETER - KeyToggleState is NULL. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle + ) +/*++ + + Routine Description: + Register a notification function for a particular keystroke for the input device. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + information data for the key that was pressed. + KeyNotificationFunction - Points to the function to be called when the key + sequence is typed specified by KeyData. + NotifyHandle - Points to the unique handle assigned to the registered notification. + + Returns: + EFI_SUCCESS - The notification function was registered successfully. + EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. + EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ) +/*++ + + Routine Description: + Remove a registered notification function from a particular keystroke. + + Arguments: + This - Protocol instance pointer. + NotificationHandle - The handle of the notification function being unregistered. + + Returns: + EFI_SUCCESS - The notification function was unregistered successfully. + EFI_INVALID_PARAMETER - The NotificationHandle is invalid. + EFI_NOT_FOUND - Can not find the matching entry in database. + +--*/ +; + +typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { + EFI_INPUT_RESET_EX Reset; + EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx; + EFI_EVENT WaitForKeyEx; + EFI_SET_STATE SetState; + EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; + EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; +} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/eficonsctl.h b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h new file mode 100644 index 0000000000..68be3d69f4 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2004 - 2010, Intel Corporation. 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. + * + * 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. + */ + +/* + * Original Module Name: ConsoleControl.h + * Abstract: Abstraction of a Text mode or GOP/UGA screen + */ + +/* $FreeBSD$ */ + +#ifndef _EFI_CONS_CTL_H +#define _EFI_CONS_CTL_H + +#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ + { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} } + +typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL; + + +typedef enum { + EfiConsoleControlScreenText, + EfiConsoleControlScreenGraphics, + EfiConsoleControlScreenMaxValue +} EFI_CONSOLE_CONTROL_SCREEN_MODE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, + OUT BOOLEAN *GopUgaExists, OPTIONAL + OUT BOOLEAN *StdInLocked OPTIONAL + ) +/*++ + + Routine Description: + Return the current video mode information. Also returns info about existence + of Graphics Output devices or UGA Draw devices in system, and if the Std In + device is locked. All the arguments are optional and only returned if a non + NULL pointer is passed in. + + Arguments: + This - Protocol instance pointer. + Mode - Are we in text of grahics mode. + GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device + StdInLocked - TRUE if StdIn device is keyboard locked + + Returns: + EFI_SUCCESS - Mode information returned. + +--*/ +; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode + ) +/*++ + + Routine Description: + Set the current mode to either text or graphics. Graphics is + for Quiet Boot. + + Arguments: + This - Protocol instance pointer. + Mode - Mode to set the + + Returns: + EFI_SUCCESS - Mode information returned. + +--*/ +; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN CHAR16 *Password + ) +/*++ + + Routine Description: + Lock Std In devices until Password is typed. + + Arguments: + This - Protocol instance pointer. + Password - Password needed to unlock screen. NULL means unlock keyboard + + Returns: + EFI_SUCCESS - Mode information returned. + EFI_DEVICE_ERROR - Std In not locked + +--*/ +; + + + +struct _EFI_CONSOLE_CONTROL_PROTOCOL { + EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; +}; + +extern EFI_GUID gEfiConsoleControlProtocolGuid; + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efidef.h b/bsps/shared/freebsd/stand/efi/include/efidef.h new file mode 100644 index 0000000000..a8f88d41df --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efidef.h @@ -0,0 +1,224 @@ +/* $FreeBSD$ */ +#ifndef _EFI_DEF_H +#define _EFI_DEF_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efidef.h + +Abstract: + + EFI definitions + + + + +Revision History + +--*/ + +typedef UINT16 CHAR16; +typedef UINT8 CHAR8; +#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ +typedef UINT8 BOOLEAN; +#endif + +#ifndef TRUE + #define TRUE ((BOOLEAN) 1) + #define FALSE ((BOOLEAN) 0) +#endif + +#ifndef NULL + #define NULL ((VOID *) 0) +#endif + +typedef UINTN EFI_STATUS; +typedef UINT64 EFI_LBA; +typedef UINTN EFI_TPL; +typedef VOID *EFI_HANDLE; +typedef VOID *EFI_EVENT; + + +// +// Prototype argument decoration for EFI parameters to indicate +// their direction +// +// IN - argument is passed into the function +// OUT - argument (pointer) is returned from the function +// OPTIONAL - argument is optional +// + +#ifndef IN + #define IN + #define OUT + #define OPTIONAL + #define CONST const +#endif + + +// +// A GUID +// + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + + +// +// Time +// + +typedef struct { + UINT16 Year; // 1998 - 20XX + UINT8 Month; // 1 - 12 + UINT8 Day; // 1 - 31 + UINT8 Hour; // 0 - 23 + UINT8 Minute; // 0 - 59 + UINT8 Second; // 0 - 59 + UINT8 Pad1; + UINT32 Nanosecond; // 0 - 999,999,999 + INT16 TimeZone; // -1440 to 1440 or 2047 + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +// Bit definitions for EFI_TIME.Daylight +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +// Value definition for EFI_TIME.TimeZone +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + + + +// +// Networking +// + +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +typedef struct { + UINT32 ReceivedQueueTimeoutValue; + UINT32 TransmitQueueTimeoutValue; + UINT16 ProtocolTypeFilter; + BOOLEAN EnableUnicastReceive; + BOOLEAN EnableMulticastReceive; + BOOLEAN EnableBroadcastReceive; + BOOLEAN EnablePromiscuousReceive; + BOOLEAN FlushQueuesOnReset; + BOOLEAN EnableReceiveTimestamps; + BOOLEAN DisableBackgroundPolling; +} EFI_MANAGED_NETWORK_CONFIG_DATA; + +// +// Memory +// + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +//Preseve the attr on any range supplied. +//ConventialMemory must have WB,SR,SW when supplied. +//When allocating from ConventialMemory always make it WB,SR,SW +//When returning to ConventialMemory always make it WB,SR,SW +//When getting the memory map, or on RT for runtime types + + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +// possible caching types for the memory range +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +// physical memory protection on range +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_RO 0x0000000000020000 + +// range requires a runtime mapping +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; // Field size is 32 bits followed by 32 bit pad + UINT32 Pad; + EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits + EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits + UINT64 NumberOfPages; // Field size is 64 bits + UINT64 Attribute; // Field size is 64 bits +} EFI_MEMORY_DESCRIPTOR; + +// +// International Language +// + +typedef UINT8 ISO_639_2; +#define ISO_639_2_ENTRY_SIZE 3 + +// +// +// + +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) \ + ( ((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0) ) + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efidevp.h b/bsps/shared/freebsd/stand/efi/include/efidevp.h new file mode 100644 index 0000000000..b00b78f02c --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efidevp.h @@ -0,0 +1,511 @@ +/* $FreeBSD$ */ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +// +// Device Path structures - Section C +// + +#pragma pack(1) + +typedef struct _EFI_DEVICE_PATH { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 + +#define END_DEVICE_PATH_TYPE 0x7f + +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH)) + + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ((size_t)(((a)->Length[0]) | ((a)->Length[1] << 8))) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) +#define IsDevicePathType(a, t) ( DevicePathType(a) == t ) +#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \ + (a)->Length[1] = 0; \ + } + +/* + * + */ +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 +typedef struct _PCI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Function; + UINT8 Device; +} PCI_DEVICE_PATH; + +#define HW_PCCARD_DP 0x02 +typedef struct _PCCARD_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 FunctionNumber; +} PCCARD_DEVICE_PATH; + +#define HW_MEMMAP_DP 0x03 +typedef struct _MEMMAP_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 MemoryType; + EFI_PHYSICAL_ADDRESS StartingAddress; + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +#define HW_VENDOR_DP 0x04 +typedef struct _VENDOR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Guid; +} VENDOR_DEVICE_PATH; + +#define UNKNOWN_DEVICE_GUID \ + { 0xcf31fac5, 0xc24e, 0x11d2, {0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} } + +typedef struct _UKNOWN_DEVICE_VENDOR_DP { + VENDOR_DEVICE_PATH DevicePath; + UINT8 LegacyDriveLetter; +} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH; + +#define HW_CONTROLLER_DP 0x05 +typedef struct _CONTROLLER_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Controller; +} CONTROLLER_DEVICE_PATH; + +/* + * + */ +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 +typedef struct _ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +#define ACPI_EXTENDED_DP 0x02 +typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; + UINT32 CID; +} ACPI_EXTENDED_HID_DEVICE_PATH; + +#define ACPI_ADR_DP 0x03 +/* ACPI_ADR_DEVICE_PATH not defined */ + +// +// EISA ID Macro +// EISA ID Definition 32-bits +// bits[15:0] - three character compressed ASCII EISA ID. +// bits[31:16] - binary number +// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' +// +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) +#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) +/* + * + */ +#define MESSAGING_DEVICE_PATH 0x03 + +#define MSG_ATAPI_DP 0x01 +typedef struct _ATAPI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +#define MSG_SCSI_DP 0x02 +typedef struct _SCSI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 Pun; + UINT16 Lun; +} SCSI_DEVICE_PATH; + +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct _FIBRECHANNEL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 WWN; + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +#define MSG_1394_DP 0x04 +typedef struct _F1394_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 Guid; +} F1394_DEVICE_PATH; + +#define MSG_USB_DP 0x05 +typedef struct _USB_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 ParentPortNumber; + UINT8 InterfaceNumber; +} USB_DEVICE_PATH; + +#define MSG_USB_CLASS_DP 0x0F +typedef struct _USB_CLASS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 VendorId; + UINT16 ProductId; + UINT8 DeviceClass; + UINT8 DeviceSubClass; + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +#define MSG_I2O_DP 0x06 +typedef struct _I2O_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Tid; +} I2O_DEVICE_PATH; + +#define MSG_MAC_ADDR_DP 0x0b +typedef struct _MAC_ADDR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_MAC_ADDRESS MacAddress; + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +#define MSG_IPv4_DP 0x0c +typedef struct _IPv4_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv4_ADDRESS LocalIpAddress; + EFI_IPv4_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; + EFI_IPv4_ADDRESS GatewayIpAddress; + EFI_IPv4_ADDRESS SubnetMask; +} IPv4_DEVICE_PATH; + +#define MSG_IPv6_DP 0x0d +typedef struct _IPv6_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv6_ADDRESS LocalIpAddress; + EFI_IPv6_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv6_DEVICE_PATH; + +#define MSG_INFINIBAND_DP 0x09 +typedef struct _INFINIBAND_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 ResourceFlags; + UINT8 PortGid[16]; + UINT64 ServiceId; + UINT64 TargetPortId; + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 +#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02 +#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 +#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 +#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 + +#define MSG_UART_DP 0x0e +typedef struct _UART_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 BaudRate; + UINT8 DataBits; + UINT8 Parity; + UINT8 StopBits; +} UART_DEVICE_PATH; + +#define MSG_VENDOR_DP 0x0A +/* Use VENDOR_DEVICE_PATH struct */ + +#define DEVICE_PATH_MESSAGING_PC_ANSI \ + { 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define DEVICE_PATH_MESSAGING_VT_100 \ + { 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define DEVICE_PATH_MESSAGING_VT_100_PLUS \ + { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} } + +#define DEVICE_PATH_MESSAGING_VT_UTF8 \ + { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} } + +/* Device Logical Unit SubType. */ +#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 +typedef struct { + EFI_DEVICE_PATH Header; + /* Logical Unit Number for the interface. */ + UINT8 Lun; +} DEVICE_LOGICAL_UNIT_DEVICE_PATH; + +#define MSG_SATA_DP 0x12 +typedef struct _SATA_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 HBAPortNumber; + UINT16 PortMultiplierPortNumber; + UINT16 Lun; +} SATA_DEVICE_PATH; + + +/* DNS Device Path SubType */ +#define MSG_DNS_DP 0x1F +typedef struct { + EFI_DEVICE_PATH Header; + /* Indicates the DNS server address is IPv4 or IPv6 address. */ + UINT8 IsIPv6; + /* Instance of the DNS server address. */ + /* XXX: actually EFI_IP_ADDRESS */ + EFI_IPv4_ADDRESS DnsServerIp[]; +} DNS_DEVICE_PATH; + +/* Uniform Resource Identifiers (URI) Device Path SubType */ +#define MSG_URI_DP 0x18 +typedef struct { + EFI_DEVICE_PATH Header; + /* Instance of the URI pursuant to RFC 3986. */ + CHAR8 Uri[]; +} URI_DEVICE_PATH; + +#define MEDIA_DEVICE_PATH 0x04 + +#define MEDIA_HARDDRIVE_DP 0x01 +typedef struct _HARDDRIVE_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 PartitionNumber; + UINT64 PartitionStart; + UINT64 PartitionSize; + UINT8 Signature[16]; + UINT8 MBRType; + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +#define MEDIA_CDROM_DP 0x02 +typedef struct _CDROM_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 BootEntry; + UINT64 PartitionStart; + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +#define MEDIA_VENDOR_DP 0x03 +/* Use VENDOR_DEVICE_PATH struct */ + +#define MEDIA_FILEPATH_DP 0x04 +typedef struct _FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH Header; + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName) + +#define MEDIA_PROTOCOL_DP 0x05 +typedef struct _MEDIA_PROTOCOL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + + +#define BBS_DEVICE_PATH 0x05 +#define BBS_BBS_DP 0x01 +typedef struct _BBS_BBS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 DeviceType; + UINT16 StatusFlag; + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +/* DeviceType definitions - from BBS specification */ +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_DEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + +typedef union { + EFI_DEVICE_PATH DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + CONTROLLER_DEVICE_PATH Controller; + ACPI_HID_DEVICE_PATH Acpi; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + USB_CLASS_DEVICE_PATH UsbClass; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + BBS_BBS_DEVICE_PATH Bbs; + +} EFI_DEV_PATH; + +typedef union { + EFI_DEVICE_PATH *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + CONTROLLER_DEVICE_PATH *Controller; + ACPI_HID_DEVICE_PATH *Acpi; + ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + USB_CLASS_DEVICE_PATH *UsbClass; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + + HARDDRIVE_DEVICE_PATH *HardDrive; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + CDROM_DEVICE_PATH *CD; + BBS_BBS_DEVICE_PATH *Bbs; + +} EFI_DEV_PATH_PTR; + +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } } + +#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } } + +#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ + { 0x05c99a21, 0xc70f, 0x4ad2, { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } } + +INTERFACE_DECL(_EFI_DEVICE_PATH_PROTOCOL); + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) ( + IN struct _EFI_DEVICE_PATH *This, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortCuts + ); + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) ( + IN struct _EFI_DEVICE_PATH *This, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortCuts + ); + +typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { + EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText; + EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; +} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; + +typedef +struct _EFI_DEVICE_PATH* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE) ( + IN CONST CHAR16* TextDeviceNode + ); +typedef +struct _EFI_DEVICE_PATH* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH) ( + IN CONST CHAR16* TextDevicePath + ); + + +typedef struct _EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL { + EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode; + EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath; +} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL; + +#pragma pack() + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efierr.h b/bsps/shared/freebsd/stand/efi/include/efierr.h new file mode 100644 index 0000000000..a8b6557185 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efierr.h @@ -0,0 +1,68 @@ +/* $FreeBSD$ */ +#ifndef _EFI_ERR_H +#define _EFI_ERR_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efierr.h + +Abstract: + + EFI error codes + + + + +Revision History + +--*/ + + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) a) < 0) +#define EFI_ERROR_CODE(a) (unsigned long)(a & ~EFI_ERROR_MASK) + + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_INVALID_PARAMETER EFIERR(2) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BAD_BUFFER_SIZE EFIERR(4) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_NOT_READY EFIERR(6) +#define EFI_DEVICE_ERROR EFIERR(7) +#define EFI_WRITE_PROTECTED EFIERR(8) +#define EFI_OUT_OF_RESOURCES EFIERR(9) +#define EFI_VOLUME_CORRUPTED EFIERR(10) +#define EFI_VOLUME_FULL EFIERR(11) +#define EFI_NO_MEDIA EFIERR(12) +#define EFI_MEDIA_CHANGED EFIERR(13) +#define EFI_NOT_FOUND EFIERR(14) +#define EFI_ACCESS_DENIED EFIERR(15) +#define EFI_NO_RESPONSE EFIERR(16) +#define EFI_NO_MAPPING EFIERR(17) +#define EFI_TIMEOUT EFIERR(18) +#define EFI_NOT_STARTED EFIERR(19) +#define EFI_ALREADY_STARTED EFIERR(20) +#define EFI_ABORTED EFIERR(21) +#define EFI_ICMP_ERROR EFIERR(22) +#define EFI_TFTP_ERROR EFIERR(23) +#define EFI_PROTOCOL_ERROR EFIERR(24) + +#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1) +#define EFI_WARN_DELETE_FAILURE EFIWARN(2) +#define EFI_WARN_WRITE_FAILURE EFIWARN(3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efigop.h b/bsps/shared/freebsd/stand/efi/include/efigop.h new file mode 100644 index 0000000000..104fa6e44b --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efigop.h @@ -0,0 +1,121 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efigop.h + +Abstract: + Info about framebuffers + + + + +Revision History + +--*/ + +#ifndef _EFIGOP_H +#define _EFIGOP_H + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a} } + +INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT); + +typedef struct { + UINT32 RedMask; + UINT32 GreenMask; + UINT32 BlueMask; + UINT32 ReservedMask; +} EFI_PIXEL_BITMASK; + +typedef enum { + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax, +} EFI_GRAPHICS_PIXEL_FORMAT; + +typedef struct { + UINT32 Version; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PIXEL_BITMASK PixelInformation; + UINT32 PixelsPerScanLine; +} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; + +typedef struct { + UINT32 MaxMode; + UINT32 Mode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + EFI_PHYSICAL_ADDRESS FrameBufferBase; + UINTN FrameBufferSize; +} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN UINT32 ModeNumber + ); + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL; + +typedef enum { + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphcisOutputBltOperationMax, +} EFI_GRAPHICS_OUTPUT_BLT_OPERATION; + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ); + +typedef struct _EFI_GRAPHICS_OUTPUT { + EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; +} EFI_GRAPHICS_OUTPUT; + +#endif /* _EFIGOP_H */ diff --git a/bsps/shared/freebsd/stand/efi/include/efilib.h b/bsps/shared/freebsd/stand/efi/include/efilib.h new file mode 100644 index 0000000000..d31212ff9a --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efilib.h @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * Copyright (c) 2006 Marcel Moolenaar + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _LOADER_EFILIB_H +#define _LOADER_EFILIB_H + +#ifndef __rtems__ +#include <stand.h> +#endif /* __rtems__ */ +#include <stdbool.h> +#include <sys/queue.h> +#ifdef __rtems__ +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#endif /* __rtems__ */ + +extern EFI_HANDLE IH; +extern EFI_SYSTEM_TABLE *ST; +extern EFI_BOOT_SERVICES *BS; +extern EFI_RUNTIME_SERVICES *RS; + +#ifndef __rtems__ + +extern struct devsw efipart_fddev; +extern struct devsw efipart_cddev; +extern struct devsw efipart_hddev; +extern struct devsw efihttp_dev; +extern struct devsw efinet_dev; +extern struct netif_driver efinetif; + +/* EFI block device data, included here to help efi_zfs_probe() */ +typedef STAILQ_HEAD(pdinfo_list, pdinfo) pdinfo_list_t; + +typedef struct pdinfo +{ + STAILQ_ENTRY(pdinfo) pd_link; /* link in device list */ + pdinfo_list_t pd_part; /* list of partitions */ + EFI_HANDLE pd_handle; + EFI_HANDLE pd_alias; + EFI_DEVICE_PATH *pd_devpath; + EFI_BLOCK_IO *pd_blkio; + uint32_t pd_unit; /* unit number */ + uint32_t pd_open; /* reference counter */ + void *pd_bcache; /* buffer cache data */ + struct pdinfo *pd_parent; /* Linked items (eg partitions) */ + struct devsw *pd_devsw; /* Back pointer to devsw */ +} pdinfo_t; + +pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); +pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); +pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h); +pdinfo_t *efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path); + +/* libefi.c */ +void *efi_get_table(EFI_GUID *tbl); +EFI_STATUS OpenProtocolByHandle(EFI_HANDLE, EFI_GUID *, void **); + +static inline EFI_STATUS +efi_exit_boot_services(UINTN key) +{ + EFI_STATUS status; + + status = BS->ExitBootServices(IH, key); + if (!EFI_ERROR(status)) + boot_services_active = false; + return (status); +} + +int efi_getdev(void **vdev, const char *devspec, const char **path); + +int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); +EFI_HANDLE efi_find_handle(struct devsw *, int); +int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *); +int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t); + +EFI_DEVICE_PATH *efi_lookup_image_devpath(EFI_HANDLE); +EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE); +void efi_close_devpath(EFI_HANDLE); +EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); +bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_match_node(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); +void efi_free_devpath_name(CHAR16 *); +bool efi_devpath_same_disk(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_to_media_path(EFI_DEVICE_PATH *); +UINTN efi_devpath_length(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_name_to_devpath(const char *path); +EFI_DEVICE_PATH *efi_name_to_devpath16(CHAR16 *path); +void efi_devpath_free(EFI_DEVICE_PATH *dp); +EFI_HANDLE efi_devpath_to_handle(EFI_DEVICE_PATH *path, EFI_HANDLE *handles, unsigned nhandles); + +int efi_status_to_errno(EFI_STATUS); +EFI_STATUS errno_to_efi_status(int errno); + +void efi_time_init(void); +void efi_time_fini(void); + +int parse_uefi_con_out(void); +EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); + +EFI_STATUS main(int argc, CHAR16 *argv[]); +void efi_exit(EFI_STATUS status) __dead2; + +/* EFI environment initialization. */ +void efi_init_environment(void); + +/* EFI Memory type strings. */ +const char *efi_memory_type(EFI_MEMORY_TYPE); +#endif /* __rtems__ */ + +/* CHAR16 utility functions. */ +int wcscmp(CHAR16 *, CHAR16 *); +void cpy8to16(const char *, CHAR16 *, size_t); +void cpy16to8(const CHAR16 *, char *, size_t); + +#ifndef __rtems__ +/* + * Routines for interacting with EFI's env vars in a more unix-like + * way than the standard APIs. In addition, convenience routines for + * the loader setting / getting FreeBSD specific variables. + */ + +EFI_STATUS efi_delenv(EFI_GUID *guid, const char *varname); +EFI_STATUS efi_freebsd_delenv(const char *varname); +EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len); +EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_setenv(EFI_GUID *guid, const char *varname, UINT32 attr, void *data, __size_t len); +EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr); + +/* guids and names */ +bool efi_guid_to_str(const EFI_GUID *, char **); +bool efi_str_to_guid(const char *, EFI_GUID *); +bool efi_name_to_guid(const char *, EFI_GUID *); +bool efi_guid_to_name(EFI_GUID *, char **); + +/* efipart.c */ +int efipart_inithandles(void); + +#endif /* __rtems__ */ + +#endif /* _LOADER_EFILIB_H */ diff --git a/bsps/shared/freebsd/stand/efi/libefi/libefi.c b/bsps/shared/freebsd/stand/efi/libefi/libefi.c new file mode 100644 index 0000000000..f63e146f2e --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/libefi/libefi.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#ifndef __rtems__ +#include <eficonsctl.h> +#include <efilib.h> +#include <stand.h> +#endif /* __rtems__ */ + +EFI_HANDLE IH; +EFI_SYSTEM_TABLE *ST; +EFI_BOOT_SERVICES *BS; +EFI_RUNTIME_SERVICES *RS; + +#ifndef __rtems__ +void * +efi_get_table(EFI_GUID *tbl) +{ + EFI_GUID *id; + int i; + + for (i = 0; i < ST->NumberOfTableEntries; i++) { + id = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(id, tbl, sizeof(EFI_GUID))) + return (ST->ConfigurationTable[i].VendorTable); + } + return (NULL); +} + +EFI_STATUS +OpenProtocolByHandle(EFI_HANDLE handle, EFI_GUID *protocol, void **interface) +{ + return (BS->OpenProtocol(handle, protocol, interface, IH, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); +} +#endif diff --git a/bsps/shared/freebsd/stand/efi/libefi/wchar.c b/bsps/shared/freebsd/stand/efi/libefi/wchar.c new file mode 100644 index 0000000000..d0c6535143 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/libefi/wchar.c @@ -0,0 +1,73 @@ +/*- + * Copyright 2016 Netflix, Inc. + * + * 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 AUTHOR 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 AUTHOR 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> + +/* + * CHAR16 related functions moved from loader. + * Perhaps we should move those to libsa afterall, but they are + * needed only by UEFI. + */ + +int +wcscmp(CHAR16 *a, CHAR16 *b) +{ + + while (*a && *b && *a == *b) { + a++; + b++; + } + return *a - *b; +} + +/* + * cpy8to16 copies a traditional C string into a CHAR16 string and + * 0 terminates it. len is the size of *dst in bytes. + */ +void +cpy8to16(const char *src, CHAR16 *dst, size_t len) +{ + len <<= 1; /* Assume CHAR16 is 2 bytes */ + while (len > 0 && *src) { + *dst++ = *src++; + len--; + } + *dst++ = (CHAR16)0; +} + +void +cpy16to8(const CHAR16 *src, char *dst, size_t len) +{ + size_t i; + + for (i = 0; i < len && src[i]; i++) + dst[i] = (char)src[i]; + if (i < len) + dst[i] = '\0'; +} diff --git a/bsps/shared/grlib/1553/b1553brm.c b/bsps/shared/grlib/1553/b1553brm.c index 484ee6d0df..7e0b9924e6 100644 --- a/bsps/shared/grlib/1553/b1553brm.c +++ b/bsps/shared/grlib/1553/b1553brm.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * BRM driver * * COPYRIGHT (c) 2006. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /********** Set defaults **********/ @@ -100,7 +119,7 @@ struct irq_log_list { typedef struct { struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[52]; /* Device Name */ struct brm_reg *regs; unsigned int memarea_base; diff --git a/bsps/shared/grlib/1553/b1553rt.c b/bsps/shared/grlib/1553/b1553rt.c index df72ada285..7a4e2535bd 100644 --- a/bsps/shared/grlib/1553/b1553rt.c +++ b/bsps/shared/grlib/1553/b1553rt.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * B1553RT driver implmenetation * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -68,7 +87,7 @@ static rtems_driver_address_table b1553rt_driver = RT_DRIVER_TABLE_ENTRY; typedef struct { struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[52]; /* Device Name */ struct rt_reg *regs; unsigned int ctrl_copy; /* Local copy of config register */ diff --git a/bsps/shared/grlib/1553/gr1553b.c b/bsps/shared/grlib/1553/gr1553b.c index 179f5e3786..debabf0d4c 100644 --- a/bsps/shared/grlib/1553/gr1553b.c +++ b/bsps/shared/grlib/1553/gr1553b.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR1553B driver, used by BC, RT and/or BM driver * * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/1553/gr1553bc.c b/bsps/shared/grlib/1553/gr1553bc.c index f37364e0ea..b992e2e87f 100644 --- a/bsps/shared/grlib/1553/gr1553bc.c +++ b/bsps/shared/grlib/1553/gr1553bc.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR1553B BC driver * * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/1553/gr1553bm.c b/bsps/shared/grlib/1553/gr1553bm.c index 0672c468a4..26736d6cd0 100644 --- a/bsps/shared/grlib/1553/gr1553bm.c +++ b/bsps/shared/grlib/1553/gr1553bm.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR1553B BM driver * * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/1553/gr1553rt.c b/bsps/shared/grlib/1553/gr1553rt.c index 7f35138376..d6eaf11a4b 100644 --- a/bsps/shared/grlib/1553/gr1553rt.c +++ b/bsps/shared/grlib/1553/gr1553rt.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR1553B RT driver * * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/amba/ahbstat.c b/bsps/shared/grlib/amba/ahbstat.c index 3ab0262e1e..ab3807d1d5 100644 --- a/bsps/shared/grlib/amba/ahbstat.c +++ b/bsps/shared/grlib/amba/ahbstat.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* AHB Status register driver * * COPYRIGHT (c) 2009 - 2017. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/amba/ambapp.c b/bsps/shared/grlib/amba/ambapp.c index a94718610b..a63452133d 100644 --- a/bsps/shared/grlib/amba/ambapp.c +++ b/bsps/shared/grlib/amba/ambapp.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011. * Aeroflex Gaisler. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <string.h> diff --git a/bsps/shared/grlib/amba/ambapp_alloc.c b/bsps/shared/grlib/amba/ambapp_alloc.c index 96fcb7961b..c8cd5dc2e9 100644 --- a/bsps/shared/grlib/amba/ambapp_alloc.c +++ b/bsps/shared/grlib/amba/ambapp_alloc.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_count.c b/bsps/shared/grlib/amba/ambapp_count.c index 9da4d93a19..190b5a77e4 100644 --- a/bsps/shared/grlib/amba/ambapp_count.c +++ b/bsps/shared/grlib/amba/ambapp_count.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_depth.c b/bsps/shared/grlib/amba/ambapp_depth.c index 2fe0b142e9..b58f43f5b2 100644 --- a/bsps/shared/grlib/amba/ambapp_depth.c +++ b/bsps/shared/grlib/amba/ambapp_depth.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_find_by_idx.c b/bsps/shared/grlib/amba/ambapp_find_by_idx.c index 55d9022881..5adbf4f0f0 100644 --- a/bsps/shared/grlib/amba/ambapp_find_by_idx.c +++ b/bsps/shared/grlib/amba/ambapp_find_by_idx.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_freq.c b/bsps/shared/grlib/amba/ambapp_freq.c index 07d8be5b39..b5cd5d6de4 100644 --- a/bsps/shared/grlib/amba/ambapp_freq.c +++ b/bsps/shared/grlib/amba/ambapp_freq.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_names.c b/bsps/shared/grlib/amba/ambapp_names.c index 4ccb0621e6..f001e58d34 100644 --- a/bsps/shared/grlib/amba/ambapp_names.c +++ b/bsps/shared/grlib/amba/ambapp_names.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play Device and Vendor name database: Created from GRLIB 3386. * @@ -7,9 +9,26 @@ * The device and vendor definitions are extracted with a script from * GRLIB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_old.c b/bsps/shared/grlib/amba/ambapp_old.c index a51e692fbf..823a2ae773 100644 --- a/bsps/shared/grlib/amba/ambapp_old.c +++ b/bsps/shared/grlib/amba/ambapp_old.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Old AMBA scanning Interface provided for backwards compability * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/ambapp.h> diff --git a/bsps/shared/grlib/amba/ambapp_parent.c b/bsps/shared/grlib/amba/ambapp_parent.c index b77b6eec68..bcb4c0424f 100644 --- a/bsps/shared/grlib/amba/ambapp_parent.c +++ b/bsps/shared/grlib/amba/ambapp_parent.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines * * COPYRIGHT (c) 2011 * Aeroflex Gaisler * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/amba/ambapp_show.c b/bsps/shared/grlib/amba/ambapp_show.c index 12cefa2c0f..cad978539b 100644 --- a/bsps/shared/grlib/amba/ambapp_show.c +++ b/bsps/shared/grlib/amba/ambapp_show.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * AMBA Plug & Play routines: device information printing. * * COPYRIGHT (c) 2009. * Aeroflex Gaisler. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdio.h> diff --git a/bsps/shared/grlib/analog/gradcdac.c b/bsps/shared/grlib/analog/gradcdac.c index 02939e58f0..09f8760bcd 100644 --- a/bsps/shared/grlib/analog/gradcdac.c +++ b/bsps/shared/grlib/analog/gradcdac.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* ADC / DAC (GRADCDAC) interface implementation * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> @@ -34,7 +53,7 @@ struct gradcdac_priv { struct gradcdac_regs *regs; /* Must be first */ struct drvmgr_dev *dev; - char devName[48]; + char devName[54]; /* Must be at least 48 per names */ unsigned int freq; int irqno; diff --git a/bsps/shared/grlib/ascs/grascs.c b/bsps/shared/grlib/ascs/grascs.c index 0e4a2ba868..016fb207e4 100644 --- a/bsps/shared/grlib/ascs/grascs.c +++ b/bsps/shared/grlib/ascs/grascs.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* This file contains the GRASCS RTEMS driver * * COPYRIGHT (c) 2008. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/btimer/gptimer.c b/bsps/shared/grlib/btimer/gptimer.c index 4b3ec8c4b8..cbf058ccef 100644 --- a/bsps/shared/grlib/btimer/gptimer.c +++ b/bsps/shared/grlib/btimer/gptimer.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* This file contains the driver for the GRLIB GPTIMER timers port. The driver * is implemented by using the tlib.c simple timer layer and the Driver * Manager. @@ -26,23 +28,37 @@ * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> -#include <bsp.h> -#include <stdlib.h> -#include <string.h> #include <drvmgr/drvmgr.h> #include <grlib/ambapp_bus.h> -#include <grlib/grlib.h> #include <grlib/gptimer.h> +#include <grlib/gptimer-regs.h> +#include <grlib/io.h> #include <grlib/tlib.h> #if defined(LEON3) -#include <leon.h> +#include <bsp/leon3.h> #endif #ifdef GPTIMER_INFO_AVAIL @@ -56,49 +72,21 @@ #include <grlib/grlib_impl.h> -/* GPTIMER Core Configuration Register (READ-ONLY) */ -#define GPTIMER_CFG_TIMERS_BIT 0 -#define GPTIMER_CFG_IRQ_BIT 3 -#define GPTIMER_CFG_SI_BIT 8 -#define GPTIMER_CFG_DF_BIT 9 - -#define GPTIMER_CFG_TIMERS (0x7<<GPTIMER_CFG_TIMERS_BIT) -#define GPTIMER_CFG_IRQ (0x1f<<GPTIMER_CFG_IRQ_BIT) -#define GPTIMER_CFG_SI (1<<GPTIMER_CFG_SI_BIT) -#define GPTIMER_CFG_DF (1<<GPTIMER_CFG_DF_BIT) - -/* GPTIMER Timer Control Register */ -#define GPTIMER_CTRL_EN_BIT 0 -#define GPTIMER_CTRL_RS_BIT 1 -#define GPTIMER_CTRL_LD_BIT 2 -#define GPTIMER_CTRL_IE_BIT 3 -#define GPTIMER_CTRL_IP_BIT 4 -#define GPTIMER_CTRL_CH_BIT 5 -#define GPTIMER_CTRL_DH_BIT 6 - -#define GPTIMER_CTRL_EN (1<<GPTIMER_CTRL_EN_BIT) -#define GPTIMER_CTRL_RS (1<<GPTIMER_CTRL_RS_BIT) -#define GPTIMER_CTRL_LD (1<<GPTIMER_CTRL_LD_BIT) -#define GPTIMER_CTRL_IE (1<<GPTIMER_CTRL_IE_BIT) -#define GPTIMER_CTRL_IP (1<<GPTIMER_CTRL_IP_BIT) -#define GPTIMER_CTRL_CH (1<<GPTIMER_CTRL_CH_BIT) -#define GPTIMER_CTRL_DH (1<<GPTIMER_CTRL_DH_BIT) - #define DBG(x...) /* GPTIMER timer private */ -struct gptimer_timer { +struct gptimer_timer_priv { struct tlib_dev tdev; /* Must be first in struct */ - struct gptimer_timer_regs *tregs; + gptimer_timer *tregs; char index; /* Timer Index in this driver */ char tindex; /* Timer Index In Hardware */ - unsigned char irq_ack_mask; + uint32_t irq_ack_mask; }; /* GPTIMER Core private */ struct gptimer_priv { struct drvmgr_dev *dev; - struct gptimer_regs *regs; + gptimer *regs; unsigned int base_clk; unsigned int base_freq; unsigned int widthmask; @@ -107,7 +95,7 @@ struct gptimer_priv { /* Structure per Timer unit, the core supports up to 8 timers */ int timer_cnt; - struct gptimer_timer timers[0]; + struct gptimer_timer_priv timers[0]; }; void gptimer_isr(void *data); @@ -181,14 +169,14 @@ void gptimer_register_drv (void) int gptimer_init1(struct drvmgr_dev *dev) { struct gptimer_priv *priv; - struct gptimer_regs *regs; + gptimer *regs; struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; int timer_hw_cnt, timer_cnt, timer_start; int i, size; - struct gptimer_timer *timer; + struct gptimer_timer_priv *timer; union drvmgr_key_value *value; - unsigned char irq_ack_mask; + uint32_t irq_ack_mask; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)dev->businfo; @@ -196,12 +184,12 @@ int gptimer_init1(struct drvmgr_dev *dev) return -1; } pnpinfo = &ambadev->info; - regs = (struct gptimer_regs *)pnpinfo->apb_slv->start; + regs = (gptimer *)pnpinfo->apb_slv->start; DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name); /* Get number of Timers */ - timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS; + timer_hw_cnt = GPTIMER_CONFIG_TIMERS_GET(grlib_load_32(®s->config)); /* Let user spelect a range of timers to be used. In AMP systems * it is sometimes neccessary to leave timers for other CPU instances. @@ -232,7 +220,7 @@ int gptimer_init1(struct drvmgr_dev *dev) * are present. */ size = sizeof(struct gptimer_priv) + - timer_cnt*sizeof(struct gptimer_timer); + timer_cnt*sizeof(struct gptimer_timer_priv); priv = dev->priv = grlib_calloc(1, size); if ( !priv ) return DRVMGR_NOMEM; @@ -258,24 +246,24 @@ int gptimer_init1(struct drvmgr_dev *dev) */ value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT); if ( value ) - regs->scaler_reload = value->i; + grlib_store_32(®s->sreload, value->i); /* Get Frequency that the timers are operating in (after prescaler) */ - priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1); + priv->base_freq = priv->base_clk / (grlib_load_32(®s->sreload) + 1); /* Stop Timer and probe Pending bit. In newer hardware the * timer has pending bit is cleared by writing a one to it, * whereas older versions it is cleared with a zero. */ - priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP; - if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0) - irq_ack_mask = ~GPTIMER_CTRL_IP; + grlib_store_32(®s->timer[timer_start].tctrl, GPTIMER_TCTRL_IP); + if ((grlib_load_32(®s->timer[timer_start].tctrl) & GPTIMER_TCTRL_IP) != 0) + irq_ack_mask = ~GPTIMER_TCTRL_IP; else - irq_ack_mask = ~0; + irq_ack_mask = ~0U; /* Probe timer register width mask */ - priv->regs->timer[timer_start].value = 0xffffffff; - priv->widthmask = priv->regs->timer[timer_start].value; + grlib_store_32(®s->timer[timer_start].tcntval, 0xffffffff); + priv->widthmask = grlib_load_32(®s->timer[timer_start].tcntval); priv->timer_cnt = timer_cnt; for (i=0; i<timer_cnt; i++) { @@ -295,7 +283,7 @@ int gptimer_init1(struct drvmgr_dev *dev) * B. Each Timer have an individual IRQ. The number is: * BASE_IRQ + timer_index */ - priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0; + priv->separate_interrupt = (grlib_load_32(®s->config) & GPTIMER_CONFIG_SI) != 0; return DRVMGR_OK; } @@ -307,7 +295,7 @@ static int gptimer_info( void *p, int argc, char *argv[]) { struct gptimer_priv *priv = dev->priv; - struct gptimer_timer *timer; + struct gptimer_timer_priv *timer; char buf[64]; int i; @@ -318,7 +306,7 @@ static int gptimer_info( print_line(p, buf); sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs); print_line(p, buf); - sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload); + sprintf(buf, "BASE SCALER: %d", grlib_load_32(&priv->regs->sreload)); print_line(p, buf); sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000); print_line(p, buf); @@ -331,9 +319,9 @@ static int gptimer_info( print_line(p, buf); sprintf(buf, " TLIB Index: %d", timer->index); print_line(p, buf); - sprintf(buf, " RELOAD REG: %d", timer->tregs->reload); + sprintf(buf, " RELOAD REG: %d", grlib_load_32(&timer->tregs->trldval)); print_line(p, buf); - sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl); + sprintf(buf, " CTRL REG: %d", grlib_load_32(&timer->tregs->tctrl)); print_line(p, buf); } @@ -341,24 +329,28 @@ static int gptimer_info( } #endif -static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t) +static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer_priv *t) { return (struct gptimer_priv *) ((unsigned int)t - sizeof(struct gptimer_priv) - - t->index * sizeof(struct gptimer_timer)); + t->index * sizeof(struct gptimer_timer_priv)); } static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl = timer->tregs->ctrl; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; - if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) == - (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) { + tctrl = grlib_load_32(&timer->tregs->tctrl); + + if ((tctrl & (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) == + (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) { /* clear Pending IRQ ? */ - if (ack) - timer->tregs->ctrl = ctrl & timer->irq_ack_mask; + if (ack) { + tctrl &= timer->irq_ack_mask; + grlib_store_32(&timer->tregs->tctrl, tctrl); + } return 1; /* timer generated IRQ */ } else return 0; /* was not timer causing IRQ */ @@ -387,12 +379,15 @@ void gptimer_isr(void *data) static void gptimer_tlib_reset(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) & - GPTIMER_CTRL_IP; - timer->tregs->reload = 0xffffffff; - timer->tregs->ctrl = GPTIMER_CTRL_LD; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; + + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= GPTIMER_TCTRL_IP; + grlib_store_32(&timer->tregs->tctrl, tctrl); + grlib_store_32(&timer->tregs->trldval, 0xffffffff); + grlib_store_32(&timer->tregs->tctrl, GPTIMER_TCTRL_LD); } static void gptimer_tlib_get_freq( @@ -400,24 +395,24 @@ static void gptimer_tlib_get_freq( unsigned int *basefreq, unsigned int *tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); /* Calculate base frequency from Timer Clock and Prescaler */ if ( basefreq ) *basefreq = priv->base_freq; if ( tickrate ) - *tickrate = timer->tregs->reload + 1; + *tickrate = grlib_load_32(&timer->tregs->trldval) + 1; } static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - timer->tregs->reload = tickrate - 1; + grlib_store_32(&timer->tregs->trldval, tickrate - 1); /*Check that value was allowed (Timer may not be as wide as expected)*/ - if ( timer->tregs->reload != (tickrate - 1) ) + if (grlib_load_32(&timer->tregs->trldval) != (tickrate - 1)) return -1; else return 0; @@ -425,8 +420,9 @@ static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; if ( priv->separate_interrupt ) { drvmgr_interrupt_register(priv->dev, timer->tindex, @@ -457,16 +453,21 @@ static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *d } #endif - timer->tregs->ctrl |= GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; /* Turn off IRQ at source, unregister IRQ handler */ - timer->tregs->ctrl &= ~GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); if ( priv->separate_interrupt ) { drvmgr_interrupt_unregister(priv->dev, timer->tindex, @@ -483,46 +484,54 @@ static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void static void gptimer_tlib_start(struct tlib_dev *hand, int once) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected frequency before starting Frequency */ - ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= ~GPTIMER_TCTRL_RS; + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; if ( once == 0 ) - ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */ - timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask & - ~GPTIMER_CTRL_RS); + tctrl |= GPTIMER_TCTRL_RS; /* Restart Timer */ + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_stop(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected Frequency */ - timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP); + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~(GPTIMER_TCTRL_EN|GPTIMER_TCTRL_IP); + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_restart(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; - timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_get_counter( struct tlib_dev *hand, unsigned int *counter) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - *counter = timer->tregs->value; + *counter = grlib_load_32(&timer->tregs->tcntval); } static void gptimer_tlib_get_widthmask( struct tlib_dev *hand, unsigned int *widthmask) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); *widthmask = priv->widthmask; diff --git a/bsps/shared/grlib/btimer/tlib.c b/bsps/shared/grlib/btimer/tlib.c index d66a472fe9..ee5dbd7730 100644 --- a/bsps/shared/grlib/btimer/tlib.c +++ b/bsps/shared/grlib/btimer/tlib.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Timer Library (TLIB) * * COPYRIGHT (c) 2011. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/btimer/tlib_ckinit.c b/bsps/shared/grlib/btimer/tlib_ckinit.c index bc52ff4fe9..e2179090fa 100644 --- a/bsps/shared/grlib/btimer/tlib_ckinit.c +++ b/bsps/shared/grlib/btimer/tlib_ckinit.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Clock Tick Device Driver using Timer Library implemented * by the GRLIB GPTIMER / LEON2 Timer drivers. @@ -5,9 +7,26 @@ * COPYRIGHT (c) 2010 - 2017. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * */ @@ -414,10 +433,10 @@ static const struct ops ops_irqamp = { } \ } while (0) -#define Clock_driver_timecounter_tick() \ +#define Clock_driver_timecounter_tick(arg) \ tlib_clock_timecounter_tick() -#define Clock_driver_support_at_tick() \ +#define Clock_driver_support_at_tick(arg) \ do { \ rtems_device_driver ret; \ ret = tlib_clock_at_tick(); \ diff --git a/bsps/shared/grlib/can/canbtrs.c b/bsps/shared/grlib/can/canbtrs.c index 307547475c..289f13a2f0 100644 --- a/bsps/shared/grlib/can/canbtrs.c +++ b/bsps/shared/grlib/can/canbtrs.c @@ -12,7 +12,7 @@ */ /* - * Copyright (C) 2019, 2020 Cobham Gailer AB + * Copyright (C) 2019, 2020 Cobham Gaisler AB * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/grlib/can/canmux.c b/bsps/shared/grlib/can/canmux.c index 631b9d941a..a6c64ea0d9 100644 --- a/bsps/shared/grlib/can/canmux.c +++ b/bsps/shared/grlib/can/canmux.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * CAN_MUX driver. Present in GR712RC. * * COPYRIGHT (c) 2008. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems/libio.h> diff --git a/bsps/shared/grlib/can/grcan.c b/bsps/shared/grlib/can/grcan.c index 162b2e1a79..47d86b053b 100644 --- a/bsps/shared/grlib/can/grcan.c +++ b/bsps/shared/grlib/can/grcan.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRCAN driver * * COPYRIGHT (c) 2007-2019. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/shared/grlib/can/grcan_internal.h b/bsps/shared/grlib/can/grcan_internal.h index 86ccda1997..d27476a985 100644 --- a/bsps/shared/grlib/can/grcan_internal.h +++ b/bsps/shared/grlib/can/grcan_internal.h @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRCAN driver * * COPYRIGHT (c) 2007-2019. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 GRCAN_DEFAULT_BAUD @@ -37,7 +56,7 @@ struct grcan_config { struct grcan_priv { struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[52]; /* Device Name */ unsigned int baseaddr, ram_base; struct grcan_regs *regs; int irq; diff --git a/bsps/shared/grlib/can/grcanfd.c b/bsps/shared/grlib/can/grcanfd.c index 00eb4b6432..e50280c41c 100644 --- a/bsps/shared/grlib/can/grcanfd.c +++ b/bsps/shared/grlib/can/grcanfd.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * FD extenstions to the GRCAN driver * * COPYRIGHT (c) 2007-2019. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/shared/grlib/can/grcanstd.c b/bsps/shared/grlib/can/grcanstd.c index b92c15a32b..a9da013aca 100644 --- a/bsps/shared/grlib/can/grcanstd.c +++ b/bsps/shared/grlib/can/grcanstd.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * non-FD specific function for GRCAN driver * * COPYRIGHT (c) 2007-2019. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/shared/grlib/can/occan.c b/bsps/shared/grlib/can/occan.c index 3df5c147de..a6b37ec74c 100644 --- a/bsps/shared/grlib/can/occan.c +++ b/bsps/shared/grlib/can/occan.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* OC_CAN driver * * COPYRIGHT (c) 2007. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> @@ -207,7 +226,7 @@ typedef struct { typedef struct { struct drvmgr_dev *dev; - char devName[32]; + char devName[52]; SPIN_DECLARE(devlock); /* hardware shortcuts */ diff --git a/bsps/shared/grlib/can/satcan.c b/bsps/shared/grlib/can/satcan.c index a94d570955..5487de49ac 100644 --- a/bsps/shared/grlib/can/satcan.c +++ b/bsps/shared/grlib/can/satcan.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * SatCAN FPGA driver * * COPYRIGHT (c) 2008. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems/libio.h> diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus.c b/bsps/shared/grlib/drvmgr/ambapp_bus.c index 3c38fc16e0..54960233d9 100644 --- a/bsps/shared/grlib/drvmgr/ambapp_bus.c +++ b/bsps/shared/grlib/drvmgr/ambapp_bus.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* General part of a AMBA Plug & Play bus driver. * * COPYRIGHT (c) 2008. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * * This is the general part of the different AMBA Plug & Play * drivers. The drivers are wrappers around this driver, making diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c index fbbe5fa9bb..35d23c1858 100644 --- a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c +++ b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* LEON3 GRLIB AMBA Plug & Play bus driver. * * COPYRIGHT (c) 2008. @@ -6,9 +8,26 @@ * This is driver is a wrapper for the general AMBA Plug & Play bus * driver. This is the root bus driver for GRLIB systems. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> @@ -22,7 +41,7 @@ #include <grlib/genirq.h> #include <bsp.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #include <grlib/grlib_impl.h> @@ -208,7 +227,10 @@ static int ambapp_grlib_int_clear struct drvmgr_dev *dev, int irq) { - BSP_shared_interrupt_clear(irq); + if (rtems_interrupt_clear(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } @@ -218,7 +240,10 @@ static int ambapp_grlib_int_mask int irq ) { - BSP_shared_interrupt_mask(irq); + if (rtems_interrupt_vector_disable(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } @@ -228,7 +253,10 @@ static int ambapp_grlib_int_unmask int irq ) { - BSP_shared_interrupt_unmask(irq); + if (rtems_interrupt_vector_enable(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } diff --git a/bsps/shared/grlib/drvmgr/get_resarray_count.c b/bsps/shared/grlib/drvmgr/get_resarray_count.c index 7b5850d982..40eaacb48e 100644 --- a/bsps/shared/grlib/drvmgr/get_resarray_count.c +++ b/bsps/shared/grlib/drvmgr/get_resarray_count.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* Common driver configuration routines. * * COPYRIGHT (c) 2015. * Cobham Gaisler. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/gpio/gpiolib.c b/bsps/shared/grlib/gpio/gpiolib.c index cf0038c5bb..16e3a79ac2 100644 --- a/bsps/shared/grlib/gpio/gpiolib.c +++ b/bsps/shared/grlib/gpio/gpiolib.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GPIOLIB interface implementation * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/gpio/grgpio.c b/bsps/shared/grlib/gpio/grgpio.c index 05504ef020..711293dd15 100644 --- a/bsps/shared/grlib/gpio/grgpio.c +++ b/bsps/shared/grlib/gpio/grgpio.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRGPIO GPIO Driver interface. * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -360,12 +379,12 @@ static int grgpio_gpiolib_get_info(void *handle, struct gpiolib_info *pinfo) /* Failed to get prefix, make sure of a unique FS name * by using the driver minor. */ - snprintf(pinfo->devName, 64, "/dev/grgpio%d/%d", dev->minor_drv, portnr); + snprintf(pinfo->devName, 80, "/dev/grgpio%d/%d", dev->minor_drv, portnr); } else { /* Got special prefix, this means we have a bus prefix * And we should use our "bus minor" */ - snprintf(pinfo->devName, 64, "/dev/%sgrgpio%d/%d", prefix, dev->minor_bus, portnr); + snprintf(pinfo->devName, 80, "/dev/%sgrgpio%d/%d", prefix, dev->minor_bus, portnr); } return 0; diff --git a/bsps/shared/grlib/i2c/i2cmst.c b/bsps/shared/grlib/i2c/i2cmst.c index fad0937df2..70c796bbce 100644 --- a/bsps/shared/grlib/i2c/i2cmst.c +++ b/bsps/shared/grlib/i2c/i2cmst.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Driver for GRLIB port of OpenCores I2C-master * * COPYRIGHT (c) 2007 Cobham Gaisler AB * based on the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * * This file contains the driver and initialization code */ @@ -356,7 +375,7 @@ int i2cmst_init3(struct drvmgr_dev *dev) { gr_i2cmst_prv_t *priv; char prefix[32]; - char devName[32]; + char devName[50]; int rc; priv = (gr_i2cmst_prv_t *)dev->priv; diff --git a/bsps/shared/grlib/iommu/griommu.c b/bsps/shared/grlib/iommu/griommu.c index d0d22723ca..7e0a1eb263 100644 --- a/bsps/shared/grlib/iommu/griommu.c +++ b/bsps/shared/grlib/iommu/griommu.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRIOMMU Driver Interface * * COPYRIGHT (c) 2017 * Cobham Gaisler AB * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/irq/genirq.c b/bsps/shared/grlib/irq/genirq.c index ca80445c70..8c35e80474 100644 --- a/bsps/shared/grlib/irq/genirq.c +++ b/bsps/shared/grlib/irq/genirq.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Generic interrupt helpers mainly for GRLIB PCI peripherals * * COPYRIGHT (c) 2008. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/l2c/l2c.c b/bsps/shared/grlib/l2c/l2c.c index 4a443ed7cf..17d96874ae 100644 --- a/bsps/shared/grlib/l2c/l2c.c +++ b/bsps/shared/grlib/l2c/l2c.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRLIB L2CACHE Driver * * COPYRIGHT (c) 2017 * Cobham Gaisler AB * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/mem/mctrl.c b/bsps/shared/grlib/mem/mctrl.c index a384547de8..f98b1713e6 100644 --- a/bsps/shared/grlib/mem/mctrl.c +++ b/bsps/shared/grlib/mem/mctrl.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* Memory Controller driver (FTMTRL, MCTRL) * * COPYRIGHT (c) 2008. @@ -7,9 +9,26 @@ * The driver sets the memory configuration registers (MCFG1, MCFG2, MCFG3) * during driver initialization * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /******************* Driver manager interface ***********************/ diff --git a/bsps/shared/grlib/pci/gr_701.c b/bsps/shared/grlib/pci/gr_701.c index 25dc6801a9..85e9fd54c5 100644 --- a/bsps/shared/grlib/pci/gr_701.c +++ b/bsps/shared/grlib/pci/gr_701.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-701 PCI Target driver. * * COPYRIGHT (c) 2008. @@ -10,9 +12,26 @@ * Driver resources for the AMBA PnP bus provided can be set using * gr701_set_resources(). * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/pci/gr_rasta_adcdac.c b/bsps/shared/grlib/pci/gr_rasta_adcdac.c index 9054967d6c..cafb1d14b9 100644 --- a/bsps/shared/grlib/pci/gr_rasta_adcdac.c +++ b/bsps/shared/grlib/pci/gr_rasta_adcdac.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-RASTA-ADCDAC PCI Target driver. * * COPYRIGHT (c) 2008. @@ -10,9 +12,26 @@ * Driver resources for the AMBA PnP bus provided can be set using * gr_rasta_adcdac_set_resources(). * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/pci/gr_rasta_io.c b/bsps/shared/grlib/pci/gr_rasta_io.c index f93f73c5a0..25153c1b2e 100644 --- a/bsps/shared/grlib/pci/gr_rasta_io.c +++ b/bsps/shared/grlib/pci/gr_rasta_io.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-RASTA-IO PCI Target driver. * * COPYRIGHT (c) 2008. @@ -10,9 +12,26 @@ * Driver resources for the AMBA PnP bus provided can be set using * gr_rasta_io_set_resources(). * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/pci/gr_rasta_spw_router.c b/bsps/shared/grlib/pci/gr_rasta_spw_router.c index 33168cf156..facd554195 100644 --- a/bsps/shared/grlib/pci/gr_rasta_spw_router.c +++ b/bsps/shared/grlib/pci/gr_rasta_spw_router.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-RASTA-SPW-ROUTER PCI Target driver. * * COPYRIGHT (c) 2011. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * * Configures the GR-RASTA-SPW-ROUTER interface PCI board. * This driver provides a AMBA PnP bus by using the general part diff --git a/bsps/shared/grlib/pci/gr_rasta_tmtc.c b/bsps/shared/grlib/pci/gr_rasta_tmtc.c index ccd1df40a6..60db715802 100644 --- a/bsps/shared/grlib/pci/gr_rasta_tmtc.c +++ b/bsps/shared/grlib/pci/gr_rasta_tmtc.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-RASTA-TMTC PCI Target driver. * * COPYRIGHT (c) 2008. @@ -10,9 +12,26 @@ * Driver resources for the AMBA PnP bus provided can be set by overriding * the defaults by declaring gr_rasta_tmtc_resources[]. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/pci/gr_tmtc_1553.c b/bsps/shared/grlib/pci/gr_tmtc_1553.c index 55a6358035..f87ea3c8ed 100644 --- a/bsps/shared/grlib/pci/gr_tmtc_1553.c +++ b/bsps/shared/grlib/pci/gr_tmtc_1553.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GR-TMTC-1553 PCI Target driver. * * COPYRIGHT (c) 2008. @@ -10,9 +12,26 @@ * Driver resources for the AMBA PnP bus provided can be set using * gr_tmtc_1553_set_resources(). * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <inttypes.h> diff --git a/bsps/shared/grlib/pci/grpci.c b/bsps/shared/grlib/pci/grpci.c index 75eacbf272..eef995304d 100644 --- a/bsps/shared/grlib/pci/grpci.c +++ b/bsps/shared/grlib/pci/grpci.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRLIB GRPCI PCI HOST driver. * * COPYRIGHT (c) 2008. @@ -11,9 +13,26 @@ * default taken from Plug and Play, but may be overridden by the * driver resources INTA#..INTD#. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/pci/grpci2.c b/bsps/shared/grlib/pci/grpci2.c index 7e3a414839..d8b521459f 100644 --- a/bsps/shared/grlib/pci/grpci2.c +++ b/bsps/shared/grlib/pci/grpci2.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRLIB GRPCI2 PCI HOST driver. * * COPYRIGHT (c) 2011 * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /* Configures the GRPCI2 core and initialize, diff --git a/bsps/shared/grlib/pci/grpci2dma.c b/bsps/shared/grlib/pci/grpci2dma.c index cb41d48966..3d90c811b1 100644 --- a/bsps/shared/grlib/pci/grpci2dma.c +++ b/bsps/shared/grlib/pci/grpci2dma.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRPCI2 DMA Driver * * COPYRIGHT (c) 2017 * Cobham Gaisler AB * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdlib.h> diff --git a/bsps/shared/grlib/pci/pcif.c b/bsps/shared/grlib/pci/pcif.c index 9be45ba189..602c74dc44 100644 --- a/bsps/shared/grlib/pci/pcif.c +++ b/bsps/shared/grlib/pci/pcif.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRLIB PCIF PCI HOST driver. * * COPYRIGHT (c) 2008. @@ -11,9 +13,26 @@ * default taken from Plug and Play, but may be overridden by the * driver resources INTA#..INTD#. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdio.h> diff --git a/bsps/shared/grlib/pwm/grpwm.c b/bsps/shared/grlib/pwm/grpwm.c index a824201795..32d16a2da8 100644 --- a/bsps/shared/grlib/pwm/grpwm.c +++ b/bsps/shared/grlib/pwm/grpwm.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * GRPWM PWM Driver interface. * * COPYRIGHT (c) 2009. * Cobham Gaisler AB, * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -150,7 +169,7 @@ struct grpwm_regs { struct grpwm_priv { struct drvmgr_dev *dev; struct grpwm_regs *regs; - char devName[32]; + char devName[52]; int irq; int open; diff --git a/bsps/shared/grlib/scrub/memscrub.c b/bsps/shared/grlib/scrub/memscrub.c index 7c6ceb43e0..d4e6c786e5 100644 --- a/bsps/shared/grlib/scrub/memscrub.c +++ b/bsps/shared/grlib/scrub/memscrub.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* Memory Scrubber register driver * * COPYRIGHT (c) 2017. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <stdint.h> diff --git a/bsps/shared/grlib/slink/grslink.c b/bsps/shared/grlib/slink/grslink.c index 7c1eb8e290..d4cdcae868 100644 --- a/bsps/shared/grlib/slink/grslink.c +++ b/bsps/shared/grlib/slink/grslink.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This file contains the RTEMS GRSLINK SLINK master driver * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. * * Comments concerning current driver implementation: * diff --git a/bsps/shared/grlib/spi/spictrl.c b/bsps/shared/grlib/spi/spictrl.c index 0c9f88c10f..081d281037 100644 --- a/bsps/shared/grlib/spi/spictrl.c +++ b/bsps/shared/grlib/spi/spictrl.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * SPICTRL SPI driver implmenetation * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -232,7 +251,7 @@ int spictrl_init3(struct drvmgr_dev *dev) { struct spictrl_priv *priv; char prefix[32]; - char devName[32]; + char devName[48]; int rc; priv = (struct spictrl_priv *)dev->priv; diff --git a/bsps/shared/grlib/spw/grspw.c b/bsps/shared/grlib/spw/grspw.c index bf1c823568..80fb26370e 100644 --- a/bsps/shared/grlib/spw/grspw.c +++ b/bsps/shared/grlib/spw/grspw.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * This file contains the GRSPW SpaceWire Driver for LEON2 and LEON3. * * COPYRIGHT (c) 2006 * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -89,7 +108,7 @@ typedef struct { typedef struct { /* configuration parameters */ struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[49]; /* Device Name */ LEON3_SPACEWIRE_Regs_Map *regs; spw_config config; diff --git a/bsps/shared/grlib/spw/grspw_pkt.c b/bsps/shared/grlib/spw/grspw_pkt.c index ca8767eeae..b0707078b7 100644 --- a/bsps/shared/grlib/spw/grspw_pkt.c +++ b/bsps/shared/grlib/spw/grspw_pkt.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * Cobham Gaisler GRSPW/GRSPW2 SpaceWire Kernel Library Interface for RTEMS. * @@ -7,9 +9,26 @@ * COPYRIGHT (c) 2011 * Cobham Gaisler AB * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/spw/grspw_router.c b/bsps/shared/grlib/spw/grspw_router.c index 9a31c3b49a..eeddf85b6d 100644 --- a/bsps/shared/grlib/spw/grspw_router.c +++ b/bsps/shared/grlib/spw/grspw_router.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRSPW ROUTER APB-Register Driver. * * COPYRIGHT (c) 2010-2017. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/spw/spwtdp.c b/bsps/shared/grlib/spw/spwtdp.c index df74675355..c24ceccddf 100644 --- a/bsps/shared/grlib/spw/spwtdp.c +++ b/bsps/shared/grlib/spw/spwtdp.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* SPWTDP - SpaceWire Time Distribution Protocol. The driver provides * device discovery and interrupt management. * * COPYRIGHT (c) 2017. * Cobham Gaisler AB * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * 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. * */ diff --git a/bsps/shared/grlib/stat/l4stat.c b/bsps/shared/grlib/stat/l4stat.c index d6e5712b00..6261bd7a96 100644 --- a/bsps/shared/grlib/stat/l4stat.c +++ b/bsps/shared/grlib/stat/l4stat.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* L4STAT APB-Register Driver. * * COPYRIGHT (c) 2017. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <rtems.h> diff --git a/bsps/shared/grlib/time/grctm.c b/bsps/shared/grlib/time/grctm.c index 038c3ddf34..474d7189c0 100644 --- a/bsps/shared/grlib/time/grctm.c +++ b/bsps/shared/grlib/time/grctm.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRCTM - CCSDS Time Manager - register driver interface. * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <drvmgr/drvmgr.h> diff --git a/bsps/shared/grlib/time/spwcuc.c b/bsps/shared/grlib/time/spwcuc.c index d742f2d225..3c80653d56 100644 --- a/bsps/shared/grlib/time/spwcuc.c +++ b/bsps/shared/grlib/time/spwcuc.c @@ -1,12 +1,31 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* SPWCUC - SpaceWire - CCSDS unsegmented Code Transfer Protocol GRLIB core * register driver interface. * * COPYRIGHT (c) 2009. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <drvmgr/drvmgr.h> diff --git a/bsps/shared/grlib/tmtc/grtc.c b/bsps/shared/grlib/tmtc/grtc.c index f734f2ed36..4cb9a06ed0 100644 --- a/bsps/shared/grlib/tmtc/grtc.c +++ b/bsps/shared/grlib/tmtc/grtc.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRTC Telecommand decoder driver * * COPYRIGHT (c) 2007. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -222,7 +241,7 @@ struct grtc_frame_pool { struct grtc_priv { struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[52]; /* Device Name */ struct grtc_regs *regs; /* TC Hardware Register MAP */ int irq; /* IRQ number of TC core */ SPIN_DECLARE(devlock); /* spin-lock of registers */ diff --git a/bsps/shared/grlib/tmtc/grtm.c b/bsps/shared/grlib/tmtc/grtm.c index 43476aaaad..a1b2a546fe 100644 --- a/bsps/shared/grlib/tmtc/grtm.c +++ b/bsps/shared/grlib/tmtc/grtm.c @@ -1,11 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* GRTM CCSDS Telemetry Encoder driver * * COPYRIGHT (c) 2007. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> @@ -348,7 +367,7 @@ struct grtm_ring { struct grtm_priv { struct drvmgr_dev *dev; /* Driver manager device */ - char devName[32]; /* Device Name */ + char devName[52]; /* Device Name */ struct grtm_regs *regs; int irq; int minor; diff --git a/bsps/shared/grlib/uart/apbuart_cons.c b/bsps/shared/grlib/uart/apbuart_cons.c index c35020e53f..a8b4eaaf88 100644 --- a/bsps/shared/grlib/uart/apbuart_cons.c +++ b/bsps/shared/grlib/uart/apbuart_cons.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* This file contains the driver for the GRLIB APBUART serial port. The driver * is implemented by using the cons.c console layer. Interrupt/Polling/Task * driven mode can be configured using driver resources: @@ -11,9 +13,26 @@ * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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. */ /******************* Driver manager interface ***********************/ @@ -28,11 +47,15 @@ #include <grlib/ambapp_bus.h> #include <grlib/apbuart.h> #include <grlib/ambapp.h> -#include <grlib/grlib.h> +#include <grlib/io.h> #include <grlib/cons.h> #include <rtems/termiostypes.h> #include <grlib/apbuart_cons.h> +#ifdef LEON3 +#include <bsp/leon3.h> +#endif + /*#define DEBUG 1 */ #ifdef DEBUG @@ -41,12 +64,6 @@ #define DBG(x...) #endif -/* LEON3 Low level transmit/receive functions provided by debug-uart code */ -#ifdef LEON3 -#include <leon.h> -extern struct apbuart_regs *leon3_debug_uart; /* The debug UART */ -#endif - /* Probed hardware capabilities */ enum { CAP_FIFO = 0x01, /* FIFO available */ @@ -55,9 +72,9 @@ enum { struct apbuart_priv { struct console_dev condev; struct drvmgr_dev *dev; - struct apbuart_regs *regs; + apbuart *regs; struct rtems_termios_tty *tty; - char devName[32]; + char devName[52]; volatile int sending; int mode; int cap; @@ -194,18 +211,23 @@ static const rtems_termios_device_handler handler_polled = { * can select appropriate routines for the hardware. probecap() return value * is a CAP_ bitmask. */ -static int probecap(struct apbuart_regs *regs) +static int probecap(apbuart *regs) { int cap = 0; + uint32_t ctrl; /* Probe FIFO */ - if (regs->ctrl & APBUART_CTRL_FA) { + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_FA) { cap |= CAP_FIFO; /* Probe RX delayed interrupt */ - regs->ctrl |= APBUART_CTRL_DI; - if (regs->ctrl & APBUART_CTRL_DI) { - regs->ctrl &= ~APBUART_CTRL_DI; + ctrl |= APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_DI) { + ctrl &= ~APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); cap |= CAP_DI; } } @@ -222,6 +244,7 @@ int apbuart_init1(struct drvmgr_dev *dev) char prefix[32]; unsigned int db; static int first_uart = 1; + uint32_t ctrl; /* The default operation in AMP is to use APBUART[0] for CPU[0], * APBUART[1] for CPU[1] and so on. The remaining UARTs is not used @@ -250,10 +273,12 @@ int apbuart_init1(struct drvmgr_dev *dev) if (ambadev == NULL) return -1; pnpinfo = &ambadev->info; - priv->regs = (struct apbuart_regs *)pnpinfo->apb_slv->start; + priv->regs = (apbuart *)pnpinfo->apb_slv->start; /* Clear HW regs, leave baudrate register as it is */ - priv->regs->status = 0; + grlib_store_32(&priv->regs->status, 0); + + ctrl = grlib_load_32(&priv->regs->ctrl); /* leave Transmitter/receiver if this is the RTEMS debug UART (assume * it has been setup by boot loader). @@ -261,10 +286,10 @@ int apbuart_init1(struct drvmgr_dev *dev) db = 0; #ifdef LEON3 if (priv->regs == leon3_debug_uart) { - db = priv->regs->ctrl & (APBUART_CTRL_RE | - APBUART_CTRL_TE | - APBUART_CTRL_PE | - APBUART_CTRL_PS); + db = ctrl & (APBUART_CTRL_RE | + APBUART_CTRL_TE | + APBUART_CTRL_PE | + APBUART_CTRL_PS); } #endif /* Let UART debug tunnelling be untouched if Flow-control is set. @@ -274,12 +299,12 @@ int apbuart_init1(struct drvmgr_dev *dev) * guess that we are debugging if FL is already set, the debugger set * either LB or DB depending on UART capabilities. */ - if (priv->regs->ctrl & APBUART_CTRL_FL) { - db |= priv->regs->ctrl & (APBUART_CTRL_DB | + if (ctrl & APBUART_CTRL_FL) { + db |= ctrl & (APBUART_CTRL_DB | APBUART_CTRL_LB | APBUART_CTRL_FL); } - priv->regs->ctrl = db; + grlib_store_32(&priv->regs->ctrl, db); priv->cap = probecap(priv->regs); @@ -368,12 +393,13 @@ static int apbuart_info( sprintf(buf, "FS Name: %s", priv->condev.fsname); print_line(p, buf); } - sprintf(buf, "STATUS REG: 0x%x", priv->regs->status); + sprintf(buf, "STATUS REG: 0x%x", grlib_load_32(&priv->regs->status)); print_line(p, buf); - sprintf(buf, "CTRL REG: 0x%x", priv->regs->ctrl); + sprintf(buf, "CTRL REG: 0x%x", grlib_load_32(&priv->regs->ctrl)); print_line(p, buf); sprintf(buf, "SCALER REG: 0x%x baud rate %d", - priv->regs->scaler, apbuart_get_baud(priv)); + grlib_load_32(&priv->regs->scaler), + apbuart_get_baud(priv)); print_line(p, buf); return DRVMGR_OK; @@ -388,6 +414,8 @@ static bool first_open( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; + uint32_t ctrl; uart->tty = tty; @@ -399,11 +427,11 @@ static bool first_open( } /* Enable TX/RX */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; if (uart->mode != TERMIOS_POLLED) { int ret; - uint32_t ctrl; /* Register interrupt and enable it */ ret = drvmgr_interrupt_register( @@ -416,15 +444,15 @@ static bool first_open( uart->sending = 0; /* Turn on RX interrupts */ - ctrl = uart->regs->ctrl; ctrl |= APBUART_CTRL_RI; if (uart->cap & CAP_DI) { /* Use RX FIFO interrupt only if delayed interrupt available. */ ctrl |= (APBUART_CTRL_DI | APBUART_CTRL_RF); } - uart->regs->ctrl = ctrl; } + grlib_store_32(®s->ctrl, ctrl); + return true; } @@ -435,13 +463,16 @@ static void last_close( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; if (uart->mode != TERMIOS_POLLED) { /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= - ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ @@ -449,8 +480,8 @@ static void last_close( /* Wait until all data has been sent */ } while ( - (uart->regs->ctrl & APBUART_CTRL_TE) && - !(uart->regs->status & APBUART_STATUS_TS) + (grlib_load_32(®s->ctrl) & APBUART_CTRL_TE) && + !(grlib_load_32(®s->status) & APBUART_STATUS_TS) ) { /* Wait until all data has left shift register */ } @@ -461,8 +492,11 @@ static void last_close( #ifdef LEON3 /* Disable TX/RX if not used for DEBUG */ - if (uart->regs != leon3_debug_uart) - uart->regs->ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + if (regs != leon3_debug_uart) { + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + grlib_store_32(®s->ctrl, ctrl); + } #endif } @@ -478,10 +512,11 @@ static int read_task(rtems_termios_device_context *base) { rtems_interrupt_lock_context lock_context; struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int cnt; char buf[33]; struct rtems_termios_tty *tty; + uint32_t ctrl; uint32_t ctrl_add; ctrl_add = APBUART_CTRL_RI; @@ -492,10 +527,10 @@ static int read_task(rtems_termios_device_context *base) do { cnt = 0; while ( - (regs->status & APBUART_STATUS_DR) && + (grlib_load_32(®s->status) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { @@ -509,9 +544,11 @@ static int read_task(rtems_termios_device_context *base) * afterwards. */ rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl |= ctrl_add; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= ctrl_add; + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); - } while (regs->status & APBUART_STATUS_DR); + } while (grlib_load_32(®s->status) & APBUART_STATUS_DR); return EOF; } @@ -522,7 +559,7 @@ int apbuart_get_baud(struct apbuart_priv *uart) unsigned int scaler; /* Get current scaler setting */ - scaler = uart->regs->scaler; + scaler = grlib_load_32(&uart->regs->scaler); /* Get APBUART core frequency */ drvmgr_freq_get(uart->dev, DEV_APB_SLV, &core_clk_hz); @@ -557,7 +594,7 @@ static bool set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch(t->c_cflag & (PARENB|PARODD)){ case (PARENB|PARODD): @@ -584,7 +621,7 @@ static bool set_attributes( ctrl &= ~APBUART_CTRL_FL; /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -598,7 +635,7 @@ static bool set_attributes( scaler = (((core_clk_hz*10)/(baud*8))-5)/10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -618,7 +655,7 @@ static void get_attributes( t->c_cflag |= CS8; /* Read out current parity */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); if (ctrl & APBUART_CTRL_PE) { if (ctrl & APBUART_CTRL_PS) t->c_cflag |= PARENB|PARODD; /* Odd parity */ @@ -654,11 +691,11 @@ static void write_interrupt( ) { struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int sending; unsigned int ctrl; - ctrl = regs->ctrl; + ctrl = grlib_load_32(®s->ctrl); if (len > 0) { /* @@ -666,28 +703,30 @@ static void write_interrupt( * we can tell termios later. */ /* Enable TX interrupt (interrupt is edge-triggered) */ - regs->ctrl = ctrl | APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); if (ctrl & APBUART_CTRL_FA) { /* APBUART with FIFO.. Fill as many as FIFO allows */ sending = 0; while ( - ((regs->status & APBUART_STATUS_TF) == 0) && + ((grlib_load_32(®s->status) & APBUART_STATUS_TF) == 0) && (sending < len) ) { - regs->data = *buf; + grlib_store_32(®s->data, *buf); buf++; sending++; } } else { /* start UART TX, this will result in an interrupt when done */ - regs->data = *buf; + grlib_store_32(®s->data, *buf); sending = 1; } } else { /* No more to send, disable TX interrupts */ - regs->ctrl = ctrl & ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); /* Tell close that we sent everything */ sending = 0; @@ -703,21 +742,24 @@ static void apbuart_cons_isr(void *arg) rtems_termios_device_context *base; struct console_dev *condev = rtems_termios_get_device_context(tty); struct apbuart_priv *uart = condev_get_priv(condev); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; unsigned int status; char buf[33]; int cnt; if (uart->mode == TERMIOS_TASK_DRIVEN) { - if ((status = regs->status) & APBUART_STATUS_DR) { + if ((status = grlib_load_32(®s->status)) & APBUART_STATUS_DR) { rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ base = rtems_termios_get_device_context(tty); rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl &= + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /* Activate termios RX daemon task */ rtems_termios_rxirq_occured(tty); @@ -730,10 +772,10 @@ static void apbuart_cons_isr(void *arg) */ cnt = 0; while ( - ((status=regs->status) & APBUART_STATUS_DR) && + ((status=grlib_load_32(®s->status)) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { diff --git a/bsps/shared/grlib/uart/apbuart_polled.c b/bsps/shared/grlib/uart/apbuart_polled.c index 87325d8951..84c31795df 100644 --- a/bsps/shared/grlib/uart/apbuart_polled.c +++ b/bsps/shared/grlib/uart/apbuart_polled.c @@ -1,45 +1,72 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDeviceGRLIBAPBUART + * + * @brief This source file contains the implementation of + * apbuart_outbyte_wait(), apbuart_outbyte_polled(), and + * apbuart_inbyte_nonblocking(). + */ + /* - * COPYRIGHT (c) 2010. - * Cobham Gaisler AB. + * Copyright (C) 2021 embedded brains GmbH & Co. KG + * + * 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. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/apbuart.h> +#include <grlib/io.h> -#include <rtems/score/cpuimpl.h> +#include <rtems/dev/io.h> -void apbuart_outbyte_wait(const struct apbuart_regs *regs) +void apbuart_outbyte_wait( const apbuart *regs ) { - while ( (regs->status & APBUART_STATUS_TE) == 0 ) { - /* Lower bus utilization while waiting for UART */ - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); + while ( ( grlib_load_32( ®s->status ) & APBUART_STATUS_TE ) == 0 ) { + _IO_Relax(); } } -void apbuart_outbyte_polled(struct apbuart_regs *regs, char ch) +void apbuart_outbyte_polled( apbuart *regs, char ch) { - apbuart_outbyte_wait(regs); - regs->data = (uint8_t) ch; + apbuart_outbyte_wait( regs ); + grlib_store_32( ®s->data, (uint8_t) ch ); } -int apbuart_inbyte_nonblocking(struct apbuart_regs *regs) +int apbuart_inbyte_nonblocking( apbuart *regs ) { - /* Clear errors */ - regs->status = ~APBUART_STATUS_ERR; + uint32_t status; + + status = grlib_load_32( ®s->status ); + + /* Clear errors, writes to non-error flags are ignored */ + status &= ~( APBUART_STATUS_FE | APBUART_STATUS_PE | APBUART_STATUS_OV | + APBUART_STATUS_BR ); + grlib_store_32( ®s->status, status ); - if ((regs->status & APBUART_STATUS_DR) == 0) { + if ( ( status & APBUART_STATUS_DR ) == 0 ) { return -1; } - return (uint8_t) regs->data; + return (int) APBUART_DATA_DATA_GET( grlib_load_32( ®s->data ) ); } diff --git a/bsps/shared/grlib/uart/apbuart_termios.c b/bsps/shared/grlib/uart/apbuart_termios.c index 9014a1c735..8b5ccd67f6 100644 --- a/bsps/shared/grlib/uart/apbuart_termios.c +++ b/bsps/shared/grlib/uart/apbuart_termios.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* * COPYRIGHT (c) 1989-1998. * On-Line Applications Research Corporation (OAR). @@ -6,13 +8,31 @@ * COPYRIGHT (c) 2004. * Gaisler Research. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <grlib/apbuart_termios.h> #include <grlib/apbuart.h> +#include <grlib/io.h> #include <bsp.h> static void apbuart_isr(void *arg) @@ -23,9 +43,9 @@ static void apbuart_isr(void *arg) char data; /* Get all received characters */ - while ((status=uart->regs->status) & APBUART_STATUS_DR) { + while ((status=grlib_load_32(&uart->regs->status)) & APBUART_STATUS_DR) { /* Data has arrived, get new data */ - data = uart->regs->data; + data = (char)grlib_load_32(&uart->regs->data); /* Tell termios layer about new character */ rtems_termios_enqueue_raw_characters(tty, &data, 1); @@ -33,7 +53,7 @@ static void apbuart_isr(void *arg) if ( (status & APBUART_STATUS_TE) - && (uart->regs->ctrl & APBUART_CTRL_TI) != 0 + && (grlib_load_32(&uart->regs->ctrl) & APBUART_CTRL_TI) != 0 ) { /* write_interrupt will get called from this function */ rtems_termios_dequeue_characters(tty, 1); @@ -48,23 +68,27 @@ static void apbuart_write_support( { struct apbuart_context *uart = (struct apbuart_context *) base; int sending; + uint32_t ctrl; + + ctrl = grlib_load_32(&uart->regs->ctrl); if (len > 0) { /* Enable TX interrupt (interrupt is edge-triggered) */ - uart->regs->ctrl |= APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; /* start UART TX, this will result in an interrupt when done */ - uart->regs->data = *buf; + grlib_store_32(&uart->regs->data, (uint8_t)*buf); sending = 1; } else { /* No more to send, disable TX interrupts */ - uart->regs->ctrl &= ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; /* Tell close that we sent everything */ sending = 0; } + grlib_store_32(&uart->regs->ctrl, ctrl); uart->sending = sending; } @@ -115,7 +139,7 @@ static bool apbuart_set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch (t->c_cflag & (PARENB|PARODD)) { case (PARENB|PARODD): @@ -143,7 +167,7 @@ static bool apbuart_set_attributes( } /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -154,7 +178,7 @@ static bool apbuart_set_attributes( scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -165,7 +189,8 @@ static void apbuart_set_best_baud( struct termios *term ) { - uint32_t baud = (uart->freq_hz * 10) / ((uart->regs->scaler * 10 + 5) * 8); + uint32_t baud = (uart->freq_hz * 10) / + ((grlib_load_32(&uart->regs->scaler) * 10 + 5) * 8); rtems_termios_set_best_baud(term, baud); } @@ -178,12 +203,15 @@ static bool apbuart_first_open_polled( ) { struct apbuart_context *uart = (struct apbuart_context *) base; + uint32_t ctrl; apbuart_set_best_baud(uart, term); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -197,6 +225,7 @@ static bool apbuart_first_open_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_status_code sc; + uint32_t ctrl; apbuart_set_best_baud(uart, term); @@ -210,11 +239,13 @@ static bool apbuart_first_open_interrupt( uart->sending = 0; /* Enable Receiver and transmitter and Turn on RX interrupts */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | - APBUART_CTRL_RI; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -227,10 +258,13 @@ static void apbuart_last_close_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= ~(APBUART_CTRL_RI); + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl &= ~APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ diff --git a/bsps/shared/grlib/uart/cons.c b/bsps/shared/grlib/uart/cons.c index 9c20193b3c..7db93247a8 100644 --- a/bsps/shared/grlib/uart/cons.c +++ b/bsps/shared/grlib/uart/cons.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /* This file contains the TTY driver for the serial ports. The driver * is layered so that different UART hardware can be used. It is implemented * using the Driver Manager. @@ -7,9 +9,26 @@ * COPYRIGHT (c) 2010. * Cobham Gaisler AB. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * 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 <bsp.h> diff --git a/bsps/shared/irq/irq-affinity.c b/bsps/shared/irq/irq-affinity.c index c21468077b..7e9250a948 100644 --- a/bsps/shared/irq/irq-affinity.c +++ b/bsps/shared/irq/irq-affinity.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_get_affinity() and rtems_interrupt_set_affinity(). */ /* - * Copyright (C) 2017, 2022 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2017, 2022 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,7 +36,6 @@ #include <bsp/irq-generic.h> -#include <rtems/score/processormask.h> #include <rtems/score/smpimpl.h> rtems_status_code rtems_interrupt_set_affinity( diff --git a/bsps/shared/irq/irq-default-handler.c b/bsps/shared/irq/irq-default-handler.c index 666d48aaa8..3f765a2a64 100644 --- a/bsps/shared/irq/irq-default-handler.c +++ b/bsps/shared/irq/irq-default-handler.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the default implementation of * bsp_interrupt_handler_default(). */ /* - * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-default.c b/bsps/shared/irq/irq-default.c index bd93bd72c6..7210235aa6 100644 --- a/bsps/shared/irq/irq-default.c +++ b/bsps/shared/irq/irq-default.c @@ -3,7 +3,7 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the default implementation of * bsp_interrupt_vector_enable(), bsp_interrupt_vector_disable(), and @@ -11,7 +11,7 @@ */ /* - * Copyright (C) 2019 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2019 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-enable-disable.c b/bsps/shared/irq/irq-enable-disable.c index 75d3d5ec46..2e0a675b85 100644 --- a/bsps/shared/irq/irq-enable-disable.c +++ b/bsps/shared/irq/irq-enable-disable.c @@ -3,7 +3,7 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_get_attributes(), rtems_interrupt_vector_is_enabled(), @@ -11,7 +11,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-entry-remove.c b/bsps/shared/irq/irq-entry-remove.c index 3e5fd33fbe..d2f290d595 100644 --- a/bsps/shared/irq/irq-entry-remove.c +++ b/bsps/shared/irq/irq-entry-remove.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_entry_remove() and bsp_interrupt_entry_remove(). */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,8 +46,8 @@ void bsp_interrupt_entry_remove( rtems_interrupt_entry *first; rtems_interrupt_entry *entry_next; - index = bsp_interrupt_handler_index( vector ); - first = bsp_interrupt_handler_table[ index ]; + index = bsp_interrupt_dispatch_index( vector ); + first = *bsp_interrupt_get_dispatch_table_slot( index ); entry_next = entry->next; if ( entry == first && entry_next == NULL ) { @@ -60,7 +60,7 @@ void bsp_interrupt_entry_remove( #endif bsp_interrupt_set_handler_unique( index, false ); #if defined(BSP_INTERRUPT_USE_INDEX_TABLE) - bsp_interrupt_handler_index_table[ vector ] = 0; + bsp_interrupt_dispatch_index_table[ vector ] = 0; #endif } diff --git a/bsps/shared/irq/irq-generic.c b/bsps/shared/irq/irq-generic.c index dac1ca4209..b6238025b7 100644 --- a/bsps/shared/irq/irq-generic.c +++ b/bsps/shared/irq/irq-generic.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the generic interrupt controller support * implementation. */ /* - * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,39 +35,41 @@ */ #include <bsp/irq-generic.h> -#include <bsp/fatal.h> - -#include <stdlib.h> #include <rtems/malloc.h> #ifdef BSP_INTERRUPT_USE_INDEX_TABLE - bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table + bsp_interrupt_dispatch_index_type bsp_interrupt_dispatch_index_table [BSP_INTERRUPT_VECTOR_COUNT]; #endif rtems_interrupt_entry * -bsp_interrupt_handler_table[ BSP_INTERRUPT_HANDLER_TABLE_SIZE ]; +bsp_interrupt_dispatch_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ]; + +RTEMS_WEAK rtems_interrupt_entry **bsp_interrupt_get_dispatch_table_slot( + rtems_vector_number index +) +{ + return &bsp_interrupt_dispatch_table[ index ]; +} /* The last entry indicates if everything is initialized */ uint8_t bsp_interrupt_handler_unique_table - [ ( BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1 ) / 8 ]; + [ ( BSP_INTERRUPT_DISPATCH_TABLE_SIZE + 7 + 1 ) / 8 ]; static inline void bsp_interrupt_set_initialized(void) { - bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE, true); + bsp_interrupt_set_handler_unique(BSP_INTERRUPT_DISPATCH_TABLE_SIZE, true); } #if defined(BSP_INTERRUPT_USE_INDEX_TABLE) -static inline rtems_vector_number bsp_interrupt_allocate_handler_index( - rtems_vector_number vector -) +static inline rtems_vector_number bsp_interrupt_allocate_handler_index( void ) { rtems_vector_number i; /* The first entry will remain empty */ - for ( i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i ) { - if ( bsp_interrupt_handler_table[ i ] == NULL ) { + for ( i = 1; i < BSP_INTERRUPT_DISPATCH_TABLE_SIZE; ++i ) { + if ( bsp_interrupt_dispatch_table[ i ] == NULL ) { break; } } @@ -91,9 +93,9 @@ void bsp_interrupt_spurious( rtems_vector_number vector ) * In order to get the last written pointer value to the first entry, we have * to carry out an atomic read-modify-write operation. */ - ptr = (Atomic_Uintptr *) &bsp_interrupt_handler_table[ - bsp_interrupt_handler_index( vector ) - ]; + ptr = (Atomic_Uintptr *) bsp_interrupt_get_dispatch_table_slot( + bsp_interrupt_dispatch_index( vector ) + ); first = (rtems_interrupt_entry *) _Atomic_Fetch_add_uintptr( ptr, 0, ATOMIC_ORDER_ACQUIRE ); @@ -142,9 +144,9 @@ rtems_interrupt_entry *bsp_interrupt_entry_find( rtems_interrupt_entry *entry; bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) ); - index = bsp_interrupt_handler_index( vector ); - *previous_next = &bsp_interrupt_handler_table[ index ]; - entry = bsp_interrupt_handler_table[ index ]; + index = bsp_interrupt_dispatch_index( vector ); + *previous_next = bsp_interrupt_get_dispatch_table_slot( index ); + entry = **previous_next; while ( entry != NULL ) { if ( entry->handler == routine && entry->arg == arg ) { @@ -173,9 +175,9 @@ static rtems_status_code bsp_interrupt_entry_install_first( rtems_vector_number index; #ifdef BSP_INTERRUPT_USE_INDEX_TABLE - index = bsp_interrupt_allocate_handler_index( vector ); + index = bsp_interrupt_allocate_handler_index(); - if ( index == BSP_INTERRUPT_HANDLER_TABLE_SIZE ) { + if ( index == BSP_INTERRUPT_DISPATCH_TABLE_SIZE ) { /* Handler table is full */ return RTEMS_NO_MEMORY; } @@ -184,10 +186,10 @@ static rtems_status_code bsp_interrupt_entry_install_first( #endif #ifdef BSP_INTERRUPT_USE_INDEX_TABLE - bsp_interrupt_handler_index_table[ vector ] = index; + bsp_interrupt_dispatch_index_table[ vector ] = index; #endif bsp_interrupt_entry_store_release( - &bsp_interrupt_handler_table[ index ], + bsp_interrupt_get_dispatch_table_slot( index ), entry ); @@ -219,8 +221,8 @@ static rtems_status_code bsp_interrupt_entry_install( return RTEMS_INVALID_NUMBER; } - index = bsp_interrupt_handler_index( vector ); - first = bsp_interrupt_handler_table[ index ]; + index = bsp_interrupt_dispatch_index( vector ); + first = *bsp_interrupt_get_dispatch_table_slot( index ); if ( first == NULL ) { return bsp_interrupt_entry_install_first( vector, options, entry ); diff --git a/bsps/shared/irq/irq-handler-install.c b/bsps/shared/irq/irq-handler-install.c index 2474d792e6..18c4cbf3a7 100644 --- a/bsps/shared/irq/irq-handler-install.c +++ b/bsps/shared/irq/irq-handler-install.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the rtems_interrupt_handler_install() * implementation. */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-handler-iterate.c b/bsps/shared/irq/irq-handler-iterate.c index 8bb29191fd..770318cc68 100644 --- a/bsps/shared/irq/irq-handler-iterate.c +++ b/bsps/shared/irq/irq-handler-iterate.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_handler_iterate(). */ /* - * Copyright (C) 2017, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2017, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -56,10 +56,10 @@ rtems_status_code rtems_interrupt_handler_iterate( return sc; } - index = bsp_interrupt_handler_index( vector ); + index = bsp_interrupt_dispatch_index( vector ); + entry = *bsp_interrupt_get_dispatch_table_slot( index ); options = bsp_interrupt_is_handler_unique( index ) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED; - entry = bsp_interrupt_handler_table[ index ]; while ( entry != NULL ) { ( *routine )( arg, entry->info, options, entry->handler, entry->arg ); diff --git a/bsps/shared/irq/irq-handler-remove.c b/bsps/shared/irq/irq-handler-remove.c index cb32ba3b7c..a01af46455 100644 --- a/bsps/shared/irq/irq-handler-remove.c +++ b/bsps/shared/irq/irq-handler-remove.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_handler_remove(). */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-info.c b/bsps/shared/irq/irq-info.c index a52465ef09..c4cbd96acf 100644 --- a/bsps/shared/irq/irq-info.c +++ b/bsps/shared/irq/irq-info.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * bsp_interrupt_report() and bsp_interrupt_report_with_plugin(). */ /* - * Copyright (C) 2008, 2010 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2010 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-legacy.c b/bsps/shared/irq/irq-legacy.c index 649b850095..ee4d11cd87 100644 --- a/bsps/shared/irq/irq-legacy.c +++ b/bsps/shared/irq/irq-legacy.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the legacy interrupt controller support * implementation. */ /* - * Copyright (C) 2008, 2009 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2009 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-lock.c b/bsps/shared/irq/irq-lock.c index 58b7020a3b..8090ade84e 100644 --- a/bsps/shared/irq/irq-lock.c +++ b/bsps/shared/irq/irq-lock.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * bsp_interrupt_lock() and bsp_interrupt_unlock(). */ /* - * Copyright (C) 2008, 2018 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-raise-clear.c b/bsps/shared/irq/irq-raise-clear.c index 93e414b2d1..e06f79658b 100644 --- a/bsps/shared/irq/irq-raise-clear.c +++ b/bsps/shared/irq/irq-raise-clear.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the implementation of * rtems_interrupt_clear(). */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-record.c b/bsps/shared/irq/irq-record.c new file mode 100644 index 0000000000..15bb20132d --- /dev/null +++ b/bsps/shared/irq/irq-record.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSImplClassicIntr + * + * @brief This source file contains the implementation of the interrupt event + * recording support. + */ + +/* + * Copyright (C) 2022 embedded brains GmbH & Co. KG + * + * 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 <bsp/irq-generic.h> + +#include <rtems/record.h> + +/* The regular interrupt entries are registered in this table */ +static rtems_interrupt_entry * +_Record_Interrupt_dispatch_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ]; + +/* + * Provide one interrupt entry for the _Record_Interrupt_handler() interrupt + * dispatch wrapper for each interrupt vector. + */ +static rtems_interrupt_entry +_Record_Interrupt_entry_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ]; + +rtems_interrupt_entry **bsp_interrupt_get_dispatch_table_slot( + rtems_vector_number index +) +{ + return &_Record_Interrupt_dispatch_table[ index ]; +} + +static void _Record_Interrupt_handler( void *arg ) +{ + uintptr_t vector; + rtems_interrupt_entry *entry; + + vector = (uintptr_t) arg; + rtems_record_produce( RTEMS_RECORD_INTERRUPT_ENTRY, vector ); + + entry = bsp_interrupt_entry_load_acquire( + &_Record_Interrupt_dispatch_table[ vector ] + ); + + if ( RTEMS_PREDICT_TRUE( entry != NULL ) ) { + bsp_interrupt_dispatch_entries( entry ); + } else { +#if defined(RTEMS_SMP) + bsp_interrupt_spurious( vector ); +#else + bsp_interrupt_handler_default( vector ); +#endif + } + + rtems_record_produce( RTEMS_RECORD_INTERRUPT_EXIT, vector ); +} + +void _Record_Interrupt_initialize( void ) +{ + uintptr_t i; + + /* + * Let each interrupt dispatch table slot reference the + * _Record_Interrupt_handler() interrupt dispatch wrapper. + */ + for ( i = 0; i < BSP_INTERRUPT_DISPATCH_TABLE_SIZE; ++i ) { + _Record_Interrupt_entry_table[ i ].handler = _Record_Interrupt_handler; + _Record_Interrupt_entry_table[ i ].arg = (void *) i; + bsp_interrupt_dispatch_table[ i ] = &_Record_Interrupt_entry_table[ i ]; + } +} diff --git a/bsps/shared/irq/irq-server.c b/bsps/shared/irq/irq-server.c index 8b9d82eb29..bac54316d1 100644 --- a/bsps/shared/irq/irq-server.c +++ b/bsps/shared/irq/irq-server.c @@ -3,13 +3,13 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the interrupt server implementation. */ /* - * Copyright (C) 2009, 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2009, 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-shell.c b/bsps/shared/irq/irq-shell.c index cf70f2ce1b..a56fa938cf 100644 --- a/bsps/shared/irq/irq-shell.c +++ b/bsps/shared/irq/irq-shell.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup bsp_interrupt + * @ingroup RTEMSImplClassicIntr * * @brief This source file contains the definition of * ::bsp_interrupt_shell_command. */ /* - * Copyright (C) 2009 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2009 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/rtems-version.c b/bsps/shared/rtems-version.c index b12504a1c9..aaac5a07f3 100644 --- a/bsps/shared/rtems-version.c +++ b/bsps/shared/rtems-version.c @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSImplClassic + * + * @brief This source file contains the implementation of + * rtems_board_support_package() and the definition of ::_RTEMS_version. + */ + /* * COPYRIGHT (c) 2003, Ralf Corsepius, Ulm, Germany. * COPYRIGHT (c) 2003, On-Line Applications Research Corporation (OAR). diff --git a/bsps/shared/start/bsp-fdt.c b/bsps/shared/start/bsp-fdt.c index 75a1ea41c9..79f31733e1 100644 --- a/bsps/shared/start/bsp-fdt.c +++ b/bsps/shared/start/bsp-fdt.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved. + * Copyright (C) 2015, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,6 +32,10 @@ #include <bsp/fdt.h> #include <bsp/linker-symbols.h> +#ifdef BSP_DTB_IS_SUPPORTED +#include BSP_DTB_HEADER_PATH +#endif + #ifndef BSP_FDT_IS_SUPPORTED #warning "BSP FDT support indication not defined" #endif @@ -76,5 +80,9 @@ void bsp_fdt_copy(const void *src) const void *bsp_fdt_get(void) { +#ifdef BSP_DTB_IS_SUPPORTED + return system_dtb; +#else return &bsp_fdt_blob[0]; +#endif } diff --git a/bsps/shared/start/bsp-uboot-board-info.c b/bsps/shared/start/bsp-uboot-board-info.c index 29ae573fd7..39828b1a9d 100644 --- a/bsps/shared/start/bsp-uboot-board-info.c +++ b/bsps/shared/start/bsp-uboot-board-info.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2010, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2010, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/bspfatal-default.c b/bsps/shared/start/bspfatal-default.c index 28f492dee1..557a0960fa 100644 --- a/bsps/shared/start/bspfatal-default.c +++ b/bsps/shared/start/bspfatal-default.c @@ -1,5 +1,14 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSBSPsShared + * + * @brief This source file contains the implementation of + * bsp_fatal_extension(). + */ + /* * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -153,7 +162,7 @@ void bsp_fatal_extension( _Thread_Get_name( executing, name, sizeof( name ) ); printk( - "executing thread ID: 0x08%" PRIx32 "\n" + "executing thread ID: 0x%08" PRIx32 "\n" "executing thread name: %s\n", executing->Object.id, name diff --git a/bsps/shared/start/bspgetworkarea-default.c b/bsps/shared/start/bspgetworkarea-default.c index 5686b013f9..5f956b124f 100644 --- a/bsps/shared/start/bspgetworkarea-default.c +++ b/bsps/shared/start/bspgetworkarea-default.c @@ -12,7 +12,7 @@ */ /* - * Copyright (C) 2011, 2019 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2011, 2019 embedded brains GmbH & Co. KG * * Copyright (C) 1989, 2009 On-Line Applications Research Corporation (OAR) * @@ -39,7 +39,6 @@ */ #include <bsp.h> -#include <bsp/bootcard.h> #if defined(HAS_UBOOT) && !defined(BSP_DISABLE_UBOOT_WORK_AREA_CONFIG) #define USE_UBOOT diff --git a/bsps/shared/start/gettargethash-default.c b/bsps/shared/start/gettargethash-default.c index 1647b01a66..28336b9f47 100644 --- a/bsps/shared/start/gettargethash-default.c +++ b/bsps/shared/start/gettargethash-default.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/mallocinitmulti.c b/bsps/shared/start/mallocinitmulti.c index ad04ea14ed..3d774ab65f 100644 --- a/bsps/shared/start/mallocinitmulti.c +++ b/bsps/shared/start/mallocinitmulti.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/mallocinitone.c b/bsps/shared/start/mallocinitone.c index 249f0b8e02..f590523ea1 100644 --- a/bsps/shared/start/mallocinitone.c +++ b/bsps/shared/start/mallocinitone.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/stackalloc.c b/bsps/shared/start/stackalloc.c index 1d2b0e6880..485753fad9 100644 --- a/bsps/shared/start/stackalloc.c +++ b/bsps/shared/start/stackalloc.c @@ -9,7 +9,7 @@ */ /* - * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved. + * Copyright (C) 2009, 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/wkspaceinitmulti.c b/bsps/shared/start/wkspaceinitmulti.c index 2a0d0b5806..8ca34c1bc5 100644 --- a/bsps/shared/start/wkspaceinitmulti.c +++ b/bsps/shared/start/wkspaceinitmulti.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/wkspaceinitone.c b/bsps/shared/start/wkspaceinitone.c index 91d007d100..a93edad962 100644 --- a/bsps/shared/start/wkspaceinitone.c +++ b/bsps/shared/start/wkspaceinitone.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/xil/VERSION b/bsps/shared/xil/VERSION new file mode 100644 index 0000000000..d94f574255 --- /dev/null +++ b/bsps/shared/xil/VERSION @@ -0,0 +1,20 @@ +The information in this file describes the source of files in +bsps/shared/xil/ and bsps/include/xil/. + +Import from: + +https://github.com/Xilinx/embeddedsw.git + +commit 8a89579489c88ea5acd23d7d439ac928659c26cf +Author: msreeram <manikanta.sreeram@xilinx.com> +AuthorDate: Wed Apr 6 23:24:38 2022 -0600 +Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com> +CommitDate: Fri Apr 8 16:47:15 2022 +0530 + + update license file for EmbeddedSW 2022.1 release + + Update license file for EmbeddedSW 2022.1 release + + Signed-off-by: Manikanta Sreeram <msreeram@xilinx.com> + + Acked-by : Meena Paleti <meena.paleti@xilinx.com> diff --git a/bsps/shared/xil/arm/ARMv8/xil_cache.c b/bsps/shared/xil/arm/ARMv8/xil_cache.c new file mode 100644 index 0000000000..aef64b310a --- /dev/null +++ b/bsps/shared/xil/arm/ARMv8/xil_cache.c @@ -0,0 +1,732 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_cache.c +* +* Contains required functions for the ARM cache functionality. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 5.0 pkp 05/29/14 First release +* 5.5 pkp 04/15/16 Updated the Xil_DCacheInvalidate, +* Xil_DCacheInvalidateLine and Xil_DCacheInvalidateRange +* functions description for proper explanation +* 6.2 pkp 01/22/17 Added support for EL1 non-secure +* 6.2 asa 01/31/17 The existing Xil_DCacheDisable API first flushes the +* D caches and then disables it. The problem with that is, +* potentially there will be a small window after the cache +* flush operation and before the we disable D caches where +* we might have valid data in cache lines. In such a +* scenario disabling the D cache can lead to unknown behavior. +* The ideal solution to this is to use assembly code for +* the complete API and avoid any memory accesses. But with +* that we will end up having a huge amount on assembly code +* which is not maintainable. Changes are done to use a mix +* of assembly and C code. All local variables are put in +* registers. Also function calls are avoided in the API to +* avoid using stack memory. +* These changes fix CR#966220. +* 6.2 mus 02/13/17 The new api Xil_ConfigureL1Prefetch is added to disable pre-fetching/configure +* the maximum number of outstanding data prefetches allowed in +* L1 cache system.It fixes CR#967864. +* 6.6 mus 02/27/18 Updated Xil_DCacheInvalidateRange and +* Xil_ICacheInvalidateRange APIs to change the data type of +* "cacheline" variable as "INTPTR", This change has been done +* to avoid the truncation of upper DDR addresses to 32 bit.It +* fixes CR#995581. +* 6.6 mus 03/15/18 By default CPUACTLR_EL1 is accessible only from EL3, it +* results into abort if accessed from EL1 non secure privilege +* level. Updated Xil_ConfigureL1Prefetch function to access +* CPUACTLR_EL1 only for EL3. +* 6.8 mn 08/01/18 Optimize the Xil_DCacheInvalidateRange() function to remove +* redundant operations +* 6.8 asa 09/15/18 Fix bug in the Xil_DCacheInvalidateRange API introduced while +* making optimizations in the previous patch. This change fixes +* CR-1008926. +* 7.0 mus 10/12/18 Updated Xil_DCacheInvalidateLine and Xil_DCacheInvalidateRange +* APIs to replace IVAC instruction with CIVAC. So that, these +* APIs will always do flush + invalidate in case of Cortexa53 as +* well as Cortexa72 processor. +* 7.1 mus 09/17/19 Xil_DCacheFlushRange and Xil_DCacheInvalidateRange are executing +* same functionality (clean + validate). Removed +* Xil_DCacheFlushRange function implementation and defined it as +* macro. Xil_DCacheFlushRange macro points to the +* Xil_DCacheInvalidateRange API to avoid code duplication. +* +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xil_io.h" +#include "xpseudo_asm.h" +#include "xparameters.h" +#include "xreg_cortexa53.h" +#include "xil_exception.h" +#include "bspconfig.h" + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */ + +/****************************************************************************/ +/** +* @brief Enable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheEnable(void) +{ + u32 CtrlReg; + + if (EL3 == 1) { + CtrlReg = mfcp(SCTLR_EL3); + } else if (EL1_NONSECURE == 1) { + CtrlReg = mfcp(SCTLR_EL1); + } else { + CtrlReg = 0U; + } + + /* enable caches only if they are disabled */ + if((CtrlReg & XREG_CONTROL_DCACHE_BIT) == 0X00000000U){ + + /* invalidate the Data cache */ + Xil_DCacheInvalidate(); + + CtrlReg |= XREG_CONTROL_DCACHE_BIT; + + if (EL3 == 1) { + /* enable the Data cache for el3*/ + mtcp(SCTLR_EL3,CtrlReg); + } else if (EL1_NONSECURE == 1) { + /* enable the Data cache for el1*/ + mtcp(SCTLR_EL1,CtrlReg); + } + } +} + +/****************************************************************************/ +/** +* @brief Disable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheDisable(void) +{ + register u32 CsidReg; + register u32 C7Reg; + register u32 LineSize; + register u32 NumWays; + register u32 Way; + register u32 WayIndex; + register u32 WayAdjust; + register u32 Set; + register u32 SetIndex; + register u32 NumSet; + register u32 CacheLevel; + + dsb(); + asm( + "mov x0, #0\n\t" +#if EL3==1 + "mrs x0, sctlr_el3 \n\t" + "and w0, w0, #0xfffffffb\n\t" + "msr sctlr_el3, x0\n\t" +#elif EL1_NONSECURE==1 + "mrs x0, sctlr_el1 \n\t" + "and w0, w0, #0xfffffffb\n\t" + "msr sctlr_el1, x0\n\t" +#endif + "dsb sy\n\t" + ); + + /* Number of level of cache*/ + CacheLevel = 0U; + /* Select cache level 0 and D cache in CSSR */ + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0x00000001U; + + /*Number of Set*/ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0x00000001U; + + WayAdjust = clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Flush all the cachelines */ + for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(CISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set = 0U; + Way += (0x00000001U << WayAdjust); + } + + /* Wait for Flush to complete */ + dsb(); + + /* Select cache level 1 and D cache in CSSR */ + CacheLevel += (0x00000001U << 1U); + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0x00000001U; + + /* Number of Sets */ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0x00000001U; + + WayAdjust=clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Flush all the cachelines */ + for (WayIndex =0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex =0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(CISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set=0U; + Way += (0x00000001U<<WayAdjust); + } + /* Wait for Flush to complete */ + dsb(); + + asm( +#if EL3==1 + "tlbi ALLE3\n\t" +#elif EL1_NONSECURE==1 + "tlbi VMALLE1\n\t" +#endif + "dsb sy\r\n" + "isb\n\t" + ); +} + +/****************************************************************************/ +/** +* @brief Invalidate the Data cache. The contents present in the cache are +* cleaned and invalidated. +* +* @return None. +* +* @note In Cortex-A53, functionality to simply invalid the cachelines +* is not present. Such operations are a problem for an environment +* that supports virtualisation. It would allow one OS to invalidate +* a line belonging to another OS. This could lead to the other OS +* crashing because of the loss of essential data. Hence, such +* operations are promoted to clean and invalidate which avoids such +* corruption. +* +****************************************************************************/ +void Xil_DCacheInvalidate(void) +{ + register u32 CsidReg, C7Reg; + u32 LineSize, NumWays; + u32 Way, WayIndex,WayAdjust, Set, SetIndex, NumSet, CacheLevel; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + + /* Number of level of cache*/ + + CacheLevel=0U; + /* Select cache level 0 and D cache in CSSR */ + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0X00000001U; + + /*Number of Set*/ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0X00000001U; + + WayAdjust = clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex =0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex =0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(ISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set = 0U; + Way += (0x00000001U << WayAdjust); + } + + /* Wait for invalidate to complete */ + dsb(); + + /* Select cache level 1 and D cache in CSSR */ + CacheLevel += (0x00000001U<<1U) ; + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0x00000001U; + + /* Number of Sets */ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0x00000001U; + + WayAdjust = clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(ISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set = 0U; + Way += (0x00000001U << WayAdjust); + } + /* Wait for invalidate to complete */ + dsb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate a Data cache line. The cacheline is cleaned and +* invalidated. +* +* @param adr: 64bit address of the data to be flushed. +* +* @return None. +* +* @note In Cortex-A53, functionality to simply invalid the cachelines +* is not present. Such operations are a problem for an environment +* that supports virtualisation. It would allow one OS to invalidate +* a line belonging to another OS. This could lead to the other OS +* crashing because of the loss of essential data. Hence, such +* operations are promoted to clean and invalidate which avoids such +* corruption. +* +****************************************************************************/ +void Xil_DCacheInvalidateLine(INTPTR adr) +{ + + u32 currmask; + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + /* Select cache level 0 and D cache in CSSR */ + mtcp(CSSELR_EL1,0x0); + mtcpdc(CIVAC,(adr & (~0x3F))); + /* Wait for invalidate to complete */ + dsb(); + /* Select cache level 1 and D cache in CSSR */ + mtcp(CSSELR_EL1,0x2); + mtcpdc(IVAC,(adr & (~0x3F))); + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the Data cache for the given address range. +* The cachelines present in the adderss range are cleaned and +* invalidated +* +* @param adr: 64bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +* @note In Cortex-A53, functionality to simply invalid the cachelines +* is not present. Such operations are a problem for an environment +* that supports virtualisation. It would allow one OS to invalidate +* a line belonging to another OS. This could lead to the other OS +* crashing because of the loss of essential data. Hence, such +* operations are promoted to clean and invalidate which avoids such +* corruption. +* +****************************************************************************/ +void Xil_DCacheInvalidateRange(INTPTR adr, INTPTR len) +{ + const INTPTR cacheline = 64U; + INTPTR end = adr + len; + adr = adr & (~0x3F); + u32 currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0U) { + while (adr < end) { + mtcpdc(CIVAC,adr); + adr += cacheline; + } + } + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheFlush(void) +{ + register u32 CsidReg, C7Reg; + u32 LineSize, NumWays; + u32 Way, WayIndex,WayAdjust, Set, SetIndex, NumSet, CacheLevel; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + + /* Number of level of cache*/ + + CacheLevel = 0U; + /* Select cache level 0 and D cache in CSSR */ + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0x00000001U; + + /*Number of Set*/ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0x00000001U; + + WayAdjust = clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Flush all the cachelines */ + for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(CISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set = 0U; + Way += (0x00000001U << WayAdjust); + } + + /* Wait for Flush to complete */ + dsb(); + + /* Select cache level 1 and D cache in CSSR */ + CacheLevel += (0x00000001U << 1U); + mtcp(CSSELR_EL1,CacheLevel); + isb(); + + CsidReg = mfcp(CCSIDR_EL1); + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + /* Number of Ways */ + NumWays = (CsidReg & 0x00001FFFU) >> 3U; + NumWays += 0x00000001U; + + /* Number of Sets */ + NumSet = (CsidReg >> 13U) & 0x00007FFFU; + NumSet += 0x00000001U; + + WayAdjust=clz(NumWays) - (u32)0x0000001FU; + + Way = 0U; + Set = 0U; + + /* Flush all the cachelines */ + for (WayIndex =0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex =0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set | CacheLevel; + mtcpdc(CISW,C7Reg); + Set += (0x00000001U << LineSize); + } + Set=0U; + Way += (0x00000001U<<WayAdjust); + } + /* Wait for Flush to complete */ + dsb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush a Data cache line. If the byte specified by the address (adr) +* is cached by the Data cache, the cacheline containing that byte is +* invalidated. If the cacheline is modified (dirty), the entire +* contents of the cacheline are written to system memory before the +* line is invalidated. +* +* @param adr: 64bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 6 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheFlushLine(INTPTR adr) +{ + u32 currmask; + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + /* Select cache level 0 and D cache in CSSR */ + mtcp(CSSELR_EL1,0x0); + mtcpdc(CIVAC,(adr & (~0x3F))); + /* Wait for flush to complete */ + dsb(); + /* Select cache level 1 and D cache in CSSR */ + mtcp(CSSELR_EL1,0x2); + mtcpdc(CIVAC,(adr & (~0x3F))); + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Enable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheEnable(void) +{ + u32 CtrlReg; + + if (EL3 == 1) { + CtrlReg = mfcp(SCTLR_EL3); + } else if (EL1_NONSECURE == 1) { + CtrlReg = mfcp(SCTLR_EL1); + } else { + CtrlReg = 0U; + } + + /* enable caches only if they are disabled */ + if((CtrlReg & XREG_CONTROL_ICACHE_BIT)==0x00000000U){ + /* invalidate the instruction cache */ + Xil_ICacheInvalidate(); + + CtrlReg |= XREG_CONTROL_ICACHE_BIT; + + if (EL3 == 1) { + /* enable the instruction cache for el3*/ + mtcp(SCTLR_EL3,CtrlReg); + } else if (EL1_NONSECURE == 1) { + /* enable the instruction cache for el1*/ + mtcp(SCTLR_EL1,CtrlReg); + } + } +} + +/****************************************************************************/ +/** +* @brief Disable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheDisable(void) +{ + u32 CtrlReg; + + if (EL3 == 1) { + CtrlReg = mfcp(SCTLR_EL3); + } else if (EL1_NONSECURE == 1) { + CtrlReg = mfcp(SCTLR_EL1); + } else { + CtrlReg = 0U; + } + /* invalidate the instruction cache */ + Xil_ICacheInvalidate(); + CtrlReg &= ~(XREG_CONTROL_ICACHE_BIT); + + if (EL3 == 1) { + /* disable the instruction cache */ + mtcp(SCTLR_EL3,CtrlReg); + } else if (EL1_NONSECURE == 1) { + /* disable the instruction cache */ + mtcp(SCTLR_EL1,CtrlReg); + } + + +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidate(void) +{ + unsigned int currmask; + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + mtcp(CSSELR_EL1,0x1); + dsb(); + /* invalidate the instruction cache */ + mtcpicall(IALLU); + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate an instruction cache line. If the instruction specified +* by the parameter adr is cached by the instruction cache, the +* cacheline containing that instruction is invalidated. +* +* @param adr: 64bit address of the instruction to be invalidated. +* +* @return None. +* +* @note The bottom 6 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_ICacheInvalidateLine(INTPTR adr) +{ + u32 currmask; + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(CSSELR_EL1,0x1); + /*Invalidate I Cache line*/ + mtcpic(IVAU,adr & (~0x3F)); + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the instruction cache for the given address range. +* If the instructions specified by the address range are cached by +* the instrunction cache, the cachelines containing those +* instructions are invalidated. +* +* @param adr: 64bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidateRange(INTPTR adr, INTPTR len) +{ + const INTPTR cacheline = 64U; + INTPTR end; + INTPTR tempadr = adr; + INTPTR tempend; + u32 currmask; + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0x00000000U) { + end = tempadr + len; + tempend = end; + tempadr &= ~(cacheline - 0x00000001U); + + /* Select cache Level 0 I-cache in CSSR */ + mtcp(CSSELR_EL1,0x1); + while (tempadr < tempend) { + /*Invalidate I Cache line*/ + mtcpic(IVAU,adr & (~0x3F)); + + tempadr += cacheline; + } + } +/* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Configure the maximum number of outstanding data prefetches +* allowed in L1 cache. +* +* @param num: maximum number of outstanding data prefetches allowed, +* valid values are 0-7. +* +* @return None. +* +* @note This function is implemented only for EL3 privilege level. +* +*****************************************************************************/ +void Xil_ConfigureL1Prefetch (u8 num) { +#if EL3 + u64 val=0; + + val= mfcp(S3_1_C15_C2_0 ); + val &= ~(L1_DATA_PREFETCH_CONTROL_MASK); + val |= (num << L1_DATA_PREFETCH_CONTROL_SHIFT); + mtcp(S3_1_C15_C2_0,val); +#endif +} diff --git a/bsps/shared/xil/arm/cortexr5/xil_cache.c b/bsps/shared/xil/arm/cortexr5/xil_cache.c new file mode 100644 index 0000000000..631d02f648 --- /dev/null +++ b/bsps/shared/xil/arm/cortexr5/xil_cache.c @@ -0,0 +1,561 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_cache.c +* +* Contains required functions for the ARM cache functionality. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 5.00 pkp 02/20/14 First release +* 6.2 mus 01/27/17 Updated to support IAR compiler +* 7.3 dp 06/25/20 Updated to support armclang compiler +* 7.7 sk 01/10/22 Update IRQ_FIQ_MASK macro from signed to unsigned +* to fix misra_c_2012_rule_10_4 violation. +* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7 +* violation. +* 7.7 mus 02/21/22 Existing note in cache API's says, "bottom 4 bits of input +* address are forced to 0 as per architecture". As cache line +* length is of 32 byte, bottom 5 bits of input address would +* be forced to 0. Updated note to have correct details. +* It fixes CR#1122561. +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xil_io.h" +#include "xpseudo_asm.h" +#include "xparameters.h" +#include "xreg_cortexr5.h" +#include "xil_exception.h" + + +/************************** Variable Definitions *****************************/ + +#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */ + +#if defined (__clang__) +extern s32 Image$$ARM_LIB_STACK$$Limit; +extern s32 Image$$ARM_UNDEF_STACK$$Base; +#elif defined (__GNUC__) +extern s32 _stack_end; +extern s32 __undef_stack; +#endif + +/****************************************************************************/ +/************************** Function Prototypes ******************************/ + +/****************************************************************************/ +/** +* @brief Enable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT)==0x00000000U) { + /* invalidate the Data cache */ + Xil_DCacheInvalidate(); + + /* enable the Data cache */ + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + } +} + +/****************************************************************************/ +/** +* @brief Disable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheDisable(void) +{ + register u32 CtrlReg; + + /* clean and invalidate the Data cache */ + Xil_DCacheFlush(); + + /* disable the Data cache */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheInvalidate(void) +{ + u32 currmask; + u32 stack_start,stack_end,stack_size; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + +#if defined (__clang__) + stack_end = (u32 )&Image$$ARM_LIB_STACK$$Limit; + stack_start = (u32 )&Image$$ARM_UNDEF_STACK$$Base; +#elif defined (__GNUC__) + stack_end = (u32 )&_stack_end; + stack_start = (u32 )&__undef_stack; +#endif + +#if defined(__GNUC__) || defined(__clang__) + stack_size = stack_start-stack_end; + + /* Flush stack memory to save return address */ + Xil_DCacheFlushRange(stack_end, stack_size); +#endif + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + /*invalidate all D cache*/ + mtcp(XREG_CP15_INVAL_DC_ALL, 0); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate a Data cache line. If the byte specified by the +* address (adr) is cached by the data cache, the cacheline +* containing that byte is invalidated.If the cacheline is modified +* (dirty), the modified contents are lost and are NOT written +* to system memory before the line is invalidated. +* +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheInvalidateLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for invalidate to complete */ + dsb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the Data cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache,the cacheline containing that byte is invalidated. +* If the cacheline is modified (dirty), the modified contents are +* lost and are NOT written to system memory before the line is +* invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of range to be invalidated in bytes. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len) +{ + const u32 cacheline = 32U; + u32 end; + u32 tempadr = adr; + u32 tempend; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + end = tempadr + len; + tempend = end; + /* Select L1 Data cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + + if ((tempadr & (cacheline-1U)) != 0U) { + tempadr &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempadr); + } + if ((tempend & (cacheline-1U)) != 0U) { + tempend &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempend); + } + + while (tempadr < tempend) { + + /* Invalidate Data cache line */ + asm_inval_dc_line_mva_poc(tempadr); + + tempadr += cacheline; + } + } + + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the entire Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheFlush(void) +{ + register u32 CsidReg, C7Reg; + u32 CacheSize, LineSize, NumWays; + u32 Way, WayIndex, Set, SetIndex, NumSet; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + /* Select cache level 0 and D cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + +#if defined (__GNUC__) + CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_CACHE_SIZE_ID,CsidReg); +#endif + /* Determine Cache Size */ + + CacheSize = (CsidReg >> 13U) & 0x000001FFU; + CacheSize += 0x00000001U; + CacheSize *= (u32)128; /* to get number of bytes */ + + /* Number of Ways */ + NumWays = (CsidReg & 0x000003ffU) >> 3U; + NumWays += 0x00000001U; + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + NumSet = CacheSize/NumWays; + NumSet /= (((u32)0x00000001U) << LineSize); + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set; + /* Flush by Set/Way */ + asm_clean_inval_dc_line_sw(C7Reg); + + Set += (((u32)0x00000001U) << LineSize); + } + Set = 0U; + Way += 0x40000000U; + } + + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush a Data cache line. If the byte specified by the address (adr) +* is cached by the Data cache, the cacheline containing that byte is +* invalidated. If the cacheline is modified (dirty), the entire +* contents of the cacheline are written to system memory before the +* line is invalidated. +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheFlushLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the Data cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache, the cacheline containing those bytes is invalidated.If +* the cacheline is modified (dirty), the written to system memory +* before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be flushed. +* @param len: Length of the range to be flushed in bytes +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheFlushRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr &= ~(cacheline - 1U); + + while (LocalAddr < end) { + /* Flush Data cache line */ + asm_clean_inval_dc_line_mva_poc(LocalAddr); + + LocalAddr += cacheline; + } + } + dsb(); + mtcpsr(currmask); +} +/****************************************************************************/ +/** +* @brief Store a Data cache line. If the byte specified by the address +* (adr) is cached by the Data cache and the cacheline is modified +* (dirty), the entire contents of the cacheline are written to +* system memory.After the store completes, the cacheline is marked +* as unmodified (not dirty). +* +* @param adr: 32bit address of the data to be stored +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheStoreLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for store to complete */ + dsb(); + isb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Enable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT)==0x00000000U) { + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* enable the instruction cache */ + CtrlReg |= (XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + } +} + +/****************************************************************************/ +/** +* @brief Disable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheDisable(void) +{ + register u32 CtrlReg; + + dsb(); + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* disable the instruction cache */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + + CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidate(void) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate an instruction cache line.If the instruction specified +* by the address is cached by the instruction cache, the +* cacheline containing that instruction is invalidated. +* +* @param adr: 32bit address of the instruction to be invalidated. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_ICacheInvalidateLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); + mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F))); + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the instruction cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache, the cacheline containing that byte is invalidated. +* If the cachelineis modified (dirty), the modified contents are +* lost and are NOT written to system memory before the line is +* invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 I-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + + while (LocalAddr < end) { + + /* Invalidate L1 I-cache line */ + asm_inval_ic_line_mva_pou(LocalAddr); + + LocalAddr += cacheline; + } + } + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} diff --git a/bsps/shared/xil/arm/cortexr5/xil_mpu.c b/bsps/shared/xil/arm/cortexr5/xil_mpu.c new file mode 100644 index 0000000000..85f8f7f8da --- /dev/null +++ b/bsps/shared/xil/arm/cortexr5/xil_mpu.c @@ -0,0 +1,645 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file xil_mpu.c +* +* This file provides APIs for enabling/disabling MPU and setting the memory +* attributes for sections, in the MPU translation table. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------- +* 5.00 pkp 02/10/14 Initial version +* 6.2 mus 01/27/17 Updated to support IAR compiler +* 6.4 asa 08/16/17 Added many APIs for MPU access to make MPU usage +* user-friendly. The APIs added are: Xil_UpdateMPUConfig, +* Xil_GetMPUConfig, Xil_GetNumOfFreeRegions, +* Xil_GetNextMPURegion, Xil_DisableMPURegionByRegNum, +* Xil_GetMPUFreeRegMask, Xil_SetMPURegionByRegNum, and +* Xil_InitializeExistingMPURegConfig. +* Added a new array of structure of type XMpuConfig to +* represent the MPU configuration table. +* 6.8 aru 07/02/18 Returned the pointer instead of address +* of that pointer in Xil_MemMap(). +* 7.5 asa 03/01/21 Ensure that Mpu_Config does not stay in .boot/.vector +* sections which generally should be executable code +* which can be allocated and not written. +* Mpu_Config array is populated during boot time, hence +* cannot be placed in .bss or .data section. Putting +* Mpu_Config in a new .bootdata section. +* 7.7 sk 01/10/22 Update int to u32 to fix misrac misra_c_2012_directive_4_6 +* violations. +* 7.7 sk 01/10/22 Typecast variables from signed to unsigned to fix +* misra_c_2012_rule_10_4 violation. +* 7.7 sk 01/10/22 Add explicit parentheses for region_size and region_size[0] +* to fix misra_c_2012_rule_12_1 violation. +* 7.7 sk 01/10/22 Remove unsigned sign to fix misra_c_2012_rule_10_3 violation. +* 7.7 sk 01/10/22 Modify if condition to fix misra_c_2012_rule_10_1 violation. +* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7 +* violation. +* 7.7 sk 01/10/22 Update conditional expression to fix misra_c_2012_rule_14_4 +* violation. +* 7.7 sk 01/10/22 Add braces for the if statement to make it a compound +* statement to fix misra_c_2012_rule_15_6 violation. +* </pre> +* +* +******************************************************************************/ + +/* + * Origin: https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexr5/xil_mpu.c + * __rtems__ changes: + * - un-include xdebug.h and add macro for xdbg_printf + * - relocate XMpu_Config + * - form Xilinx link script section(".bootdata") + * - to RTEMS link script section(".bsp_start_data") + */ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xpseudo_asm.h" +#include "xil_types.h" +#include "xil_mpu.h" +#ifndef __rtems__ +#include "xdebug.h" +#else +#define xdbg_printf(...) +#endif +#include "xstatus.h" +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ +#define MPU_REGION_SIZE_MIN 0x20 +/************************** Variable Definitions *****************************/ + +static const struct { + u64 size; + u32 encoding; +}region_size[] = { + { 0x20, REGION_32B }, + { 0x40, REGION_64B }, + { 0x80, REGION_128B }, + { 0x100, REGION_256B }, + { 0x200, REGION_512B }, + { 0x400, REGION_1K }, + { 0x800, REGION_2K }, + { 0x1000, REGION_4K }, + { 0x2000, REGION_8K }, + { 0x4000, REGION_16K }, + { 0x8000, REGION_32K }, + { 0x10000, REGION_64K }, + { 0x20000, REGION_128K }, + { 0x40000, REGION_256K }, + { 0x80000, REGION_512K }, + { 0x100000, REGION_1M }, + { 0x200000, REGION_2M }, + { 0x400000, REGION_4M }, + { 0x800000, REGION_8M }, + { 0x1000000, REGION_16M }, + { 0x2000000, REGION_32M }, + { 0x4000000, REGION_64M }, + { 0x8000000, REGION_128M }, + { 0x10000000, REGION_256M }, + { 0x20000000, REGION_512M }, + { 0x40000000, REGION_1G }, + { 0x80000000, REGION_2G }, + { 0x100000000, REGION_4G }, +}; + +#ifndef __rtems__ +#if defined (__GNUC__) +XMpu_Config Mpu_Config __attribute__((section(".bootdata"))); +#elif defined (__ICCARM__) +#pragma default_function_attributes = @ ".bootdata" +XMpu_Config Mpu_Config; +#endif +#else +XMpu_Config Mpu_Config __attribute__((section(".bsp_start_data"))); +#endif + +/************************** Function Prototypes ******************************/ +void Xil_InitializeExistingMPURegConfig(void); +/*****************************************************************************/ +/** +* @brief This function sets the memory attributes for a section covering +* 1MB, of memory in the translation table. +* +* @param addr: 32-bit address for which memory attributes need to be set. +* @param attrib: Attribute for the given memory region. +* @return None. +* +* +******************************************************************************/ +void Xil_SetTlbAttributes(INTPTR addr, u32 attrib) +{ + INTPTR Localaddr = addr; + Localaddr &= (INTPTR)(~(0xFFFFFU)); + /* Setting the MPU region with given attribute with 1MB size */ + Xil_SetMPURegion(Localaddr, 0x100000, attrib); +} + +/*****************************************************************************/ +/** +* @brief Set the memory attributes for a section of memory in the +* translation table. +* +* @param addr: 32-bit address for which memory attributes need to be set.. +* @param size: size is the size of the region. +* @param attrib: Attribute for the given memory region. +* @return None. +* +* +******************************************************************************/ +u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib) +{ + u32 Regionsize = 0; + INTPTR Localaddr = addr; + u32 NextAvailableMemRegion; + u32 i; + + NextAvailableMemRegion = Xil_GetNextMPURegion(); + if (NextAvailableMemRegion == 0xFFU) { + xdbg_printf(DEBUG, "No regions available\r\n"); + return XST_FAILURE; + } + + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,NextAvailableMemRegion); + isb(); + + /* Lookup the size. */ + for (i = 0; i < (sizeof (region_size) / sizeof (region_size[0])); i++) { + if (size <= region_size[i].size) { + Regionsize = region_size[i].encoding; + break; + } + } + + Localaddr &= (INTPTR)(~(region_size[i].size - 1U)); + + Regionsize <<= 1; + Regionsize |= REGION_EN; + dsb(); + mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); /* Set base address of a region */ + mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); /* Set the control attribute */ + mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); /* set the region size and enable it*/ + dsb(); + isb(); + Xil_UpdateMPUConfig(NextAvailableMemRegion, Localaddr, Regionsize, attrib); + return XST_SUCCESS; +} +/*****************************************************************************/ +/** +* @brief Enable MPU for Cortex R5 processor. This function invalidates I +* cache and flush the D Caches, and then enables the MPU. +* +* @return None. +* +******************************************************************************/ +void Xil_EnableMPU(void) +{ + u32 CtrlReg, Reg; + s32 DCacheStatus=0, ICacheStatus=0; + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) { + DCacheStatus=1; + } + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) { + ICacheStatus=1; + } + + if(DCacheStatus != 0) { + Xil_DCacheDisable(); + } + if(ICacheStatus != 0){ + Xil_ICacheDisable(); + } +#if defined (__GNUC__) + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,Reg); +#endif + Reg |= 0x00000001U; + dsb(); + mtcp(XREG_CP15_SYS_CONTROL, Reg); + isb(); + /* enable caches only if they are disabled in routine*/ + if(DCacheStatus != 0) { + Xil_DCacheEnable(); + } + if(ICacheStatus != 0) { + Xil_ICacheEnable(); + } +} + +/*****************************************************************************/ +/** +* @brief Disable MPU for Cortex R5 processors. This function invalidates I +* cache and flush the D Caches, and then disabes the MPU. +* +* @return None. +* +******************************************************************************/ +void Xil_DisableMPU(void) +{ + u32 CtrlReg, Reg; + s32 DCacheStatus=0, ICacheStatus=0; + /* enable caches only if they are disabled */ + +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) { + DCacheStatus=1; + } + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) { + ICacheStatus=1; + } + + if(DCacheStatus != 0) { + Xil_DCacheDisable(); + } + if(ICacheStatus != 0){ + Xil_ICacheDisable(); + } + + mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0); +#if defined (__GNUC__) + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,Reg); +#endif + Reg &= ~(0x00000001U); + dsb(); + mtcp(XREG_CP15_SYS_CONTROL, Reg); + isb(); + /* enable caches only if they are disabled in routine*/ + if(DCacheStatus != 0) { + Xil_DCacheEnable(); + } + if(ICacheStatus != 0) { + Xil_ICacheEnable(); + } +} + +/*****************************************************************************/ +/** +* @brief Update the MPU configuration for the requested region number in +* the global MPU configuration table. +* +* @param reg_num: The requested region number to be updated information for. +* @param address: 32 bit address for start of the region. +* @param size: Requested size of the region. +* @param attrib: Attribute for the corresponding region. +* @return XST_FAILURE: When the requested region number if 16 or more. +* XST_SUCCESS: When the MPU configuration table is updated. +* +* +******************************************************************************/ +u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib) +{ + u32 ReturnVal = XST_SUCCESS; + u32 Tempsize = size; + u32 Index; + + if (reg_num >= MAX_POSSIBLE_MPU_REGS) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + ReturnVal = XST_FAILURE; + goto exit; + } + + if ((size & REGION_EN) != 0) { + Mpu_Config[reg_num].RegionStatus = MPU_REG_ENABLED; + Mpu_Config[reg_num].BaseAddress = address; + Tempsize &= (~REGION_EN); + Tempsize >>= 1; + /* Lookup the size. */ + for (Index = 0; Index < + (sizeof (region_size) / sizeof (region_size[0])); Index++) { + if (Tempsize <= region_size[Index].encoding) { + Mpu_Config[reg_num].Size = region_size[Index].size; + break; + } + } + Mpu_Config[reg_num].Attribute = attrib; + } else { + Mpu_Config[reg_num].RegionStatus = 0U; + Mpu_Config[reg_num].BaseAddress = 0; + Mpu_Config[reg_num].Size = 0U; + Mpu_Config[reg_num].Attribute = 0U; + } + +exit: + return ReturnVal; +} + +/*****************************************************************************/ +/** +* @brief The MPU configuration table is passed to the caller. +* +* @param mpuconfig: This is of type XMpu_Config which is an array of +* 16 entries of type structure representing the MPU config table +* @return none +* +* +******************************************************************************/ +void Xil_GetMPUConfig (XMpu_Config mpuconfig) { + u32 Index = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + mpuconfig[Index].RegionStatus = Mpu_Config[Index].RegionStatus; + mpuconfig[Index].BaseAddress = Mpu_Config[Index].BaseAddress; + mpuconfig[Index].Attribute = Mpu_Config[Index].Attribute; + mpuconfig[Index].Size = Mpu_Config[Index].Size; + Index++; + } +} + +/*****************************************************************************/ +/** +* @brief Returns the total number of free MPU regions available. +* +* @return Number of free regions available to users +* +* +******************************************************************************/ +u32 Xil_GetNumOfFreeRegions (void) { + u32 Index = 0U; + u32 NumofFreeRegs = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) { + NumofFreeRegs++; + } + Index++; + } + return NumofFreeRegs; +} + +/*****************************************************************************/ +/** +* @brief Returns the total number of free MPU regions available in the form +* of a mask. A bit of 1 in the returned 16 bit value represents the +* corresponding region number to be available. +* For example, if this function returns 0xC0000, this would mean, the +* regions 14 and 15 are available to users. +* +* @return The free region mask as a 16 bit value +* +* +******************************************************************************/ +u16 Xil_GetMPUFreeRegMask (void) { + u32 Index = 0U; + u16 FreeRegMask = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) { + FreeRegMask |= ((u16)1U << Index); + } + Index++; + } + return FreeRegMask; +} + +/*****************************************************************************/ +/** +* @brief Disables the corresponding region number as passed by the user. +* +* @param reg_num: The region number to be disabled +* @return XST_SUCCESS: If the region could be disabled successfully +* XST_FAILURE: If the requested region number is 16 or more. +* +* +******************************************************************************/ +u32 Xil_DisableMPURegionByRegNum (u32 reg_num) { + u32 Temp = 0U; + u32 ReturnVal = XST_FAILURE; + + if (reg_num >= 16U) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + goto exit1; + } + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num); +#if defined (__GNUC__) + Temp = mfcp(XREG_CP15_MPU_REG_SIZE_EN); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); +#endif + Temp &= (~REGION_EN); + dsb(); + mtcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); + dsb(); + isb(); + Xil_UpdateMPUConfig(reg_num, 0, 0U, 0U); + ReturnVal = XST_SUCCESS; + +exit1: + return ReturnVal; +} + +/*****************************************************************************/ +/** +* @brief Enables the corresponding region number as passed by the user. +* +* @param reg_num: The region number to be enabled +* @param addr: 32 bit address for start of the region. +* @param size: Requested size of the region. +* @param attrib: Attribute for the corresponding region. +* @return XST_SUCCESS: If the region could be created successfully +* XST_FAILURE: If the requested region number is 16 or more. +* +* +******************************************************************************/ +u32 Xil_SetMPURegionByRegNum (u32 reg_num, INTPTR addr, u64 size, u32 attrib) +{ + u32 ReturnVal = XST_SUCCESS; + INTPTR Localaddr = addr; + u32 Regionsize = 0; + u32 Index; + + if (reg_num >= 16U) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + ReturnVal = XST_FAILURE; + goto exit2; + } + + if (Mpu_Config[reg_num].RegionStatus == MPU_REG_ENABLED) { + xdbg_printf(DEBUG, "Region already enabled\r\n"); + ReturnVal = XST_FAILURE; + goto exit2; + } + + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num); + isb(); + + /* Lookup the size. */ + for (Index = 0; Index < + (sizeof (region_size) / sizeof (region_size[0])); Index++) { + if (size <= region_size[Index].size) { + Regionsize = region_size[Index].encoding; + break; + } + } + + Localaddr &= (INTPTR)(~(region_size[Index].size - 1U)); + Regionsize <<= 1; + Regionsize |= REGION_EN; + dsb(); + mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); + mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); + mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); + dsb(); + isb(); + Xil_UpdateMPUConfig(reg_num, Localaddr, Regionsize, attrib); +exit2: + return ReturnVal; + +} + +/*****************************************************************************/ +/** +* @brief Initializes the MPU configuration table that are setup in the +* R5 boot code in the Init_Mpu function called before C main. +* +* @return none +* +* +******************************************************************************/ +void Xil_InitializeExistingMPURegConfig(void) +{ + u32 Index = 0U; + u32 Index1 = 0U; + u32 MPURegSize; + INTPTR MPURegBA; + u32 MPURegAttrib; + u32 Tempsize; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,Index); +#if defined (__GNUC__) + MPURegSize = mfcp(XREG_CP15_MPU_REG_SIZE_EN); + MPURegBA = mfcp(XREG_CP15_MPU_REG_BASEADDR); + MPURegAttrib = mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_MPU_REG_SIZE_EN,MPURegSize); + mfcp(XREG_CP15_MPU_REG_BASEADDR, MPURegBA); + mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL, MPURegAttrib); +#endif + if ((MPURegSize & REGION_EN) != 0) { + Mpu_Config[Index].RegionStatus = MPU_REG_ENABLED; + Mpu_Config[Index].BaseAddress = MPURegBA; + Mpu_Config[Index].Attribute = MPURegAttrib; + Tempsize = MPURegSize & (~REGION_EN); + Tempsize >>= 1; + for (Index1 = 0; Index1 < + (sizeof (region_size) / sizeof (region_size[0])); Index1++) { + if (Tempsize <= region_size[Index1].encoding) { + Mpu_Config[Index].Size = region_size[Index1].size; + break; + } + } + } + Index++; + } +} + +/*****************************************************************************/ +/** +* @brief Returns the next available free MPU region +* +* @return The free MPU region available +* +* +******************************************************************************/ +u32 Xil_GetNextMPURegion(void) +{ + u32 Index = 0U; + u32 NextAvailableReg = 0xFF; + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (Mpu_Config[Index].RegionStatus != MPU_REG_ENABLED) { + NextAvailableReg = Index; + break; + } + Index++; + } + return NextAvailableReg; +} + +#ifdef __GNUC__ +#define u32overflow(a, b) ({typeof(a) s; __builtin_uadd_overflow(a, b, &s); }) +#else +#define u32overflow(a, b) ((a) > ((a) + (b))) +#endif /* __GNUC__ */ + +/*****************************************************************************/ +/** +* @brief Memory mapping for Cortex-R5F. If successful, the mapped +* region will include all of the memory requested, but may +* include more. Specifically, it will be a power of 2 in +* size, aligned on a boundary of that size. +* +* @param Physaddr is base physical address at which to start mapping. +* NULL in Physaddr masks possible mapping errors. +* @param size of region to be mapped. +* @param flags used to set translation table. +* +* @return Physaddr on success, NULL on error. Ambiguous if Physaddr==NULL +* +* @cond Xil_MemMap_internal +* @note: u32overflow() is defined for readability and (for __GNUC__) to +* - force the type of the check to be the same as the first argument +* - hide the otherwise unused third argument of the builtin +* - improve safety by choosing the explicit _uadd_ version. +* Consider __builtin_add_overflow_p() when available. +* Use an alternative (less optimal?) for compilers w/o the builtin. +* @endcond +******************************************************************************/ +void *Xil_MemMap(UINTPTR Physaddr, size_t size, u32 flags) +{ + size_t Regionsize = MPU_REGION_SIZE_MIN; + UINTPTR Basephysaddr = 0, end = Physaddr + size; + + if (flags == 0U) { + return (void *)Physaddr; + } + if (u32overflow(Physaddr, size)) { + return NULL; + } + for ( ; Regionsize != 0U; Regionsize <<= 1) { + if (Regionsize >= size) { + Basephysaddr = Physaddr & ~(Regionsize - 1U); + if (u32overflow(Basephysaddr, Regionsize)) { + break; + } + if ((Basephysaddr + Regionsize) >= end) { + return ((Xil_SetMPURegion(Basephysaddr, + Regionsize, flags) == XST_SUCCESS) ? + (void *)Physaddr : NULL); + } + } + } + return NULL; +} diff --git a/bsps/shared/xil/xil_assert.c b/bsps/shared/xil/xil_assert.c new file mode 100644 index 0000000000..b3dd7e9718 --- /dev/null +++ b/bsps/shared/xil/xil_assert.c @@ -0,0 +1,126 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_assert.c +* @addtogroup common_assert_apis Assert APIs and Macros +* @{ +* +* This file contains basic assert related functions for Xilinx software IP. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00a hbm 07/14/09 Initial release +* 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/** + * @brief This variable allows testing to be done easier with asserts. An assert + * sets this variable such that a driver can evaluate this variable + * to determine if an assert occurred. + */ +u32 Xil_AssertStatus; + +/** + * @brief This variable allows the assert functionality to be changed for testing + * such that it does not wait infinitely. Use the debugger to disable the + * waiting during testing of asserts. + */ +s32 Xil_AssertWait = 1; + +/* The callback function to be invoked when an assert is taken */ +static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* @brief Implement assert. Currently, it calls a user-defined callback +* function if one has been set. Then, it potentially enters an +* infinite loop depending on the value of the Xil_AssertWait +* variable. +* +* @param File: filename of the source +* @param Line: linenumber within File +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void Xil_Assert(const char8 *File, s32 Line) +{ + /* if the callback has been set then invoke it */ + if (Xil_AssertCallbackRoutine != 0) { + (*Xil_AssertCallbackRoutine)(File, Line); + } + + /* if specified, wait indefinitely such that the assert will show up + * in testing + */ + while (Xil_AssertWait != 0) { + } +} + +/*****************************************************************************/ +/** +* +* @brief Set up a callback function to be invoked when an assert occurs. +* If a callback is already installed, then it will be replaced. +* +* @param Routine: callback to be invoked when an assert is taken +* +* @return None. +* +* @note This function has no effect if NDEBUG is set +* +******************************************************************************/ +void Xil_AssertSetCallback(Xil_AssertCallback Routine) +{ + Xil_AssertCallbackRoutine = Routine; +} + +/*****************************************************************************/ +/** +* +* @brief Null handler function. This follows the XInterruptHandler +* signature for interrupt handlers. It can be used to assign a null +* handler (a stub) to an interrupt controller vector table. +* +* @param NullParameter: arbitrary void pointer and not used. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XNullHandler(void *NullParameter) +{ + (void) NullParameter; +} +/** +* @} End of "addtogroup common_assert_apis". +*/ diff --git a/bsps/shared/xil/xil_mem.c b/bsps/shared/xil/xil_mem.c new file mode 100644 index 0000000000..44e7d9a0c4 --- /dev/null +++ b/bsps/shared/xil/xil_mem.c @@ -0,0 +1,70 @@ +/******************************************************************************/ +/** +* Copyright (c) 2015 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* @file xil_mem.c +* +* This file contains xil mem copy function to use in case of word aligned +* data copies. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- -------- -------- ----------------------------------------------- +* 6.1 nsk 11/07/16 First release. +* 7.7 sk 01/10/22 Update Xil_MemCpy functions variables typecast +* from int to s32 to fix misra_c_2012_directive_4_6 +* violations. +* 7.7 sk 01/10/22 Include xil_mem.h header file to fix Xil_MemCpy +* prototype misra_c_2012_rule_8_4 violation. +* +* </pre> +* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_mem.h" + +/***************** Inline Functions Definitions ********************/ +/*****************************************************************************/ +/** +* @brief This function copies memory from once location to other. +* +* @param dst: pointer pointing to destination memory +* +* @param src: pointer pointing to source memory +* +* @param cnt: 32 bit length of bytes to be copied +* +*****************************************************************************/ +void Xil_MemCpy(void* dst, const void* src, u32 cnt) +{ + char *d = (char*)(void *)dst; + const char *s = src; + + while (cnt >= sizeof (s32)) { + *(s32*)d = *(s32*)s; + d += sizeof (s32); + s += sizeof (s32); + cnt -= sizeof (s32); + } + while (cnt >= sizeof (u16)) { + *(u16*)d = *(u16*)s; + d += sizeof (u16); + s += sizeof (u16); + cnt -= sizeof (u16); + } + while ((cnt) > 0U){ + *d = *s; + d += 1U; + s += 1U; + cnt -= 1U; + } +} |