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