diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index e2149d5e1..ba8abfdf8 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -54,6 +54,7 @@ bics BISR BODIEN BODSTS +brealid BRGR brhi brne diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index bae32c966..b29209c10 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -1,6 +1,13 @@ name: FreeRTOS-Kernel Demos on: [push, pull_request] +env: + # The bash escape character is \033 + bashPass: \033[32;1mPASSED - + bashInfo: \033[33;1mINFO - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + jobs: WIN32-MSVC: name: WIN32 MSVC @@ -147,6 +154,92 @@ jobs: working-directory: FreeRTOS/Demo/msp430_GCC run: make -j + MicroBlaze-GCC: + name: GCC MicroBlaze Toolchain + runs-on: ubuntu-latest + steps: + - name: Checkout the FreeRTOS/FreeRTOS Repository + uses: actions/checkout@v3 + with: + ref: main + repository: FreeRTOS/FreeRTOS + fetch-depth: 1 + + - env: + stepName: Fetch Community-Supported-Demos Submodule + shell: bash + run: | + # Fetch Community-Supported-Demos Submodule + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos + # This repository contains the microblaze_instructions.h header file + git clone https://github.com/Xilinx/embeddedsw.git --branch xilinx_v2023.1 + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + + # Checkout user pull request changes + - name: Checkout Pull Request + uses: actions/checkout@v3 + with: + path: ./FreeRTOS/Source + + - env: + stepName: Install Dependancies + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + sudo apt update -y + sudo apt upgrade -y + sudo apt install -y build-essential m4 debhelper bison texinfo dejagnu flex + sudo apt install -y autogen gawk libgmp-dev libmpc-dev libmpfr-dev + sudo apt install -y patchutils sharutils zlib1g-dev autoconf2.64 + + # Download the mb-gcc toolchain from github + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/binutils-microblaze_2.35-2021-0623+1_amd64.deb; + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/gcc-microblaze_10.2.0-2021-0623+2_amd64.deb; + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-dev_3.3.0-2021-0623+3_all.deb; + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-doc_3.3.0-2021-0623+3_all.deb; + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze_3.3.0-2021-0623+3_all.deb; + curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/newlib-source_3.3.0-2021-0623+3_all.deb; + + # Install the packages for the toolchain + sudo apt install -y ./binutils-microblaze*.deb; + sudo apt install -y ./gcc-microblaze*.deb; + sudo apt install -y ./libnewlib-microblaze-dev*.deb; + sudo apt install -y ./libnewlib-microblaze-doc*.deb; + sudo apt install -y ./libnewlib-microblaze*.deb; + sudo apt install -y ./newlib-source*.deb; + + # Validate that the toolchain is in the path and can be called + which mb-gcc + mb-gcc --version + + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + + - env: + stepName: Compile Microblaze Port + shell: bash + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + # Compile MicroBlazeV9 Port files to validate they build + mb-gcc -mcpu=v9.5 -c \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/port.c \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/portasm.S \ + FreeRTOS/Source/portable/GCC/MicroBlazeV9/port_exceptions.c \ + FreeRTOS/Source/tasks.c \ + FreeRTOS/Source/list.c \ + -I embeddedsw/lib/bsp/standalone/src/microblaze \ + -I FreeRTOS/Source/portable/GCC/MicroBlazeV9/ \ + -I FreeRTOS/Source/include \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/RTOSDemo/src \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/standalone_v5_4/src \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/include \ + -I FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/intc_v3_5/src + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + + ARM-GCC: name: GNU ARM Toolchain runs-on: ubuntu-latest @@ -164,7 +257,7 @@ jobs: # Fetch Community-Supported-Demos Submodule echo "::group::Fetch Community-Supported-Demos Submodule" git submodule update --checkout --init --depth 1 FreeRTOS/Demo/ThirdParty/Community-Supported-Demos - echo "::engdroup::" + echo "::endgroup::" if [ "$?" = "0" ]; then echo -e "\033[32;3mCloned the Community-Supported-Demos\033[0m" else diff --git a/portable/GCC/MicroBlazeV9/port.c b/portable/GCC/MicroBlazeV9/port.c index fd5de1527..25c9ac357 100644 --- a/portable/GCC/MicroBlazeV9/port.c +++ b/portable/GCC/MicroBlazeV9/port.c @@ -42,6 +42,7 @@ #include #include #include +#include /* Tasks are started with a critical section nesting of 0 - however, prior to * the scheduler being commenced interrupts should not be enabled, so the critical @@ -58,6 +59,13 @@ * given to the FSR register when the initial context is set up for a task being * created. */ #define portINITIAL_FSR ( 0U ) +/* + * Global counter used for calculation of run time statistics of tasks. + * Defined only when the relevant option is turned on + */ +#if (configGENERATE_RUN_TIME_STATS==1) + volatile uint32_t ulHighFrequencyTimerTicks; +#endif /*-----------------------------------------------------------*/ @@ -116,10 +124,11 @@ static XIntc xInterruptControllerInstance; void * pvParameters ) #endif { - extern void * _SDA2_BASE_; - extern void * _SDA_BASE_; - const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_; - const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_; + extern void *_SDA2_BASE_; + extern void *_SDA_BASE_; + const UINTPTR ulR2 = ( UINTPTR ) &_SDA2_BASE_; + const UINTPTR ulR13 = ( UINTPTR ) &_SDA_BASE_; + extern void _start1( void ); /* Place a few bytes of known values on the bottom of the stack. @@ -255,8 +264,8 @@ static XIntc xInterruptControllerInstance; BaseType_t xPortStartScheduler( void ) { - extern void( vPortStartFirstTask )( void ); - extern uint32_t _stack[]; + extern void ( vPortStartFirstTask )( void ); + extern UINTPTR _stack[]; /* Setup the hardware to generate the tick. Interrupts are disabled when * this function is called. @@ -270,7 +279,7 @@ BaseType_t xPortStartScheduler( void ) vApplicationSetupTimerInterrupt(); /* Reuse the stack from main() as the stack for the interrupts/exceptions. */ - pulISRStack = ( uint32_t * ) _stack; + pulISRStack = ( UINTPTR * ) _stack; /* Ensure there is enough space for the functions called from the interrupt * service routines to write back into the stack frame of the caller. */ @@ -304,13 +313,18 @@ void vPortYield( void ) * not interrupted by the tick ISR. It is not a problem to do this as * each task maintains its own interrupt status. */ portENTER_CRITICAL(); - { - /* Jump directly to the yield function to ensure there is no - * compiler generated prologue code. */ - asm volatile ( "bralid r14, VPortYieldASM \n\t" \ - "or r0, r0, r0 \n\t" ); - } - portEXIT_CRITICAL(); + { + /* Jump directly to the yield function to ensure there is no + * compiler generated prologue code. */ + #ifdef __arch64__ + asm volatile ( "brealid r14, VPortYieldASM \n\t" \ + "or r0, r0, r0 \n\t" ); + #else + asm volatile ( "bralid r14, VPortYieldASM \n\t" \ + "or r0, r0, r0 \n\t" ); + #endif + } + portEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ @@ -434,22 +448,34 @@ void vPortTickISR( void * pvUnused ) { extern void vApplicationClearTimerInterrupt( void ); - /* Ensure the unused parameter does not generate a compiler warning. */ - ( void ) pvUnused; + /* Ensure the unused parameter does not generate a compiler warning. */ + ( void ) pvUnused; - /* This port uses an application defined callback function to clear the tick - * interrupt because the kernel will run on lots of different MicroBlaze and - * FPGA configurations - not all of which will have the same timer peripherals - * defined or available. An example definition of - * vApplicationClearTimerInterrupt() is provided in the official demo - * application that accompanies this port. */ - vApplicationClearTimerInterrupt(); - - /* Increment the RTOS tick - this might cause a task to unblock. */ - if( xTaskIncrementTick() != pdFALSE ) + /* The Xilinx implementation of generating run time task stats uses the same timer used for generating + * FreeRTOS ticks. In case user decides to generate run time stats the tick handler is called more + * frequently (10 times faster). The timer ick handler uses logic to handle the same. It handles + * the FreeRTOS tick once per 10 interrupts. + * For handling generation of run time stats, it increments a pre-defined counter every time the + * interrupt handler executes. */ +#if (configGENERATE_RUN_TIME_STATS == 1) + ulHighFrequencyTimerTicks++; + if (!(ulHighFrequencyTimerTicks % 10)) +#endif { - /* Force vTaskSwitchContext() to be called as the interrupt exits. */ - ulTaskSwitchRequested = 1; + /* This port uses an application defined callback function to clear the tick + * interrupt because the kernel will run on lots of different MicroBlaze and + * FPGA configurations - not all of which will have the same timer peripherals + * defined or available. An example definition of + * vApplicationClearTimerInterrupt() is provided in the official demo + * application that accompanies this port. */ + vApplicationClearTimerInterrupt(); + + /* Increment the RTOS tick - this might cause a task to unblock. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Force vTaskSwitchContext() to be called as the interrupt exits. */ + ulTaskSwitchRequested = 1; + } } } /*-----------------------------------------------------------*/ @@ -495,4 +521,25 @@ static int32_t prvInitialiseInterruptController( void ) return lStatus; } + +#if( configGENERATE_RUN_TIME_STATS == 1 ) +/* + * For Xilinx implementation this is a dummy function that does a redundant operation + * of zeroing out the global counter. + * It is called by FreeRTOS kernel. + */ +void xCONFIGURE_TIMER_FOR_RUN_TIME_STATS (void) +{ + ulHighFrequencyTimerTicks = 0; +} +/* + * For Xilinx implementation this function returns the global counter used for + * run time task stats calculation. + * It is called by FreeRTOS kernel task handling logic. + */ +uint32_t xGET_RUN_TIME_COUNTER_VALUE (void) +{ + return ulHighFrequencyTimerTicks; +} +#endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/MicroBlazeV9/port_exceptions.c b/portable/GCC/MicroBlazeV9/port_exceptions.c index e2347732d..f89e47b0a 100644 --- a/portable/GCC/MicroBlazeV9/port_exceptions.c +++ b/portable/GCC/MicroBlazeV9/port_exceptions.c @@ -67,7 +67,7 @@ /* This variable is set in the exception entry code, before * vPortExceptionHandler is called. */ - uint32_t * pulStackPointerOnFunctionEntry = NULL; + UINTPTR *pulStackPointerOnFunctionEntry = NULL; /* This is the structure that is filled with the MicroBlaze context as it * existed immediately prior to the exception occurrence. A pointer to this @@ -80,7 +80,6 @@ * in portasm.S. */ void vPortExceptionHandler( void * pvExceptionID ); extern void vPortExceptionHandlerEntry( void * pvExceptionID ); - /*-----------------------------------------------------------*/ /* vApplicationExceptionRegisterDump() is a callback function that the @@ -149,7 +148,7 @@ xRegisterDump.ulR29 = mfgpr( R29 ); xRegisterDump.ulR30 = mfgpr( R30 ); xRegisterDump.ulR31 = mfgpr( R31 ); - xRegisterDump.ulR1_SP = ( ( uint32_t ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE; + xRegisterDump.ulR1_SP = ( ( UINTPTR ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE; xRegisterDump.ulEAR = mfear(); xRegisterDump.ulESR = mfesr(); xRegisterDump.ulEDR = mfedr(); diff --git a/portable/GCC/MicroBlazeV9/portasm.S b/portable/GCC/MicroBlazeV9/portasm.S index 2114d00e8..0a5e658d9 100644 --- a/portable/GCC/MicroBlazeV9/portasm.S +++ b/portable/GCC/MicroBlazeV9/portasm.S @@ -33,63 +33,97 @@ #include "microblaze_exceptions_g.h" #include "xparameters.h" +#include "microblaze_instructions.h" +/* The context is oversized to allow functions called from the ISR to write +back into the caller stack. */ +#if defined (__arch64__) +#if( XPAR_MICROBLAZE_USE_FPU != 0 ) + #define portCONTEXT_SIZE 272 + #define portMINUS_CONTEXT_SIZE -272 +#else + #define portCONTEXT_SIZE 264 + #define portMINUS_CONTEXT_SIZE -264 +#endif +#else +#if( XPAR_MICROBLAZE_USE_FPU != 0 ) + #define portCONTEXT_SIZE 136 + #define portMINUS_CONTEXT_SIZE -136 +#else + #define portCONTEXT_SIZE 132 + #define portMINUS_CONTEXT_SIZE -132 +#endif +#endif + /* Offsets from the stack pointer at which saved registers are placed. */ -#define portR31_OFFSET 4 -#define portR30_OFFSET 8 -#define portR29_OFFSET 12 -#define portR28_OFFSET 16 -#define portR27_OFFSET 20 -#define portR26_OFFSET 24 -#define portR25_OFFSET 28 -#define portR24_OFFSET 32 -#define portR23_OFFSET 36 -#define portR22_OFFSET 40 -#define portR21_OFFSET 44 -#define portR20_OFFSET 48 -#define portR19_OFFSET 52 -#define portR18_OFFSET 56 -#define portR17_OFFSET 60 -#define portR16_OFFSET 64 -#define portR15_OFFSET 68 -#define portR14_OFFSET 72 -#define portR13_OFFSET 76 -#define portR12_OFFSET 80 -#define portR11_OFFSET 84 -#define portR10_OFFSET 88 -#define portR9_OFFSET 92 -#define portR8_OFFSET 96 -#define portR7_OFFSET 100 -#define portR6_OFFSET 104 -#define portR5_OFFSET 108 -#define portR4_OFFSET 112 -#define portR3_OFFSET 116 -#define portR2_OFFSET 120 +#if defined (__arch64__) +#define portR31_OFFSET 8 +#define portR30_OFFSET 16 +#define portR29_OFFSET 24 +#define portR28_OFFSET 32 +#define portR27_OFFSET 40 +#define portR26_OFFSET 48 +#define portR25_OFFSET 56 +#define portR24_OFFSET 64 +#define portR23_OFFSET 72 +#define portR22_OFFSET 80 +#define portR21_OFFSET 88 +#define portR20_OFFSET 96 +#define portR19_OFFSET 104 +#define portR18_OFFSET 112 +#define portR17_OFFSET 120 +#define portR16_OFFSET 128 +#define portR15_OFFSET 136 +#define portR14_OFFSET 144 +#define portR13_OFFSET 152 +#define portR12_OFFSET 160 +#define portR11_OFFSET 168 +#define portR10_OFFSET 176 +#define portR9_OFFSET 184 +#define portR8_OFFSET 192 +#define portR7_OFFSET 200 +#define portR6_OFFSET 208 +#define portR5_OFFSET 216 +#define portR4_OFFSET 224 +#define portR3_OFFSET 232 +#define portR2_OFFSET 240 +#define portCRITICAL_NESTING_OFFSET 248 +#define portMSR_OFFSET 256 +#define portFSR_OFFSET 264 +#else +#define portR31_OFFSET 4 +#define portR30_OFFSET 8 +#define portR29_OFFSET 12 +#define portR28_OFFSET 16 +#define portR27_OFFSET 20 +#define portR26_OFFSET 24 +#define portR25_OFFSET 28 +#define portR24_OFFSET 32 +#define portR23_OFFSET 36 +#define portR22_OFFSET 40 +#define portR21_OFFSET 44 +#define portR20_OFFSET 48 +#define portR19_OFFSET 52 +#define portR18_OFFSET 56 +#define portR17_OFFSET 60 +#define portR16_OFFSET 64 +#define portR15_OFFSET 68 +#define portR14_OFFSET 72 +#define portR13_OFFSET 76 +#define portR12_OFFSET 80 +#define portR11_OFFSET 84 +#define portR10_OFFSET 88 +#define portR9_OFFSET 92 +#define portR8_OFFSET 96 +#define portR7_OFFSET 100 +#define portR6_OFFSET 104 +#define portR5_OFFSET 108 +#define portR4_OFFSET 112 +#define portR3_OFFSET 116 +#define portR2_OFFSET 120 #define portCRITICAL_NESTING_OFFSET 124 #define portMSR_OFFSET 128 +#define portFSR_OFFSET 132 -#if( XPAR_MICROBLAZE_USE_FPU != 0 ) - #define portFSR_OFFSET 132 - #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) - #define portSLR_OFFSET 136 - #define portSHR_OFFSET 140 - - #define portCONTEXT_SIZE 144 - #define portMINUS_CONTEXT_SIZE -144 - #else - #define portCONTEXT_SIZE 136 - #define portMINUS_CONTEXT_SIZE -136 - #endif -#else - #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) - #define portSLR_OFFSET 132 - #define portSHR_OFFSET 136 - - #define portCONTEXT_SIZE 140 - #define portMINUS_CONTEXT_SIZE -140 - #else - #define portCONTEXT_SIZE 132 - #define portMINUS_CONTEXT_SIZE -132 - #endif #endif .extern pxCurrentTCB @@ -109,54 +143,54 @@ .macro portSAVE_CONTEXT - /* Make room for the context on the stack. */ - addik r1, r1, portMINUS_CONTEXT_SIZE + /* Make room for the context on the stack. */ + ADDLIK r1, r1, portMINUS_CONTEXT_SIZE - /* Stack general registers. */ - swi r31, r1, portR31_OFFSET - swi r30, r1, portR30_OFFSET - swi r29, r1, portR29_OFFSET - swi r28, r1, portR28_OFFSET - swi r27, r1, portR27_OFFSET - swi r26, r1, portR26_OFFSET - swi r25, r1, portR25_OFFSET - swi r24, r1, portR24_OFFSET - swi r23, r1, portR23_OFFSET - swi r22, r1, portR22_OFFSET - swi r21, r1, portR21_OFFSET - swi r20, r1, portR20_OFFSET - swi r19, r1, portR19_OFFSET - swi r18, r1, portR18_OFFSET - swi r17, r1, portR17_OFFSET - swi r16, r1, portR16_OFFSET - swi r15, r1, portR15_OFFSET - /* R14 is saved later as it needs adjustment if a yield is performed. */ - swi r13, r1, portR13_OFFSET - swi r12, r1, portR12_OFFSET - swi r11, r1, portR11_OFFSET - swi r10, r1, portR10_OFFSET - swi r9, r1, portR9_OFFSET - swi r8, r1, portR8_OFFSET - swi r7, r1, portR7_OFFSET - swi r6, r1, portR6_OFFSET - swi r5, r1, portR5_OFFSET - swi r4, r1, portR4_OFFSET - swi r3, r1, portR3_OFFSET - swi r2, r1, portR2_OFFSET + /* Stack general registers. */ + SI r31, r1, portR31_OFFSET + SI r30, r1, portR30_OFFSET + SI r29, r1, portR29_OFFSET + SI r28, r1, portR28_OFFSET + SI r27, r1, portR27_OFFSET + SI r26, r1, portR26_OFFSET + SI r25, r1, portR25_OFFSET + SI r24, r1, portR24_OFFSET + SI r23, r1, portR23_OFFSET + SI r22, r1, portR22_OFFSET + SI r21, r1, portR21_OFFSET + SI r20, r1, portR20_OFFSET + SI r19, r1, portR19_OFFSET + SI r18, r1, portR18_OFFSET + SI r17, r1, portR17_OFFSET + SI r16, r1, portR16_OFFSET + SI r15, r1, portR15_OFFSET + /* R14 is saved later as it needs adjustment if a yield is performed. */ + SI r13, r1, portR13_OFFSET + SI r12, r1, portR12_OFFSET + SI r11, r1, portR11_OFFSET + SI r10, r1, portR10_OFFSET + SI r9, r1, portR9_OFFSET + SI r8, r1, portR8_OFFSET + SI r7, r1, portR7_OFFSET + SI r6, r1, portR6_OFFSET + SI r5, r1, portR5_OFFSET + SI r4, r1, portR4_OFFSET + SI r3, r1, portR3_OFFSET + SI r2, r1, portR2_OFFSET - /* Stack the critical section nesting value. */ - lwi r18, r0, uxCriticalNesting - swi r18, r1, portCRITICAL_NESTING_OFFSET + /* Stack the critical section nesting value. */ + LI r18, r0, uxCriticalNesting + SI r18, r1, portCRITICAL_NESTING_OFFSET - /* Stack MSR. */ - mfs r18, rmsr - swi r18, r1, portMSR_OFFSET + /* Stack MSR. */ + mfs r18, rmsr + SI r18, r1, portMSR_OFFSET - #if( XPAR_MICROBLAZE_USE_FPU != 0 ) - /* Stack FSR. */ - mfs r18, rfsr - swi r18, r1, portFSR_OFFSET - #endif + #if( XPAR_MICROBLAZE_USE_FPU != 0 ) + /* Stack FSR. */ + mfs r18, rfsr + SI r18, r1, portFSR_OFFSET + #endif #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) /* Save the stack limits */ @@ -166,17 +200,17 @@ swi r18, r1, portSHR_OFFSET #endif - /* Save the top of stack value to the TCB. */ - lwi r3, r0, pxCurrentTCB - sw r1, r0, r3 + /* Save the top of stack value to the TCB. */ + LI r3, r0, pxCurrentTCB + STORE r1, r0, r3 .endm .macro portRESTORE_CONTEXT - /* Load the top of stack value from the TCB. */ - lwi r18, r0, pxCurrentTCB - lw r1, r0, r18 + /* Load the top of stack value from the TCB. */ + LI r18, r0, pxCurrentTCB + LOAD r1, r0, r18 #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) /* Restore the stack limits -- must not load from r1 (Stack Pointer) @@ -189,101 +223,112 @@ mts rshr, r12 #endif - /* Restore the general registers. */ - lwi r31, r1, portR31_OFFSET - lwi r30, r1, portR30_OFFSET - lwi r29, r1, portR29_OFFSET - lwi r28, r1, portR28_OFFSET - lwi r27, r1, portR27_OFFSET - lwi r26, r1, portR26_OFFSET - lwi r25, r1, portR25_OFFSET - lwi r24, r1, portR24_OFFSET - lwi r23, r1, portR23_OFFSET - lwi r22, r1, portR22_OFFSET - lwi r21, r1, portR21_OFFSET - lwi r20, r1, portR20_OFFSET - lwi r19, r1, portR19_OFFSET - lwi r17, r1, portR17_OFFSET - lwi r16, r1, portR16_OFFSET - lwi r15, r1, portR15_OFFSET - lwi r14, r1, portR14_OFFSET - lwi r13, r1, portR13_OFFSET - lwi r12, r1, portR12_OFFSET - lwi r11, r1, portR11_OFFSET - lwi r10, r1, portR10_OFFSET - lwi r9, r1, portR9_OFFSET - lwi r8, r1, portR8_OFFSET - lwi r7, r1, portR7_OFFSET - lwi r6, r1, portR6_OFFSET - lwi r5, r1, portR5_OFFSET - lwi r4, r1, portR4_OFFSET - lwi r3, r1, portR3_OFFSET - lwi r2, r1, portR2_OFFSET + /* Restore the general registers. */ + LI r31, r1, portR31_OFFSET + LI r30, r1, portR30_OFFSET + LI r29, r1, portR29_OFFSET + LI r28, r1, portR28_OFFSET + LI r27, r1, portR27_OFFSET + LI r26, r1, portR26_OFFSET + LI r25, r1, portR25_OFFSET + LI r24, r1, portR24_OFFSET + LI r23, r1, portR23_OFFSET + LI r22, r1, portR22_OFFSET + LI r21, r1, portR21_OFFSET + LI r20, r1, portR20_OFFSET + LI r19, r1, portR19_OFFSET + LI r17, r1, portR17_OFFSET + LI r16, r1, portR16_OFFSET + LI r15, r1, portR15_OFFSET + LI r14, r1, portR14_OFFSET + LI r13, r1, portR13_OFFSET + LI r12, r1, portR12_OFFSET + LI r11, r1, portR11_OFFSET + LI r10, r1, portR10_OFFSET + LI r9, r1, portR9_OFFSET + LI r8, r1, portR8_OFFSET + LI r7, r1, portR7_OFFSET + LI r6, r1, portR6_OFFSET + LI r5, r1, portR5_OFFSET + LI r4, r1, portR4_OFFSET + LI r3, r1, portR3_OFFSET + LI r2, r1, portR2_OFFSET - /* Reload the rmsr from the stack. */ - lwi r18, r1, portMSR_OFFSET - mts rmsr, r18 + /* Reload the rmsr from the stack. */ + LI r18, r1, portMSR_OFFSET + mts rmsr, r18 - #if( XPAR_MICROBLAZE_USE_FPU != 0 ) - /* Reload the FSR from the stack. */ - lwi r18, r1, portFSR_OFFSET - mts rfsr, r18 - #endif + #if( XPAR_MICROBLAZE_USE_FPU != 0 ) + /* Reload the FSR from the stack. */ + LI r18, r1, portFSR_OFFSET + mts rfsr, r18 + #endif - /* Load the critical nesting value. */ - lwi r18, r1, portCRITICAL_NESTING_OFFSET - swi r18, r0, uxCriticalNesting + /* Load the critical nesting value. */ + LI r18, r1, portCRITICAL_NESTING_OFFSET + SI r18, r0, uxCriticalNesting - /* Test the critical nesting value. If it is non zero then the task last - exited the running state using a yield. If it is zero, then the task - last exited the running state through an interrupt. */ - xori r18, r18, 0 - bnei r18, exit_from_yield + /* Test the critical nesting value. If it is non zero then the task last + exited the running state using a yield. If it is zero, then the task + last exited the running state through an interrupt. */ + XORI r18, r18, 0 + BNEI r18, exit_from_yield - /* r18 was being used as a temporary. Now restore its true value from the - stack. */ - lwi r18, r1, portR18_OFFSET + /* r18 was being used as a temporary. Now restore its true value from the + stack. */ + LI r18, r1, portR18_OFFSET - /* Remove the stack frame. */ - addik r1, r1, portCONTEXT_SIZE + /* Remove the stack frame. */ + ADDLIK r1, r1, portCONTEXT_SIZE - /* Return using rtid so interrupts are re-enabled as this function is - exited. */ - rtid r14, 0 - or r0, r0, r0 + /* Return using rtid so interrupts are re-enabled as this function is + exited. */ + rtid r14, 0 + OR r0, r0, r0 - .endm + .endm /* This function is used to exit portRESTORE_CONTEXT() if the task being returned to last left the Running state by calling taskYIELD() (rather than being preempted by an interrupt). */ - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + exit_from_yield: - /* r18 was being used as a temporary. Now restore its true value from the - stack. */ - lwi r18, r1, portR18_OFFSET + /* r18 was being used as a temporary. Now restore its true value from the + stack. */ + LI r18, r1, portR18_OFFSET - /* Remove the stack frame. */ - addik r1, r1, portCONTEXT_SIZE + /* Remove the stack frame. */ + ADDLIK r1, r1, portCONTEXT_SIZE - /* Return to the task. */ - rtsd r14, 0 - or r0, r0, r0 + /* Return to the task. */ + rtsd r14, 0 + OR r0, r0, r0 - .text - .align 4 + .text + +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + _interrupt_handler: portSAVE_CONTEXT - /* Stack the return address. */ - swi r14, r1, portR14_OFFSET + /* Stack the return address. */ + SI r14, r1, portR14_OFFSET - /* Switch to the ISR stack. */ - lwi r1, r0, pulISRStack + /* Switch to the ISR stack. */ + LI r1, r0, pulISRStack #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) ori r18, r0, _stack_end @@ -292,29 +337,29 @@ _interrupt_handler: mts rshr, r18 #endif - /* The parameter to the interrupt handler. */ - ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE + /* The parameter to the interrupt handler. */ + ORI r5, r0, configINTERRUPT_CONTROLLER_TO_USE - /* Execute any pending interrupts. */ - bralid r15, XIntc_DeviceInterruptHandler - or r0, r0, r0 + /* Execute any pending interrupts. */ + BRALID r15, XIntc_DeviceInterruptHandler + OR r0, r0, r0 - /* See if a new task should be selected to execute. */ - lwi r18, r0, ulTaskSwitchRequested - or r18, r18, r0 + /* See if a new task should be selected to execute. */ + LI r18, r0, ulTaskSwitchRequested + OR r18, r18, r0 - /* If ulTaskSwitchRequested is already zero, then jump straight to - restoring the task that is already in the Running state. */ - beqi r18, task_switch_not_requested + /* If ulTaskSwitchRequested is already zero, then jump straight to + restoring the task that is already in the Running state. */ + BEQI r18, task_switch_not_requested - /* Set ulTaskSwitchRequested back to zero as a task switch is about to be - performed. */ - swi r0, r0, ulTaskSwitchRequested + /* Set ulTaskSwitchRequested back to zero as a task switch is about to be + performed. */ + SI r0, r0, ulTaskSwitchRequested - /* ulTaskSwitchRequested was not 0 when tested. Select the next task to - execute. */ - bralid r15, vTaskSwitchContext - or r0, r0, r0 + /* ulTaskSwitchRequested was not 0 when tested. Select the next task to + execute. */ + BRALID r15, vTaskSwitchContext + OR r0, r0, r0 task_switch_not_requested: @@ -322,19 +367,24 @@ task_switch_not_requested: portRESTORE_CONTEXT - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + VPortYieldASM: portSAVE_CONTEXT - /* Modify the return address so a return is done to the instruction after - the call to VPortYieldASM. */ - addi r14, r14, 8 - swi r14, r1, portR14_OFFSET + /* Modify the return address so a return is done to the instruction after + the call to VPortYieldASM. */ + ADDI r14, r14, 8 + SI r14, r1, portR14_OFFSET - /* Switch to use the ISR stack. */ - lwi r1, r0, pulISRStack + /* Switch to use the ISR stack. */ + LI r1, r0, pulISRStack #if( XPAR_MICROBLAZE_USE_STACK_PROTECTION ) ori r18, r0, _stack_end @@ -343,15 +393,20 @@ VPortYieldASM: mts rshr, r18 #endif - /* Select the next task to execute. */ - bralid r15, vTaskSwitchContext - or r0, r0, r0 + /* Select the next task to execute. */ + BRALID r15, vTaskSwitchContext + OR r0, r0, r0 /* Restore the context of the next task scheduled to execute. */ portRESTORE_CONTEXT - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + vPortStartFirstTask: portRESTORE_CONTEXT @@ -360,14 +415,19 @@ vPortStartFirstTask: #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) - .text - .align 4 + .text +#ifdef __arch64__ + .align 8 +#else + .align 4 +#endif + vPortExceptionHandlerEntry: - /* Take a copy of the stack pointer before vPortExecptionHandler is called, - storing its value prior to the function stack frame being created. */ - swi r1, r0, pulStackPointerOnFunctionEntry - bralid r15, vPortExceptionHandler - or r0, r0, r0 + /* Take a copy of the stack pointer before vPortExecptionHandler is called, + storing its value prior to the function stack frame being created. */ + SI r1, r0, pulStackPointerOnFunctionEntry + BRALID r15, vPortExceptionHandler + OR r0, r0, r0 #endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */ diff --git a/portable/GCC/MicroBlazeV9/portmacro.h b/portable/GCC/MicroBlazeV9/portmacro.h index ccf98ed4c..497f9c514 100644 --- a/portable/GCC/MicroBlazeV9/portmacro.h +++ b/portable/GCC/MicroBlazeV9/portmacro.h @@ -50,20 +50,26 @@ */ /* Type definitions. */ -#define portCHAR char -#define portFLOAT float -#define portDOUBLE double -#define portLONG long -#define portSHORT short -#define portSTACK_TYPE uint32_t -#define portBASE_TYPE long +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#ifdef __arch64__ + #define portSTACK_TYPE size_t + typedef uint64_t UBaseType_t; +#else + #define portSTACK_TYPE uint32_t + typedef unsigned long UBaseType_t; +#endif +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; -typedef portSTACK_TYPE StackType_t; -typedef long BaseType_t; -typedef unsigned long UBaseType_t; #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) - typedef uint16_t TickType_t; + typedef uint16_t TickType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; @@ -155,10 +161,14 @@ extern volatile uint32_t ulTaskSwitchRequested; /*-----------------------------------------------------------*/ /* Hardware specifics. */ -#define portBYTE_ALIGNMENT 4 -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portNOP() asm volatile ( "NOP" ) +#ifdef __arch64__ + #define portBYTE_ALIGNMENT 8 +#else + #define portBYTE_ALIGNMENT 4 +#endif +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portNOP() asm volatile ( "NOP" ) #define portMEMORY_BARRIER() asm volatile ( "" ::: "memory" ) /*-----------------------------------------------------------*/ @@ -179,43 +189,43 @@ typedef struct PORT_REGISTER_DUMP { /* The following structure members hold the values of the MicroBlaze * registers at the time the exception was raised. */ - uint32_t ulR1_SP; - uint32_t ulR2_small_data_area; - uint32_t ulR3; - uint32_t ulR4; - uint32_t ulR5; - uint32_t ulR6; - uint32_t ulR7; - uint32_t ulR8; - uint32_t ulR9; - uint32_t ulR10; - uint32_t ulR11; - uint32_t ulR12; - uint32_t ulR13_read_write_small_data_area; - uint32_t ulR14_return_address_from_interrupt; - uint32_t ulR15_return_address_from_subroutine; - uint32_t ulR16_return_address_from_trap; - uint32_t ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */ - uint32_t ulR18; - uint32_t ulR19; - uint32_t ulR20; - uint32_t ulR21; - uint32_t ulR22; - uint32_t ulR23; - uint32_t ulR24; - uint32_t ulR25; - uint32_t ulR26; - uint32_t ulR27; - uint32_t ulR28; - uint32_t ulR29; - uint32_t ulR30; - uint32_t ulR31; - uint32_t ulPC; - uint32_t ulESR; - uint32_t ulMSR; - uint32_t ulEAR; - uint32_t ulFSR; - uint32_t ulEDR; + UINTPTR ulR1_SP; + UINTPTR ulR2_small_data_area; + UINTPTR ulR3; + UINTPTR ulR4; + UINTPTR ulR5; + UINTPTR ulR6; + UINTPTR ulR7; + UINTPTR ulR8; + UINTPTR ulR9; + UINTPTR ulR10; + UINTPTR ulR11; + UINTPTR ulR12; + UINTPTR ulR13_read_write_small_data_area; + UINTPTR ulR14_return_address_from_interrupt; + UINTPTR ulR15_return_address_from_subroutine; + UINTPTR ulR16_return_address_from_trap; + UINTPTR ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */ + UINTPTR ulR18; + UINTPTR ulR19; + UINTPTR ulR20; + UINTPTR ulR21; + UINTPTR ulR22; + UINTPTR ulR23; + UINTPTR ulR24; + UINTPTR ulR25; + UINTPTR ulR26; + UINTPTR ulR27; + UINTPTR ulR28; + UINTPTR ulR29; + UINTPTR ulR30; + UINTPTR ulR31; + UINTPTR ulPC; + UINTPTR ulESR; + UINTPTR ulMSR; + UINTPTR ulEAR; + UINTPTR ulFSR; + UINTPTR ulEDR; /* A human readable description of the exception cause. The strings used * are the same as the #define constant names found in the @@ -384,4 +394,4 @@ void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump ); #endif /* *INDENT-ON* */ -#endif /* PORTMACRO_H */ +#endif /* PORTMACRO_H */ \ No newline at end of file