Sync up MicroblazeV9 port with Xilinx tree (#220)
* MicroblazeV9: Add support for 64 bit microblaze
* MicroblazeV9: Add support for generation of run time task stats
* MicroblazeV9: Add default implementation for callback functions
---------
Signed-off-by: Mubin Usman Sayyed <mubin.usman.sayyed@xilinx.com>
diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt
index e2149d5..ba8abfd 100644
--- a/.github/.cSpellWords.txt
+++ b/.github/.cSpellWords.txt
@@ -54,6 +54,7 @@
BISR
BODIEN
BODSTS
+brealid
BRGR
brhi
brne
diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml
index bae32c9..b29209c 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 @@
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 @@
# 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 fd5de15..25c9ac3 100644
--- a/portable/GCC/MicroBlazeV9/port.c
+++ b/portable/GCC/MicroBlazeV9/port.c
@@ -42,6 +42,7 @@
#include <xintc_i.h>
#include <xil_exception.h>
#include <microblaze_exceptions_g.h>
+#include <microblaze_instructions.h>
/* 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 @@
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 @@
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 @@
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 @@
* 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 @@
{
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 @@
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 e234773..f89e47b 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 2114d00..0a5e658 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 @@
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 @@
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 @@
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 @@
#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 ccf98ed..497f9c5 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 unsigned long UBaseType_t;
+typedef portSTACK_TYPE StackType_t;
+typedef long BaseType_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 @@
/*-----------------------------------------------------------*/
/* 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 @@
{
/* 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 @@
#endif
/* *INDENT-ON* */
-#endif /* PORTMACRO_H */
+#endif /* PORTMACRO_H */
\ No newline at end of file