diff --git a/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.mld b/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.mld index 0b9bf388..a8c8142e 100755 --- a/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.mld +++ b/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.mld @@ -21,10 +21,10 @@ OPTION psf_version = 2.1.0 ; BEGIN OS freertos821_xilinx OPTION DRC = FreeRTOS_drc ; -OPTION supported_peripherals = (microblaze ps7_cortexa9 psu_cortexr5); +OPTION supported_peripherals = (microblaze ps7_cortexa9 psu_cortexr5 psu_cortexa53); OPTION COPYFILES = all; OPTION NAME = freertos821_xilinx; -OPTION VERSION = 1.1; +OPTION VERSION = 1.0; OPTION DEPENDS = (standalone_v5_3); OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxil,-lfreertos,-lgcc,-lc,--end-group"; OPTION DESC = "FreeRTOS is a market leading open source RTOS"; diff --git a/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.tcl b/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.tcl index b5eb7598..593aa0b5 100755 --- a/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.tcl +++ b/ThirdParty/bsp/freertos821_xilinx/data/freertos821_xilinx.tcl @@ -42,14 +42,17 @@ proc generate {os_handle} { set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ] set proctype [common::get_property IP_NAME $hw_proc_handle] set need_config_file "false" - - # proctype should be "microblaze", ps7_cortexa9 or psu_cortexr5 + set enable_sw_profile [common::get_property CONFIG.enable_sw_intrusive_profiling $os_handle] + # proctype should be "microblaze", ps7_cortexa9, psu_cortexr5 or psu_cortexa53 set commonsrcdir "../${standalone_version}/src/common" set mbsrcdir "../${standalone_version}/src/microblaze" set armr5srcdir "../${standalone_version}/src/cortexr5" set armr5gccdir "../${standalone_version}/src/cortexr5/gcc" set arma53srcdir "../${standalone_version}/src/cortexa53" - set arma53gccdir "../${standalone_version}/src/cortexa53/gcc" + set arma5364srcdir "../${standalone_version}/src/cortexa53/64bit" + set arma5332srcdir "../${standalone_version}/src/cortexa53/32bit" + set arma5364gccdir "../${standalone_version}/src/cortexa53/64bit/gcc" + set arma5332gccdir "../${standalone_version}/src/cortexa53/32bit/gcc" set includedir "../${standalone_version}/src/cortexa53/includes_ps" set arma9srcdir "../${standalone_version}/src/cortexa9" set arma9gccdir "../${standalone_version}/src/cortexa9/gcc" @@ -76,7 +79,10 @@ proc generate {os_handle} { file copy -force $includedir "../${standalone_version}/src/" file delete -force "../${standalone_version}/src/gcc" - + file delete -force "../${standalone_version}/src/profile" + if { $enable_sw_profile == "true" } { + error "ERROR: Profiling is not supported for R5" + } set need_config_file "true" set file_handle [::hsi::utils::open_include_file "xparameters.h"] @@ -84,7 +90,36 @@ proc generate {os_handle} { puts $file_handle "" close $file_handle } + "psu_cortexa53" { + set procdrv [hsi::get_sw_processor] + set compiler [get_property CONFIG.compiler $procdrv] + if {[string compare -nocase $compiler "arm-none-eabi-gcc"] == 0} { + error "ERROR: FreeRTOS is not supported for 32bit A53" + } + puts "In start copy psu_cortexa53" + file copy -force "./src/Makefile_psu_cortexa53" "./src/Makefile" + file copy -force "./src/Makefile" "./src/Makefile_dep" + foreach entry [glob -nocomplain [file join $arma5364srcdir *]] { + file copy -force $entry [file join ".." "${standalone_version}" "src"] + } + foreach entry [glob -nocomplain [file join $arma5364gccdir *]] { + file copy -force $entry [file join ".." "${standalone_version}" "src"] + } + + file copy -force $includedir "../${standalone_version}/src/" + file delete -force "../${standalone_version}/src/gcc" + file delete -force "../${standalone_version}/src/profile" + if { $enable_sw_profile == "true" } { + error "ERROR: Profiling is not supported for A53" + } + set need_config_file "true" + + set file_handle [::hsi::utils::open_include_file "xparameters.h"] + puts $file_handle "#include \"xparameters_ps.h\"" + puts $file_handle "" + close $file_handle + } "ps7_cortexa9" { puts "In start copy ps7_cortexa9" file copy -force "./src/Makefile_ps7_cortexa9" "./src/Makefile" @@ -132,7 +167,7 @@ proc generate {os_handle} { set makeconfig [open "../${standalone_version}/src/config.make" w] file rename -force -- "../${standalone_version}/src/Makefile" "../${standalone_version}/src/Makefile_depends" - if { $proctype == "psu_cortexr5" || $proctype == "ps7_cortexa9" || $proctype == "microblaze" } { + if { $proctype == "psu_cortexr5" || $proctype == "ps7_cortexa9" || $proctype == "microblaze" || $proctype == "psu_cortexa53" } { puts $makeconfig "LIBSOURCES = *.c *.S" puts $makeconfig "LIBS = standalone_libs" } @@ -142,6 +177,7 @@ proc generate {os_handle} { # Remove arm directory... file delete -force $armr5srcdir file delete -force $arma9srcdir + file delete -force $arma5364srcdir file delete -force $mbsrcdir # Copy core kernel files to the main src directory @@ -159,6 +195,13 @@ proc generate {os_handle} { file copy -force [file join src Source portable GCC ARM_CR5 portmacro.h] ./src file copy -force [file join src Source portable GCC ARM_CR5 portZynqUltrascale.c] ./src } + if { $proctype == "psu_cortexa53" } { + file copy -force [file join src Source portable GCC ARM_CA53 port.c] ./src + file copy -force [file join src Source portable GCC ARM_CA53 portASM.S] ./src + file copy -force [file join src Source portable GCC ARM_CA53 port_asm_vectors.S] ./src + file copy -force [file join src Source portable GCC ARM_CA53 portmacro.h] ./src + file copy -force [file join src Source portable GCC ARM_CA53 portZynqUltrascale.c] ./src + } if { $proctype == "ps7_cortexa9" } { file copy -force [file join src Source portable GCC ARM_CA9 port.c] ./src @@ -227,7 +270,6 @@ proc generate {os_handle} { file delete -force $armr5srcdir file delete -force $armr5gccdir file delete -force $arma53srcdir - file delete -force $arma53gccdir file delete -force $arma9srcdir file delete -force $arma9gccdir file delete -force $arma9armccdir @@ -587,6 +629,11 @@ proc generate {os_handle} { puts $config_file "#define configSETUP_TICK_INTERRUPT() FreeRTOS_SetupTickInterrupt()\n" puts $config_file "void FreeRTOS_ClearTickInterrupt( void );" puts $config_file "#define configCLEAR_TICK_INTERRUPT() FreeRTOS_ClearTickInterrupt()\n" + puts $config_file "#define configGENERATE_RUN_TIME_STATS 0\n" + puts $config_file "#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\n" + puts $config_file "#define portGET_RUN_TIME_COUNTER_VALUE()\n" + puts $config_file "#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096\n" + puts $config_file "#define recmuCONTROLLING_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )\n" set max_api_call_interrupt_priority [common::get_property CONFIG.max_api_call_interrupt_priority $os_handle] xput_define $config_file "configMAX_API_CALL_INTERRUPT_PRIORITY" "($max_api_call_interrupt_priority)" @@ -600,7 +647,152 @@ proc generate {os_handle} { } # end of if $proctype == "psu_cortexr5" + ############################################################################ + ## Add constants specific to the psu_cortexa53 + ############################################################################ + if { $proctype == "psu_cortexa53" } { + + set val [common::get_property CONFIG.PSU_TTC0_Select $os_handle] + if {$val == "true"} { + set have_tick_timer 1 + set val1 [common::get_property CONFIG.PSU_TTC0_Select_Cntr $os_handle] + if {$val1 == "0"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_0_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_0_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_0_INTR" + } else { + if {$val1 == "1"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_1_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_1_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_1_INTR" + } else { + if {$val1 == "2"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_2_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_2_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_2_INTR" + } else { + error "ERROR: invalid timer selected" "mdt_error" + } + } + } + } + + set val [common::get_property CONFIG.PSU_TTC1_Select $os_handle] + if {$val == "true"} { + if {$have_tick_timer == 1} { + error "ERROR: Cannot select multiple timers for tick generation " "mdt_error" + } else { + set have_tick_timer 1 + set val1 [common::get_property CONFIG.PSU_TTC1_Select_Cntr $os_handle] + if {$val1 == "0"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_3_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_3_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_3_INTR" + } else { + if {$val1 == "1"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_4_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_4_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_4_INTR" + } else { + if {$val1 == "2"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_5_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_5_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_5_INTR" + } else { + error "ERROR: invalid timer selected " "mdt_error" + } + } + } + } + } + + set val [common::get_property CONFIG.PSU_TTC2_Select $os_handle] + if {$val == "true"} { + if {$have_tick_timer == 1} { + error "ERROR: Cannot select multiple timers for tick generation " "mdt_error" + } else { + set have_tick_timer 1 + set val1 [common::get_property CONFIG.PSU_TTC2_Select_Cntr $os_handle] + if {$val1 == "0"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_6_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_6_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_6_INTR" + } else { + if {$val1 == "1"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_7_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_7_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_7_INTR" + } else { + if {$val1 == "2"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_8_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_8_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_8_INTR" + } else { + error "ERROR: invalid timer selected " "mdt_error" + } + } + } + } + } + + set val [common::get_property CONFIG.PSU_TTC3_Select $os_handle] + if {$val == "true"} { + if {$have_tick_timer == 1} { + error "ERROR: Cannot select multiple timers for tick generation " "mdt_error" + } else { + set have_tick_timer 1 + set val1 [common::get_property CONFIG.PSU_TTC3_Select_Cntr $os_handle] + if {$val1 == "0"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_9_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_9_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_9_INTR" + } else { + if {$val1 == "1"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_10_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_10_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_10_INTR" + } else { + if {$val1 == "2"} { + xput_define $config_file "configTIMER_ID" "XPAR_XTTCPS_11_DEVICE_ID" + xput_define $config_file "configTIMER_BASEADDR" "XPAR_XTTCPS_11_BASEADDR" + xput_define $config_file "configTIMER_INTERRUPT_ID" "XPAR_XTTCPS_11_INTR" + } else { + error "ERROR: invalid timer selected " "mdt_error" + } + } + } + } + } + + if {$have_tick_timer == 0} { + error "ERROR: No tick timer selected " "mdt_error" + } + xput_define $config_file "configUNIQUE_INTERRUPT_PRIORITIES" "32" + xput_define $config_file "configINTERRUPT_CONTROLLER_DEVICE_ID" "XPAR_SCUGIC_SINGLE_DEVICE_ID" + xput_define $config_file "configINTERRUPT_CONTROLLER_BASE_ADDRESS" "XPAR_SCUGIC_0_DIST_BASEADDR" + xput_define $config_file "configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET" "0x10000" + + # Function prototypes cannot be in the common code as some compilers or + # ports require pre-processor guards to ensure they are not visible from + # assembly files. + puts $config_file "void vApplicationAssert( const char *pcFile, uint32_t ulLine );" + puts $config_file "void FreeRTOS_SetupTickInterrupt( void );" + puts $config_file "#define configSETUP_TICK_INTERRUPT() FreeRTOS_SetupTickInterrupt()\n" + puts $config_file "void FreeRTOS_ClearTickInterrupt( void );" + puts $config_file "#define configCLEAR_TICK_INTERRUPT() FreeRTOS_ClearTickInterrupt()\n" + + set max_api_call_interrupt_priority [common::get_property CONFIG.max_api_call_interrupt_priority $os_handle] + xput_define $config_file "configMAX_API_CALL_INTERRUPT_PRIORITY" "($max_api_call_interrupt_priority)" + + set val [common::get_property CONFIG.use_port_optimized_task_selection $os_handle] + if {$val == "false"} { + xput_define $config_file "configUSE_PORT_OPTIMISED_TASK_SELECTION" "0" + } else { + xput_define $config_file "configUSE_PORT_OPTIMISED_TASK_SELECTION" "1" + } + } + # end of if $proctype == "psu_cortexa53" ############################################################################ diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Makefile_psu_cortexa53 b/ThirdParty/bsp/freertos821_xilinx/src/Makefile_psu_cortexa53 new file mode 100644 index 00000000..462ccfad --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Makefile_psu_cortexa53 @@ -0,0 +1,140 @@ +# +# Copyright (C) 2012-2013 Xilinx, Inc. +# +# This file is part of the port for FreeRTOS made by Xilinx to allow FreeRTOS +# to operate with Xilinx Zynq devices. +# +# This file is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License (version 2) as published by the +# Free Software Foundation AND MODIFIED BY the FreeRTOS exception +# (see text further below). +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License; if not it +# can be viewed here: +# +# The following exception language was found at +# http://www.freertos.org/a00114.html on May 8, 2012. +# +# GNU General Public License Exception +# +# Any FreeRTOS source code, whether modified or in its original release form, +# or whether in whole or in part, can only be distributed by you under the +# terms of the GNU General Public License plus this exception. An independent +# module is a module which is not derived from or based on FreeRTOS. +# +# EXCEPTION TEXT: +# +# Clause 1 +# +# Linking FreeRTOS statically or dynamically with other modules is making a +# combined work based on FreeRTOS. Thus, the terms and conditions of the +# GNU General Public License cover the whole combination. +# +# As a special exception, the copyright holder of FreeRTOS gives you permission +# to link FreeRTOS with independent modules that communicate with FreeRTOS +# solely through the FreeRTOS API interface, regardless of the license terms +# of these independent modules, and to copy and distribute the resulting +# combined work under terms of your choice, provided that +# +# Every copy of the combined work is accompanied by a written statement that +# details to the recipient the version of FreeRTOS used and an offer by +# yourself to provide the FreeRTOS source code (including any modifications +# you may have made) should the recipient request it. +# The combined work is not itself an RTOS, scheduler, kernel or related product. +# The independent modules add significant and primary functionality to FreeRTOS +# and do not merely extend the existing functionality already present +# in FreeRTOS. +# +# Clause 2 +# +# FreeRTOS may not be used for any competitive or comparative purpose, +# including the publication of any form of run time or compile time metric, +# without the express permission of Real Time Engineers Ltd. (this is the norm +# within the industry and is intended to ensure information accuracy). +# + +# +# Processor architecture +# psu_cortexa53 +# +ARCH = psu_cortexa53 + +SYSTEMDIR = ../../.. + +TOPDIR = . + +ARCH_PREFIX = aarch64-none-eabi + +# +# gnu tools for Makefile +# +CC = $(ARCH_PREFIX)-gcc +AS = aarch64-none-eabi-as +AR = $(ARCH_PREFIX)-ar +CP = cp + +ifeq ($(COMPILER) , aarch64-none-eabi-gcc) + EXTRA_COMPILER_FLAGS = += -nostartfiles +endif + +EXTRA_COMPILER_FLAGS += -march=armv8-a \ + -mfpu=VFPv4 \ + +# +# Compiler, linker and other options. +# +CFLAGS = ${COMPILER_FLAGS} ${EXTRA_COMPILER_FLAGS} + +# +# System project directories. +# +LIBDIR = $(SYSTEMDIR)/lib +INCLUDEDIR = $(SYSTEMDIR)/include + +# Kernel library. +LIBFREERTOS = ${LIBDIR}/libfreertos.a +LIBXIL = ${LIBDIR}/libxil.a + +INCLUDEFILES = ${TOPDIR}/*.h + +INCLUDES = -I$(INCLUDEDIR) \ + -I${TOPDIR} + +KERNEL_AR_OBJS = *.c *.S + +OUTS = *.o + + + +libs: $(KERNEL_AR_OBJS) + $(MAKE) -f Makefile_depends -e "COMPILER_FLAGS=$(COMPILER_FLAGS)" "EXTRA_COMPILER_FLAGS=$(EXTRA_COMPILER_FLAGS)" -C ../../standalone_v5_3/src libs + @echo "Compiling FreeRTOS" + @$(COMPILER) $(COMPILER_FLAGS) $(CC_FLAG) $(EXTRA_COMPILER_FLAGS) -march=armv8-a $(INCLUDES) $^ + @$(ARCHIVER) -r ${LIBFREERTOS} ${OUTS} + @$(ARCHIVER) -d ${LIBXIL} asm_vectors.o + @$(ARCHIVER) -s ${LIBXIL} + + make clean + + + + +include_standalone: + @echo "includes" + $(MAKE) -f Makefile_depends -e "COMPILER_FLAGS=$(COMPILER_FLAGS)" "EXTRA_COMPILER_FLAGS=$(EXTRA_COMPILER_FLAGS)" -C ../../standalone_v5_3/src include + $(CP) -rf $(INCLUDEFILES) $(INCLUDEDIR) + + +.PHONY: include +include: + @echo "include" + $(MAKE) -f Makefile_depends -e "COMPILER_FLAGS=$(COMPILER_FLAGS)" "EXTRA_COMPILER_FLAGS=$(EXTRA_COMPILER_FLAGS)" -C ../../standalone_v5_3/src include + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OUTS} diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/include/portable.h b/ThirdParty/bsp/freertos821_xilinx/src/Source/include/portable.h index ed7f73de..dbcd6000 100644 --- a/ThirdParty/bsp/freertos821_xilinx/src/Source/include/portable.h +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/include/portable.h @@ -94,6 +94,14 @@ must be set in the compiler's include path. */ #include "portmacro.h" #endif +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + #if portBYTE_ALIGNMENT == 8 #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) #endif diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port.c b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port.c new file mode 100644 index 00000000..efe381ed --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port.c @@ -0,0 +1,541 @@ +/* + FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS + #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET + #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#ifndef configUNIQUE_INTERRUPT_PRIORITIES + #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#ifndef configSETUP_TICK_INTERRUPT + #error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif /* configSETUP_TICK_INTERRUPT */ + +#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html +#endif + +#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 + #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 +#endif + +#if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/* In case security extensions are implemented. */ +#if configMAX_API_CALL_INTERRUPT_PRIORITY <= ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) +#endif + +/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in +portmacro.h. */ +#ifndef configCLEAR_TICK_INTERRUPT + #define configCLEAR_TICK_INTERRUPT() +#endif + +/* A critical section is exited when the critical section nesting count reaches +this value. */ +#define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) + +/* In all GICs 255 can be written to the priority mask register to unmask all +(but the lowest) interrupt priority. */ +#define portUNMASK_VALUE ( 0xFFUL ) + +/* Tasks are not created with a floating point context, but can be given a +floating point context after they have been created. A variable is stored as +part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task +does not have an FPU context, or any other value if the task does have an FPU +context. */ +#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) + +/* Constants required to setup the initial task context. */ +#define portEL3 ( ( StackType_t ) 0x0c ) +#define portSP_ELx ( ( StackType_t ) 0x01 ) +#define portSP_EL0 ( ( StackType_t ) 0x00 ) + +/* At the time of writing, the BSP only supports EL3. */ +#define portINITIAL_PSTATE ( portEL3 | portSP_EL0 ) + +/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary +point is zero. */ +#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) + +/* Masks all bits in the APSR other than the mode bits. */ +#define portAPSR_MODE_BITS_MASK ( 0x0C ) + +/* The I bit in the DAIF bits. */ +#define portDAIF_I ( 0x80 ) + +/* Macro to unmask all interrupt priorities. */ +#define portCLEAR_INTERRUPT_MASK() \ +{ \ + portDISABLE_INTERRUPTS(); \ + portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ + __asm volatile ( "DSB SY \n" \ + "ISB SY \n" ); \ + portENABLE_INTERRUPTS(); \ +} + +/* Hardware specifics used when sanity checking the configuration. */ +#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portBIT_0_SET ( ( uint8_t ) 0x01 ) + +/*-----------------------------------------------------------*/ + +/* + * Starts the first task executing. This function is necessarily written in + * assembly code so is implemented in portASM.s. + */ +extern void vPortRestoreTaskContext( void ); + +/*-----------------------------------------------------------*/ + +/* A variable is used to keep track of the critical section nesting. This +variable has to be stored as part of the task context and must be initialised to +a non zero value to ensure interrupts don't inadvertently become unmasked before +the scheduler starts. As it is stored as part of the task context it will +automatically be set to 0 when the first task is started. */ +volatile uint64_t ullCriticalNesting = 9999ULL; + +/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero +then floating point context must be saved and restored for the task. */ +uint64_t ullPortTaskHasFPUContext = pdFALSE; + +/* Set to 1 to pend a context switch from an ISR. */ +uint64_t ullPortYieldRequired = pdFALSE; + +/* Counts the interrupt nesting depth. A context switch is only performed if +if the nesting depth is 0. */ +uint64_t ullPortInterruptNesting = 0; + +/* Used in the ASM code. */ +__attribute__(( used )) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS; +__attribute__(( used )) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS; +__attribute__(( used )) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; +__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Setup the initial stack of the task. The stack is set exactly as + expected by the portRESTORE_CONTEXT() macro. */ + + /* First all the general purpose registers. */ + pxTopOfStack--; + *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ + pxTopOfStack--; + *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ + pxTopOfStack--; + *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ + pxTopOfStack--; + *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ + pxTopOfStack--; + *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_PSTATE; + pxTopOfStack--; + + *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ + pxTopOfStack--; + + /* The task will start with a critical nesting count of 0 as interrupts are + enabled. */ + *pxTopOfStack = portNO_CRITICAL_NESTING; + pxTopOfStack--; + + /* The task will start without a floating point context. A task that uses + the floating point hardware must call vPortTaskUsesFPU() before executing + any floating point instructions. */ + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) +{ +uint32_t ulAPSR; + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine how many priority bits are implemented in the GIC. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to + all possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Shift to the least significant bits. */ + while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET ) + { + ucMaxPriorityValue >>= ( uint8_t ) 0x01; + } + + /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read + value. */ + configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + + /* At the time of writing, the BSP only supports EL3. */ + __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) ); + ulAPSR &= portAPSR_MODE_BITS_MASK; + configASSERT( ulAPSR == portEL3 ); + + if( ulAPSR == portEL3 ) + { + /* Only continue if the binary point value is set to its lowest possible + setting. See the comments in vPortValidateInterruptPriority() below for + more information. */ + configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); + + if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) + { + /* Interrupts are turned off in the CPU itself to ensure a tick does + not execute while the scheduler is being started. Interrupts are + automatically turned back on in the CPU when the first task starts + executing. */ + portDISABLE_INTERRUPTS(); + + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + /* Start the first task executing. */ + vPortRestoreTaskContext(); + } + } + + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( ullCriticalNesting == 1000ULL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + /* Mask interrupts up to the max syscall interrupt priority. */ + uxPortSetInterruptMask(); + + /* Now interrupts are disabled ullCriticalNesting can be accessed + directly. Increment ullCriticalNesting to keep a count of how many times + portENTER_CRITICAL() has been called. */ + ullCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( ullCriticalNesting == 1ULL ) + { + configASSERT( ullPortInterruptNesting == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + if( ullCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as the critical section is being + exited. */ + ullCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + priorities must be re-enabled. */ + if( ullCriticalNesting == portNO_CRITICAL_NESTING ) + { + /* Critical nesting has reached zero so all interrupt priorities + should be unmasked. */ + portCLEAR_INTERRUPT_MASK(); + } + } +} +/*-----------------------------------------------------------*/ + +void FreeRTOS_Tick_Handler( void ) +{ + /* Must be the lowest possible priority. */ + configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER == ( uint32_t ) ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); + + /* Interrupts should not be enabled before this point. */ + #if( configASSERT_DEFINED == 1 ) + { + uint32_t ulMaskBits; + + __asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) ); + configASSERT( ( ulMaskBits & portDAIF_I ) != 0 ); + } + #endif /* configASSERT_DEFINED */ + + /* Set interrupt mask before altering scheduler structures. The tick + handler runs at the lowest priority, so interrupts cannot already be masked, + so there is no need to save and restore the current mask value. It is + necessary to turn off interrupts in the CPU itself while the ICCPMR is being + updated. */ + portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); + __asm volatile ( "dsb sy \n" + "isb sy \n" ); + + /* Ok to enable interrupts after the interrupt source has been cleared. */ + configCLEAR_TICK_INTERRUPT(); + portENABLE_INTERRUPTS(); + + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + ullPortYieldRequired = pdTRUE; + } + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_MASK(); +} +/*-----------------------------------------------------------*/ + +void vPortTaskUsesFPU( void ) +{ + /* A task is registering the fact that it needs an FPU context. Set the + FPU flag (which is saved as part of the task context). */ + ullPortTaskHasFPUContext = pdTRUE; + + /* Consider initialising the FPSR here - but probably not necessary in + AArch64. */ +} +/*-----------------------------------------------------------*/ + +void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) +{ + if( uxNewMaskValue == pdFALSE ) + { + portCLEAR_INTERRUPT_MASK(); + } +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxPortSetInterruptMask( void ) +{ +uint32_t ulReturn; + + /* Interrupt in the CPU must be turned off while the ICCPMR is being + updated. */ + portDISABLE_INTERRUPTS(); + if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) + { + /* Interrupts were already masked. */ + ulReturn = pdTRUE; + } + else + { + ulReturn = pdFALSE; + portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); + __asm volatile ( "dsb sy \n" + "isb sy \n" ); + } + portENABLE_INTERRUPTS(); + + return ulReturn; +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. */ + configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); + + /* Priority grouping: The interrupt controller (GIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + The priority grouping is configured by the GIC's binary point register + (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + possible value (which may be above 0). */ + configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); + } + +#endif /* configASSERT_DEFINED */ +/*-----------------------------------------------------------*/ diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portASM.S b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portASM.S new file mode 100644 index 00000000..8a03afef --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portASM.S @@ -0,0 +1,430 @@ +/* + FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + .text + + /* Variables and functions. */ + .extern ullMaxAPIPriorityMask + .extern pxCurrentTCB + .extern vTaskSwitchContext + .extern FreeRTOS_ApplicationIRQHandler + .extern ullPortInterruptNesting + .extern ullPortTaskHasFPUContext + .extern ullCriticalNesting + .extern ullPortYieldRequired + .extern ullICCEOIR + .extern ullICCIAR + .extern _freertos_vector_table + + .global FreeRTOS_IRQ_Handler + .global FreeRTOS_SWI_Handler + .global vPortRestoreTaskContext + + +.macro portSAVE_CONTEXT + + /* Switch to use the EL0 stack pointer. */ + MSR SPSEL, #0 + + /* Save the entire context. */ + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X20, X21, [SP, #-0x10]! + STP X22, X23, [SP, #-0x10]! + STP X24, X25, [SP, #-0x10]! + STP X26, X27, [SP, #-0x10]! + STP X28, X29, [SP, #-0x10]! + STP X30, XZR, [SP, #-0x10]! + + /* Save the SPSR. */ + MRS X3, SPSR_EL3 + + /* Save the ELR. */ + MRS X2, ELR_EL3 + + STP X2, X3, [SP, #-0x10]! + + /* Save the critical section nesting depth. */ + LDR X0, ullCriticalNestingConst + LDR X3, [X0] + + /* Save the FPU context indicator. */ + LDR X0, ullPortTaskHasFPUContextConst + LDR X2, [X0] + + /* Save the FPU context, if any (32 128-bit registers). */ + CMP X2, #0 + B.EQ 1f + STP Q0, Q1, [SP,#-0x20]! + STP Q2, Q3, [SP,#-0x20]! + STP Q4, Q5, [SP,#-0x20]! + STP Q6, Q7, [SP,#-0x20]! + STP Q8, Q9, [SP,#-0x20]! + STP Q10, Q11, [SP,#-0x20]! + STP Q12, Q13, [SP,#-0x20]! + STP Q14, Q15, [SP,#-0x20]! + STP Q16, Q17, [SP,#-0x20]! + STP Q18, Q19, [SP,#-0x20]! + STP Q20, Q21, [SP,#-0x20]! + STP Q22, Q23, [SP,#-0x20]! + STP Q24, Q25, [SP,#-0x20]! + STP Q26, Q27, [SP,#-0x20]! + STP Q28, Q29, [SP,#-0x20]! + STP Q30, Q31, [SP,#-0x20]! + +1: + /* Store the critical nesting count and FPU context indicator. */ + STP X2, X3, [SP, #-0x10]! + + LDR X0, pxCurrentTCBConst + LDR X1, [X0] + MOV X0, SP /* Move SP into X0 for saving. */ + STR X0, [X1] + + /* Switch to use the ELx stack pointer. */ + MSR SPSEL, #1 + + .endm + +; /**********************************************************************/ + +.macro portRESTORE_CONTEXT + + /* Switch to use the EL0 stack pointer. */ + MSR SPSEL, #0 + + /* Set the SP to point to the stack of the task being restored. */ + LDR X0, pxCurrentTCBConst + LDR X1, [X0] + LDR X0, [X1] + MOV SP, X0 + + LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */ + + /* Set the PMR register to be correct for the current critical nesting + depth. */ + LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */ + MOV X1, #255 /* X1 holds the unmask value. */ + LDR X4, ullICCPMRConst /* X4 holds the address of the ICCPMR constant. */ + CMP X3, #0 + LDR X5, [X4] /* X5 holds the address of the ICCPMR register. */ + B.EQ 1f + LDR X6, ullMaxAPIPriorityMaskConst + LDR X1, [X6] /* X1 holds the mask value. */ +1: + STR W1, [X5] /* Write the mask value to ICCPMR. */ + DSB SY /* _RB_Barriers probably not required here. */ + ISB SY + STR X3, [X0] /* Restore the task's critical nesting count. */ + + /* Restore the FPU context indicator. */ + LDR X0, ullPortTaskHasFPUContextConst + STR X2, [X0] + + /* Restore the FPU context, if any. */ + CMP X2, #0 + B.EQ 1f + LDP Q30, Q31, [SP], #0x20 + LDP Q28, Q29, [SP], #0x20 + LDP Q26, Q27, [SP], #0x20 + LDP Q24, Q25, [SP], #0x20 + LDP Q22, Q23, [SP], #0x20 + LDP Q20, Q21, [SP], #0x20 + LDP Q18, Q19, [SP], #0x20 + LDP Q16, Q17, [SP], #0x20 + LDP Q14, Q15, [SP], #0x20 + LDP Q12, Q13, [SP], #0x20 + LDP Q10, Q11, [SP], #0x20 + LDP Q8, Q9, [SP], #0x20 + LDP Q6, Q7, [SP], #0x20 + LDP Q4, Q5, [SP], #0x20 + LDP Q2, Q3, [SP], #0x20 + LDP Q0, Q1, [SP], #0x20 +1: + LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ + + /* Restore the SPSR. */ + MSR SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */ + + /* Restore the ELR. */ + MSR ELR_EL3, X2 + + LDP X30, XZR, [SP], #0x10 + LDP X28, X29, [SP], #0x10 + LDP X26, X27, [SP], #0x10 + LDP X24, X25, [SP], #0x10 + LDP X22, X23, [SP], #0x10 + LDP X20, X21, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + + /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ + MSR SPSEL, #1 + + ERET + + .endm + + +/****************************************************************************** + * FreeRTOS_SWI_Handler handler is used to perform a context switch. + *****************************************************************************/ +.align 8 +.type FreeRTOS_SWI_Handler, %function +FreeRTOS_SWI_Handler: + /* Save the context of the current task and select a new task to run. */ + portSAVE_CONTEXT + + MRS X0, ESR_EL3 + LSR X1, X0, #26 + CMP X1, #0x17 /* 0x17 = SMC instruction. */ + B.NE FreeRTOS_Abort + BL vTaskSwitchContext + + portRESTORE_CONTEXT + +FreeRTOS_Abort: + /* Full ESR is in X0, exception class code is in X1. */ + B . + +/****************************************************************************** + * vPortRestoreTaskContext is used to start the scheduler. + *****************************************************************************/ +.align 8 +.type vPortRestoreTaskContext, %function +vPortRestoreTaskContext: +.set freertos_vector_base, _freertos_vector_table + + /* Install the FreeRTOS interrupt handlers. */ + LDR X1, =freertos_vector_base + MSR VBAR_EL3, X1 + DSB SY + ISB SY + + /* Start the first task. */ + portRESTORE_CONTEXT + + +/****************************************************************************** + * FreeRTOS_IRQ_Handler handles IRQ entry and exit. + *****************************************************************************/ +.align 8 +.type FreeRTOS_IRQ_Handler, %function +FreeRTOS_IRQ_Handler: + /* Save volatile registers. */ + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X29, X30, [SP, #-0x10]! + + /* Save the SPSR and ELR. */ + MRS X3, SPSR_EL3 + MRS X2, ELR_EL3 + STP X2, X3, [SP, #-0x10]! + + /* Increment the interrupt nesting counter. */ + LDR X5, ullPortInterruptNestingConst + LDR X1, [X5] /* Old nesting count in X1. */ + ADD X6, X1, #1 + STR X6, [X5] /* Address of nesting count variable in X5. */ + + /* Maintain the interrupt nesting information across the function call. */ + STP X1, X5, [SP, #-0x10]! + + /* Read value from the interrupt acknowledge register, which is stored in W0 + for future parameter and interrupt clearing use. */ + LDR X2, ullICCIARConst + LDR X3, [X2] + LDR W0, [X3] /* ICCIAR in W0 as parameter. */ + + /* Maintain the ICCIAR value across the function call. */ + STP X0, X1, [SP, #-0x10]! + + /* Call the C handler. */ + BL FreeRTOS_ApplicationIRQHandler + + /* Disable interrupts. */ + MSR DAIFSET, #2 + DSB SY + ISB SY + + /* Restore the ICCIAR value. */ + LDP X0, X1, [SP], #0x10 + + /* End IRQ processing by writing ICCIAR to the EOI register. */ + LDR X4, ullICCEOIRConst + LDR X4, [X4] + STR W0, [X4] + + /* Restore the critical nesting count. */ + LDP X1, X5, [SP], #0x10 + STR X1, [X5] + + /* Has interrupt nesting unwound? */ + CMP X1, #0 + B.NE Exit_IRQ_No_Context_Switch + + /* Is a context switch required? */ + LDR X0, ullPortYieldRequiredConst + LDR X1, [X0] + CMP X1, #0 + B.EQ Exit_IRQ_No_Context_Switch + + /* Reset ullPortYieldRequired to 0. */ + MOV X2, #0 + STR X2, [X0] + + /* Restore volatile registers. */ + LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ + MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ + MSR ELR_EL3, X4 + DSB SY + ISB SY + + LDP X29, X30, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + + /* Save the context of the current task and select a new task to run. */ + portSAVE_CONTEXT + BL vTaskSwitchContext + portRESTORE_CONTEXT + +Exit_IRQ_No_Context_Switch: + /* Restore volatile registers. */ + LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ + MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ + MSR ELR_EL3, X4 + DSB SY + ISB SY + + LDP X29, X30, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + + ERET + + + + +.align 8 +pxCurrentTCBConst: .dword pxCurrentTCB +ullCriticalNestingConst: .dword ullCriticalNesting +ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext + +ullICCPMRConst: .dword ullICCPMR +ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask +vApplicationIRQHandlerConst: .word FreeRTOS_ApplicationIRQHandler +ullPortInterruptNestingConst: .dword ullPortInterruptNesting +ullPortYieldRequiredConst: .dword ullPortYieldRequired +ullICCIARConst: .dword ullICCIAR +ullICCEOIRConst: .dword ullICCEOIR + + + +.end diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portZynqUltrascale.c b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portZynqUltrascale.c new file mode 100644 index 00000000..c967de85 --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portZynqUltrascale.c @@ -0,0 +1,260 @@ +/* + FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Xilinx includes. */ +#include "xttcps.h" +#include "xscugic.h" + +/* Timer used to generate the tick interrupt. */ +static XTtcPs xTimerInstance; +XScuGic xInterruptController; +/*-----------------------------------------------------------*/ + +void FreeRTOS_SetupTickInterrupt( void ) +{ +BaseType_t xStatus; +XTtcPs_Config *pxTimerConfiguration; +uint16_t usInterval; +uint8_t ucPrescale; +const uint8_t ucLevelSensitive = 1; +XScuGic_Config *pxInterruptControllerConfig; + + /* Initialize the interrupt controller driver. */ + pxInterruptControllerConfig = XScuGic_LookupConfig( configINTERRUPT_CONTROLLER_DEVICE_ID ); + XScuGic_CfgInitialize( &xInterruptController, + pxInterruptControllerConfig, + pxInterruptControllerConfig->CpuBaseAddress ); + + /* Connect the interrupt controller interrupt handler to the hardware + interrupt handling logic in the ARM processor. */ + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_IRQ_INT, + ( Xil_ExceptionHandler ) XScuGic_InterruptHandler, + &xInterruptController); + + /* Enable interrupts in the ARM. */ + Xil_ExceptionEnable(); + + pxTimerConfiguration = XTtcPs_LookupConfig( configTIMER_ID ); + + /* Initialise the device. */ + xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); + + if( xStatus != XST_SUCCESS ) + { + /* Not sure how to do this before XTtcPs_CfgInitialize is called as + *xRTOSTickTimerInstance is set within XTtcPs_CfgInitialize(). */ + XTtcPs_Stop( &xTimerInstance ); + xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); + configASSERT( xStatus == XST_SUCCESS ); + } + + /* Set the options. */ + XTtcPs_SetOptions( &xTimerInstance, ( XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE ) ); + + /* Derive values from the tick rate. */ + XTtcPs_CalcIntervalFromFreq( &xTimerInstance, configTICK_RATE_HZ, &( usInterval ), &( ucPrescale ) ); + + /* Set the interval and prescale. */ + XTtcPs_SetInterval( &xTimerInstance, usInterval ); + XTtcPs_SetPrescaler( &xTimerInstance, ucPrescale ); + + /* The priority must be the lowest possible. */ + XScuGic_SetPriorityTriggerType( &xInterruptController, configTIMER_INTERRUPT_ID, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucLevelSensitive ); + + /* Connect to the interrupt controller. */ + XScuGic_Connect( &xInterruptController, + configTIMER_INTERRUPT_ID, + ( Xil_InterruptHandler ) FreeRTOS_Tick_Handler, + ( void * ) &xTimerInstance ); + + /* Enable the interrupt in the GIC. */ + XScuGic_Enable( &xInterruptController, configTIMER_INTERRUPT_ID ); + + /* Enable the interrupts in the timer. */ + XTtcPs_EnableInterrupts( &xTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); + + /* Start the timer. */ + XTtcPs_Start( &xTimerInstance ); +} +/*-----------------------------------------------------------*/ + +void FreeRTOS_ClearTickInterrupt( void ) +{ +volatile uint32_t ulInterruptStatus; + + /* Read the interrupt status, then write it back to clear the interrupt. */ + ulInterruptStatus = XTtcPs_GetInterruptStatus( &xTimerInstance ); + XTtcPs_ClearInterruptStatus( &xTimerInstance, ulInterruptStatus ); + __asm volatile( "DSB SY" ); + __asm volatile( "ISB SY" ); +} +/*-----------------------------------------------------------*/ + +void FreeRTOS_ApplicationIRQHandler( uint32_t ulICCIAR ) +{ +extern const XScuGic_Config XScuGic_ConfigTable[]; +static const XScuGic_VectorTableEntry *pxVectorTable = XScuGic_ConfigTable[ XPAR_SCUGIC_SINGLE_DEVICE_ID ].HandlerTable; +uint32_t ulInterruptID; +const XScuGic_VectorTableEntry *pxVectorEntry; + + /* Interrupts cannot be re-enabled until the source of the interrupt is + cleared. The ID of the interrupt is obtained by bitwise ANDing the ICCIAR + value with 0x3FF. */ + ulInterruptID = ulICCIAR & 0x3FFUL; + if( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS ) + { + /* Call the function installed in the array of installed handler + functions. */ + pxVectorEntry = &( pxVectorTable[ ulInterruptID ] ); + configASSERT( pxVectorEntry ); + pxVectorEntry->Handler( pxVectorEntry->CallBackRef ); + } +} +/*-----------------------------------------------------------*/ + +/* This version of vApplicationAssert() is declared as a weak symbol to allow it +to be overridden by a version implemented within the application that is using +this BSP. */ +void vApplicationAssert( const char *pcFileName, uint32_t ulLine ) +{ +volatile uint32_t ul = 0; +volatile const char *pcLocalFileName = pcFileName; /* To prevent pcFileName being optimized away. */ +volatile uint32_t ulLocalLine = ulLine; /* To prevent ulLine being optimized away. */ + + /* Prevent compile warnings about the following two variables being set but + not referenced. They are intended for viewing in the debugger. */ + ( void ) pcLocalFileName; + ( void ) ulLocalLine; + + xil_printf( "Assert failed in file %s, line %lu\r\n", pcLocalFileName, ulLocalLine ); + + /* If this function is entered then a call to configASSERT() failed in the + FreeRTOS code because of a fatal error. The pcFileName and ulLine + parameters hold the file name and line number in that file of the assert + that failed. Additionally, if using the debugger, the function call stack + can be viewed to find which line failed its configASSERT() test. Finally, + the debugger can be used to set ul to a non-zero value, then step out of + this function to find where the assert function was entered. */ + taskENTER_CRITICAL(); + { + while( ul == 0 ) + { + __asm volatile( "NOP" ); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +/* This default tick hook does nothing and is declared as a weak symbol to allow +the application writer to override this default by providing their own +implementation in the application code. */ +void vApplicationTickHook( void ) +{ +} +/*-----------------------------------------------------------*/ + +/* This default idle hook does nothing and is declared as a weak symbol to allow +the application writer to override this default by providing their own +implementation in the application code. */ +void vApplicationIdleHook( void ) +{ +} +/*-----------------------------------------------------------*/ + +/* This default malloc failed hook does nothing and is declared as a weak symbol +to allow the application writer to override this default by providing their own +implementation in the application code. */ +void vApplicationMallocFailedHook( void ) +{ + xil_printf( "vApplicationMallocFailedHook() called\n" ); +} +/*-----------------------------------------------------------*/ + +/* This default stack overflow hook will stop the application for executing. It +is declared as a weak symbol to allow the application writer to override this +default by providing their own implementation in the application code. */ +void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ) +{ +/* Attempt to prevent the handle and name of the task that overflowed its stack +from being optimised away because they are not used. */ +volatile TaskHandle_t xOverflowingTaskHandle = xTask; +volatile char *pcOverflowingTaskName = pcTaskName; + + ( void ) xOverflowingTaskHandle; + ( void ) pcOverflowingTaskName; + + xil_printf( "HALT: Task %s overflowed its stack.", pcOverflowingTaskName ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} \ No newline at end of file diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port_asm_vectors.S b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port_asm_vectors.S new file mode 100644 index 00000000..da706551 --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/port_asm_vectors.S @@ -0,0 +1,307 @@ +/****************************************************************************** +* +* Copyright (C) 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/*****************************************************************************/ +/** +* @file asm_vectors.s +* +* This file contains the initial vector table for the Cortex A53 processor +* Currently NEON registers are not saved on stack if interrupt is taken. +* It will be implemented. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who     Date     Changes
+* ----- ------- -------- ---------------------------------------------------
+* 5.00	pkp	5/21/14 Initial version
+* 
+* +* @note +* +* None. +* +******************************************************************************/ + + + +.org 0 +.text + +.globl _boot +.globl _vector_table +.globl _freertos_vector_table + +.globl FIQInterrupt +.globl IRQInterrupt +.globl SErrorInterrupt +.globl SynchronousInterrupt + + +.org 0 + +.section .vectors, "a" + +_vector_table: + +.set VBAR, _vector_table + +.org VBAR + b _boot + +.org (VBAR + 0x80) + b . + +.org (VBAR + 0x100) + b . + +.org (VBAR + 0x180) + b . + + +.org (VBAR + 0x200) + b . + +.org (VBAR + 0x280) + b . + +.org (VBAR + 0x300) + b . + +.org (VBAR + 0x380) + b . + + + +.org (VBAR + 0x400) + b . + +.org (VBAR + 0x480) + b . + +.org (VBAR + 0x500) + b . + +.org (VBAR + 0x580) + b . + +.org (VBAR + 0x600) + b . + +.org (VBAR + 0x680) + b . + +.org (VBAR + 0x700) + b . + +.org (VBAR + 0x780) + b . + + + +/****************************************************************************** + * Vector table to use when FreeRTOS is running. + *****************************************************************************/ +.set FREERTOS_VBAR, (VBAR+0x1000) + +.org(FREERTOS_VBAR) +_freertos_vector_table: + b FreeRTOS_SWI_Handler + +.org (FREERTOS_VBAR + 0x80) + b FreeRTOS_IRQ_Handler + +.org (FREERTOS_VBAR + 0x100) + b . + +.org (FREERTOS_VBAR + 0x180) + b . + +.org (FREERTOS_VBAR + 0x200) + b FreeRTOS_SWI_Handler + +.org (FREERTOS_VBAR + 0x280) + b FreeRTOS_IRQ_Handler + +.org (FREERTOS_VBAR + 0x300) + b . + +.org (FREERTOS_VBAR + 0x380) + b . + +.org (FREERTOS_VBAR + 0x400) + b . + +.org (FREERTOS_VBAR + 0x480) + b . + +.org (FREERTOS_VBAR + 0x500) + b . + +.org (FREERTOS_VBAR + 0x580) + b . + +.org (FREERTOS_VBAR + 0x600) + b . + +.org (FREERTOS_VBAR + 0x680) + b . + +.org (FREERTOS_VBAR + 0x700) + b . + +.org (FREERTOS_VBAR + 0x780) + b . + +.org (FREERTOS_VBAR + 0x800) + + + + +SynchronousInterruptHandler: + stp X0,X1, [sp,#-0x10]! + stp X2,X3, [sp,#-0x10]! + stp X4,X5, [sp,#-0x10]! + stp X6,X7, [sp,#-0x10]! + stp X8,X9, [sp,#-0x10]! + stp X10,X11, [sp,#-0x10]! + stp X12,X13, [sp,#-0x10]! + stp X14,X15, [sp,#-0x10]! + stp X16,X17, [sp,#-0x10]! + stp X18,X19, [sp,#-0x10]! + stp X29,X30, [sp,#-0x10]! + + bl SynchronousInterrupt + + ldp X29,X30, [sp], #0x10 + ldp X18,X19, [sp], #0x10 + ldp X16,X17, [sp], #0x10 + ldp X14,X15, [sp], #0x10 + ldp X12,X13, [sp], #0x10 + ldp X10,X11, [sp], #0x10 + ldp X8,X9, [sp], #0x10 + ldp X6,X7, [sp], #0x10 + ldp X4,X5, [sp], #0x10 + ldp X2,X3, [sp], #0x10 + ldp X0,X1, [sp], #0x10 + + eret + +IRQInterruptHandler: + stp X0,X1, [sp,#-0x10]! + stp X2,X3, [sp,#-0x10]! + stp X4,X5, [sp,#-0x10]! + stp X6,X7, [sp,#-0x10]! + stp X8,X9, [sp,#-0x10]! + stp X10,X11, [sp,#-0x10]! + stp X12,X13, [sp,#-0x10]! + stp X14,X15, [sp,#-0x10]! + stp X16,X17, [sp,#-0x10]! + stp X18,X19, [sp,#-0x10]! + stp X29,X30, [sp,#-0x10]! + + bl IRQInterrupt + + ldp X29,X30, [sp], #0x10 + ldp X18,X19, [sp], #0x10 + ldp X16,X17, [sp], #0x10 + ldp X14,X15, [sp], #0x10 + ldp X12,X13, [sp], #0x10 + ldp X10,X11, [sp], #0x10 + ldp X8,X9, [sp], #0x10 + ldp X6,X7, [sp], #0x10 + ldp X4,X5, [sp], #0x10 + ldp X2,X3, [sp], #0x10 + ldp X0,X1, [sp], #0x10 + + eret + +FIQInterruptHandler: + + stp X0,X1, [sp,#-0x10]! + stp X2,X3, [sp,#-0x10]! + stp X4,X5, [sp,#-0x10]! + stp X6,X7, [sp,#-0x10]! + stp X8,X9, [sp,#-0x10]! + stp X10,X11, [sp,#-0x10]! + stp X12,X13, [sp,#-0x10]! + stp X14,X15, [sp,#-0x10]! + stp X16,X17, [sp,#-0x10]! + stp X18,X19, [sp,#-0x10]! + stp X29,X30, [sp,#-0x10]! + + bl FIQInterrupt + + ldp X29,X30, [sp], #0x10 + ldp X18,X19, [sp], #0x10 + ldp X16,X17, [sp], #0x10 + ldp X14,X15, [sp], #0x10 + ldp X12,X13, [sp], #0x10 + ldp X10,X11, [sp], #0x10 + ldp X8,X9, [sp], #0x10 + ldp X6,X7, [sp], #0x10 + ldp X4,X5, [sp], #0x10 + ldp X2,X3, [sp], #0x10 + ldp X0,X1, [sp], #0x10 + + eret + +SErrorInterruptHandler: + + stp X0,X1, [sp,#-0x10]! + stp X2,X3, [sp,#-0x10]! + stp X4,X5, [sp,#-0x10]! + stp X6,X7, [sp,#-0x10]! + stp X8,X9, [sp,#-0x10]! + stp X10,X11, [sp,#-0x10]! + stp X12,X13, [sp,#-0x10]! + stp X14,X15, [sp,#-0x10]! + stp X16,X17, [sp,#-0x10]! + stp X18,X19, [sp,#-0x10]! + stp X29,X30, [sp,#-0x10]! + + bl SErrorInterrupt + + ldp X29,X30, [sp], #0x10 + ldp X18,X19, [sp], #0x10 + ldp X16,X17, [sp], #0x10 + ldp X14,X15, [sp], #0x10 + ldp X12,X13, [sp], #0x10 + ldp X10,X11, [sp], #0x10 + ldp X8,X9, [sp], #0x10 + ldp X6,X7, [sp], #0x10 + ldp X4,X5, [sp], #0x10 + ldp X2,X3, [sp], #0x10 + ldp X0,X1, [sp], #0x10 + + eret + +.end diff --git a/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portmacro.h b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portmacro.h new file mode 100644 index 00000000..e2f687b5 --- /dev/null +++ b/ThirdParty/bsp/freertos821_xilinx/src/Source/portable/GCC/ARM_CA53/portmacro.h @@ -0,0 +1,247 @@ +/* + FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the given hardware + * and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE size_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef uint64_t UBaseType_t; + +typedef uint64_t TickType_t; +#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do +not need to be guarded with a critical section. */ +#define portTICK_TYPE_IS_ATOMIC 1 + +/*-----------------------------------------------------------*/ + +/* Hardware specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 16 +#define portPOINTER_SIZE_TYPE uint64_t + +/*-----------------------------------------------------------*/ + +/* Task utilities. */ + +/* Called at the end of an ISR that can cause a context switch. */ +#define portEND_SWITCHING_ISR( xSwitchRequired )\ +{ \ +extern uint64_t ullPortYieldRequired; \ + \ + if( xSwitchRequired != pdFALSE ) \ + { \ + ullPortYieldRequired = pdTRUE; \ + } \ +} + +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +#define portYIELD() __asm volatile ( "SMC 0" ) + +/*----------------------------------------------------------- + * Critical section control + *----------------------------------------------------------*/ + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern UBaseType_t uxPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ); +extern void vPortInstallFreeRTOSVectorTable( void ); + +#define portDISABLE_INTERRUPTS() \ + __asm volatile ( "MSR DAIFSET, #2" ); \ + __asm volatile ( "DSB SY" ); \ + __asm volatile ( "ISB SY" ); + +#define portENABLE_INTERRUPTS() \ + __asm volatile ( "MSR DAIFCLR, #2" ); \ + __asm volatile ( "DSB SY" ); \ + __asm volatile ( "ISB SY" ); + + +/* These macros do not globally disable/enable interrupts. They do mask off +interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ +#define portENTER_CRITICAL() vPortEnterCritical(); +#define portEXIT_CRITICAL() vPortExitCritical(); +#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not required for this port but included in case common demo code that uses these +macros is used. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +/* Prototype of the FreeRTOS tick handler. This must be installed as the +handler for whichever peripheral is used to generate the RTOS tick. */ +void FreeRTOS_Tick_Handler( void ); + +/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() +before any floating point instructions are executed. */ +void vPortTaskUsesFPU( void ); +#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() + +#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif /* configASSERT */ + +#define portNOP() __asm volatile( "NOP" ) +#define portINLINE __inline + +#ifdef __cplusplus + } /* extern C */ +#endif + + +/* The number of bits to shift for an interrupt priority is dependent on the +number of bits implemented by the interrupt controller. */ +#if configUNIQUE_INTERRUPT_PRIORITIES == 16 + #define portPRIORITY_SHIFT 4 + #define portMAX_BINARY_POINT_VALUE 3 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 32 + #define portPRIORITY_SHIFT 3 + #define portMAX_BINARY_POINT_VALUE 2 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 64 + #define portPRIORITY_SHIFT 2 + #define portMAX_BINARY_POINT_VALUE 1 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 128 + #define portPRIORITY_SHIFT 1 + #define portMAX_BINARY_POINT_VALUE 0 +#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 + #define portPRIORITY_SHIFT 0 + #define portMAX_BINARY_POINT_VALUE 0 +#else + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware +#endif + +/* Interrupt controller access addresses. */ +#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) +#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C ) +#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 ) +#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 ) +#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 ) + +#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) +#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) ) +#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ) +#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET ) +#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) +#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) ) +#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) ) + +#endif /* PORTMACRO_H */