mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-03 18:49:02 +01:00 
			
		
		
		
	Add ARMv7-R MPU Port (#938)
* Apply git review patch created by @aggargr * Add necessary changes to the CMakeLists.txt file to build the port
This commit is contained in:
		
							parent
							
								
									839ccb719b
								
							
						
					
					
						commit
						61111b1460
					
				
							
								
								
									
										16
									
								
								.github/.cSpellWords.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/.cSpellWords.txt
									
									
									
									
										vendored
									
									
								
							@ -549,6 +549,10 @@ NTRST
 | 
			
		||||
NVIC
 | 
			
		||||
ODAT
 | 
			
		||||
ODSR
 | 
			
		||||
OINC
 | 
			
		||||
OIWBNOWA
 | 
			
		||||
OIWBWA
 | 
			
		||||
OIWTNOWA
 | 
			
		||||
OPMOD
 | 
			
		||||
optimisations
 | 
			
		||||
OPTIMISED
 | 
			
		||||
@ -795,6 +799,15 @@ SWRST
 | 
			
		||||
SWTRG
 | 
			
		||||
synchronise
 | 
			
		||||
SYSC
 | 
			
		||||
sysclk
 | 
			
		||||
Sysclk
 | 
			
		||||
SysClk
 | 
			
		||||
SYSClk
 | 
			
		||||
SYSCLK
 | 
			
		||||
sysclock
 | 
			
		||||
Sysclock
 | 
			
		||||
SysClock
 | 
			
		||||
SYSCLOCK
 | 
			
		||||
TACCR
 | 
			
		||||
TACCTL
 | 
			
		||||
TACLR
 | 
			
		||||
@ -877,6 +890,9 @@ UNDADD
 | 
			
		||||
unpadded
 | 
			
		||||
Unpadded
 | 
			
		||||
UNPADDED
 | 
			
		||||
unprotect
 | 
			
		||||
Unprotect
 | 
			
		||||
Unprotected
 | 
			
		||||
UNRE
 | 
			
		||||
UNSUB
 | 
			
		||||
UNSUBACK
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								.github/scripts/kernel_checker.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/scripts/kernel_checker.py
									
									
									
									
										vendored
									
									
								
							@ -37,7 +37,8 @@ KERNEL_IGNORED_FILES = [
 | 
			
		||||
    'FreeRTOS-openocd.c',
 | 
			
		||||
    'Makefile',
 | 
			
		||||
    '.DS_Store',
 | 
			
		||||
    'cspell.config.yaml'
 | 
			
		||||
    'cspell.config.yaml',
 | 
			
		||||
    '.clang-format'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
KERNEL_IGNORED_EXTENSIONS = [
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/formatting.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/formatting.yml
									
									
									
									
										vendored
									
									
								
							@ -19,7 +19,7 @@ jobs:
 | 
			
		||||
    runs-on: ubuntu-20.04
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Apply Formatting Fix
 | 
			
		||||
      id: check-formatting  
 | 
			
		||||
      id: check-formatting
 | 
			
		||||
      uses: FreeRTOS/CI-CD-Github-Actions/formatting-bot@main
 | 
			
		||||
      with:
 | 
			
		||||
        exclude-dirs: portable
 | 
			
		||||
 | 
			
		||||
@ -85,6 +85,7 @@ if(NOT FREERTOS_PORT)
 | 
			
		||||
        " GCC_ARM_CM85_NTZ_NONSECURE       - Compiler: GCC           Target: ARM Cortex-M85 non-trustzone non-secure\n"
 | 
			
		||||
        " GCC_ARM_CM85_TFM                 - Compiler: GCC           Target: ARM Cortex-M85 non-secure for TF-M\n"
 | 
			
		||||
        " GCC_ARM_CR5                      - Compiler: GCC           Target: ARM Cortex-R5\n"
 | 
			
		||||
        " GCC_ARM_CRX_MPU                  - Compiler: GCC           Target: ARM Cortex-Rx with MPU\n"
 | 
			
		||||
        " GCC_ARM_CRX_NOGIC                - Compiler: GCC           Target: ARM Cortex-Rx no GIC\n"
 | 
			
		||||
        " GCC_ARM7_AT91FR40008             - Compiler: GCC           Target: ARM7 Atmel AT91R40008\n"
 | 
			
		||||
        " GCC_ARM7_AT91SAM7S               - Compiler: GCC           Target: ARM7 Atmel AT91SAM7S\n"
 | 
			
		||||
 | 
			
		||||
@ -207,6 +207,11 @@ add_library(freertos_kernel_port OBJECT
 | 
			
		||||
        GCC/ARM_CR5/port.c
 | 
			
		||||
        GCC/ARM_CR5/portASM.S>
 | 
			
		||||
 | 
			
		||||
    $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:
 | 
			
		||||
        GCC/ARM_CRx_MPU/port.c
 | 
			
		||||
        GCC/ARM_CRx_MPU/portASM.S
 | 
			
		||||
        GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S>
 | 
			
		||||
 | 
			
		||||
    $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:
 | 
			
		||||
        GCC/ARM_CRx_No_GIC/port.c
 | 
			
		||||
        GCC/ARM_CRx_No_GIC/portASM.S>
 | 
			
		||||
@ -836,6 +841,7 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
 | 
			
		||||
 | 
			
		||||
    # ARMv7-R ports for GCC
 | 
			
		||||
    $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5>
 | 
			
		||||
    $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU>
 | 
			
		||||
    $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC>
 | 
			
		||||
 | 
			
		||||
    # ARMv4T ARM7TDMI ports for GCC
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										854
									
								
								portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										854
									
								
								portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,854 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .arm
 | 
			
		||||
    .syntax unified
 | 
			
		||||
    .section freertos_system_calls
 | 
			
		||||
 | 
			
		||||
#define FREERTOS_ASSEMBLY
 | 
			
		||||
    #include "FreeRTOSConfig.h"
 | 
			
		||||
    #include "portmacro_asm.h"
 | 
			
		||||
    #include "mpu_syscall_numbers.h"
 | 
			
		||||
#undef FREERTOS_ASSEMBLY
 | 
			
		||||
 | 
			
		||||
/* ----------------------- Start of Port Specific System Calls ----------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vPortYield( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vPortYield
 | 
			
		||||
.type vPortYield, %function
 | 
			
		||||
vPortYield:
 | 
			
		||||
    SVC     #portSVC_YIELD
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vPortSystemCallExit( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vPortSystemCallExit
 | 
			
		||||
.type vPortSystemCallExit, %function
 | 
			
		||||
vPortSystemCallExit:
 | 
			
		||||
    SVC     #portSVC_SYSTEM_CALL_EXIT
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * BaseType_t xPortIsPrivileged( void );
 | 
			
		||||
 *
 | 
			
		||||
 * According to the Procedure Call Standard for the ARM Architecture (AAPCS):
 | 
			
		||||
 * - Return value must be in R0.
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global xPortIsPrivileged
 | 
			
		||||
.type xPortIsPrivileged, %function
 | 
			
		||||
xPortIsPrivileged:
 | 
			
		||||
    MRS     R0, CPSR        /* R0 = CPSR. */
 | 
			
		||||
    AND     R0, R0, #0x1F   /* R0 = R0 & 0x1F. Extract mode bits.*/
 | 
			
		||||
    CMP     R0, #USER_MODE  /* If R0 == #USER_MODE. */
 | 
			
		||||
    MOVEQ   R0, #0x0        /* Then, set R0 to 0 to indicate that the processer is not privileged. */
 | 
			
		||||
    MOVNE   R0, #0x01       /* Otherwise, set R0 to 1 to indicate that the processer is privileged. */
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
 | 
			
		||||
 *
 | 
			
		||||
 * According to the Procedure Call Standard for the ARM Architecture (AAPCS):
 | 
			
		||||
 * - Parameter ulBitmap is passed in R0.
 | 
			
		||||
 * - Return value must be in R0.
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.weak ulPortCountLeadingZeros
 | 
			
		||||
.type ulPortCountLeadingZeros, %function
 | 
			
		||||
ulPortCountLeadingZeros:
 | 
			
		||||
    CLZ     R0, R0
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ------------------- End of Port Specific System Calls ------------------- */
 | 
			
		||||
 | 
			
		||||
.macro INVOKE_SYSTEM_CALL systemCallNumber, systemCallImpl
 | 
			
		||||
    PUSH    {R0}
 | 
			
		||||
    MRS     R0, CPSR
 | 
			
		||||
    AND     R0, R0, #0x1F
 | 
			
		||||
    CMP     R0, #USER_MODE
 | 
			
		||||
    POP     {R0}
 | 
			
		||||
    SVCEQ   \systemCallNumber
 | 
			
		||||
    B       \systemCallImpl
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xTaskGetTickCountImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xTaskGetTickCount
 | 
			
		||||
.type MPU_xTaskGetTickCount, function
 | 
			
		||||
MPU_xTaskGetTickCount:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetTickCount, MPU_xTaskGetTickCountImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_uxTaskGetNumberOfTasksImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_uxTaskGetNumberOfTasks
 | 
			
		||||
.type MPU_uxTaskGetNumberOfTasks, function
 | 
			
		||||
MPU_uxTaskGetNumberOfTasks:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetNumberOfTasks, MPU_uxTaskGetNumberOfTasksImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_vTaskSetTimeOutStateImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_vTaskSetTimeOutState
 | 
			
		||||
.type MPU_vTaskSetTimeOutState, function
 | 
			
		||||
MPU_vTaskSetTimeOutState:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetTimeOutState, MPU_vTaskSetTimeOutStateImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xTaskCheckForTimeOutImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xTaskCheckForTimeOut
 | 
			
		||||
.type MPU_xTaskCheckForTimeOut, function
 | 
			
		||||
MPU_xTaskCheckForTimeOut:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskCheckForTimeOut, MPU_xTaskCheckForTimeOutImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xQueueGenericSendImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xQueueGenericSend
 | 
			
		||||
.type MPU_xQueueGenericSend, function
 | 
			
		||||
MPU_xQueueGenericSend:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGenericSend, MPU_xQueueGenericSendImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_uxQueueMessagesWaitingImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_uxQueueMessagesWaiting
 | 
			
		||||
.type MPU_uxQueueMessagesWaiting, function
 | 
			
		||||
MPU_uxQueueMessagesWaiting:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueMessagesWaiting, MPU_uxQueueMessagesWaitingImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_uxQueueSpacesAvailableImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_uxQueueSpacesAvailable
 | 
			
		||||
.type MPU_uxQueueSpacesAvailable, function
 | 
			
		||||
MPU_uxQueueSpacesAvailable:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueSpacesAvailable, MPU_uxQueueSpacesAvailableImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xQueueReceiveImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xQueueReceive
 | 
			
		||||
.type MPU_xQueueReceive, function
 | 
			
		||||
MPU_xQueueReceive:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueReceive, MPU_xQueueReceiveImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xQueuePeekImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xQueuePeek
 | 
			
		||||
.type MPU_xQueuePeek, function
 | 
			
		||||
MPU_xQueuePeek:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueuePeek, MPU_xQueuePeekImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xQueueSemaphoreTakeImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xQueueSemaphoreTake
 | 
			
		||||
.type MPU_xQueueSemaphoreTake, function
 | 
			
		||||
MPU_xQueueSemaphoreTake:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSemaphoreTake, MPU_xQueueSemaphoreTakeImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xEventGroupWaitBitsImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xEventGroupWaitBitsEntry
 | 
			
		||||
.type MPU_xEventGroupWaitBitsEntry, function
 | 
			
		||||
MPU_xEventGroupWaitBitsEntry:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupWaitBits, MPU_xEventGroupWaitBitsImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xEventGroupClearBitsImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xEventGroupClearBits
 | 
			
		||||
.type MPU_xEventGroupClearBits, function
 | 
			
		||||
MPU_xEventGroupClearBits:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupClearBits, MPU_xEventGroupClearBitsImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xEventGroupSetBitsImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xEventGroupSetBits
 | 
			
		||||
.type MPU_xEventGroupSetBits, function
 | 
			
		||||
MPU_xEventGroupSetBits:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSetBits, MPU_xEventGroupSetBitsImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xEventGroupSyncImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xEventGroupSync
 | 
			
		||||
.type MPU_xEventGroupSync, function
 | 
			
		||||
MPU_xEventGroupSync:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSync, MPU_xEventGroupSyncImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferSendImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferSend
 | 
			
		||||
.type MPU_xStreamBufferSend, function
 | 
			
		||||
MPU_xStreamBufferSend:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSend, MPU_xStreamBufferSendImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferReceiveImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferReceive
 | 
			
		||||
.type MPU_xStreamBufferReceive, function
 | 
			
		||||
MPU_xStreamBufferReceive:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferReceive, MPU_xStreamBufferReceiveImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferIsFullImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferIsFull
 | 
			
		||||
.type MPU_xStreamBufferIsFull, function
 | 
			
		||||
MPU_xStreamBufferIsFull:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsFull, MPU_xStreamBufferIsFullImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferIsEmptyImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferIsEmpty
 | 
			
		||||
.type MPU_xStreamBufferIsEmpty, function
 | 
			
		||||
MPU_xStreamBufferIsEmpty:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsEmpty, MPU_xStreamBufferIsEmptyImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferSpacesAvailableImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferSpacesAvailable
 | 
			
		||||
.type MPU_xStreamBufferSpacesAvailable, function
 | 
			
		||||
MPU_xStreamBufferSpacesAvailable:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSpacesAvailable, MPU_xStreamBufferSpacesAvailableImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferBytesAvailableImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferBytesAvailable
 | 
			
		||||
.type MPU_xStreamBufferBytesAvailable, function
 | 
			
		||||
MPU_xStreamBufferBytesAvailable:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferBytesAvailable, MPU_xStreamBufferBytesAvailableImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferSetTriggerLevelImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferSetTriggerLevel
 | 
			
		||||
.type MPU_xStreamBufferSetTriggerLevel, function
 | 
			
		||||
MPU_xStreamBufferSetTriggerLevel:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSetTriggerLevel, MPU_xStreamBufferSetTriggerLevelImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.extern MPU_xStreamBufferNextMessageLengthBytesImpl
 | 
			
		||||
.align 4
 | 
			
		||||
.global MPU_xStreamBufferNextMessageLengthBytes
 | 
			
		||||
.type MPU_xStreamBufferNextMessageLengthBytes, function
 | 
			
		||||
MPU_xStreamBufferNextMessageLengthBytes:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes, MPU_xStreamBufferNextMessageLengthBytesImpl
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskDelayUntilImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskDelayUntil
 | 
			
		||||
    .type MPU_xTaskDelayUntil, function
 | 
			
		||||
    MPU_xTaskDelayUntil:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskDelayUntil, MPU_xTaskDelayUntilImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTaskAbortDelay == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskAbortDelayImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskAbortDelay
 | 
			
		||||
    .type MPU_xTaskAbortDelay, function
 | 
			
		||||
    MPU_xTaskAbortDelay:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskAbortDelay, MPU_xTaskAbortDelayImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_vTaskDelay == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskDelayImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskDelay
 | 
			
		||||
    .type MPU_vTaskDelay, function
 | 
			
		||||
    MPU_vTaskDelay:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskDelay, MPU_vTaskDelayImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_vTaskDelay == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_uxTaskPriorityGet == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxTaskPriorityGetImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxTaskPriorityGet
 | 
			
		||||
    .type MPU_uxTaskPriorityGet, function
 | 
			
		||||
    MPU_uxTaskPriorityGet:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskPriorityGet, MPU_uxTaskPriorityGetImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_eTaskGetState == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_eTaskGetStateImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_eTaskGetState
 | 
			
		||||
    .type MPU_eTaskGetState, function
 | 
			
		||||
    MPU_eTaskGetState:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_eTaskGetState, MPU_eTaskGetStateImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_eTaskGetState == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskGetInfoImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskGetInfo
 | 
			
		||||
    .type MPU_vTaskGetInfo, function
 | 
			
		||||
    MPU_vTaskGetInfo:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskGetInfo, MPU_vTaskGetInfoImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxTaskGetSystemStateImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxTaskGetSystemState
 | 
			
		||||
    .type MPU_uxTaskGetSystemState, function
 | 
			
		||||
    MPU_uxTaskGetSystemState:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetSystemState, MPU_uxTaskGetSystemStateImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxEventGroupGetNumberImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxEventGroupGetNumber
 | 
			
		||||
    .type MPU_uxEventGroupGetNumber, function
 | 
			
		||||
    MPU_uxEventGroupGetNumber:
 | 
			
		||||
    INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxEventGroupGetNumber, MPU_uxEventGroupGetNumberImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vEventGroupSetNumberImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vEventGroupSetNumber
 | 
			
		||||
    .type MPU_vEventGroupSetNumber, function
 | 
			
		||||
    MPU_vEventGroupSetNumber:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vEventGroupSetNumber, MPU_vEventGroupSetNumberImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGetIdleTaskHandleImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGetIdleTaskHandle
 | 
			
		||||
    .type MPU_xTaskGetIdleTaskHandle, function
 | 
			
		||||
    MPU_xTaskGetIdleTaskHandle:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetIdleTaskHandle, MPU_xTaskGetIdleTaskHandleImpl
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_vTaskSuspend == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskSuspendImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskSuspend
 | 
			
		||||
    .type MPU_vTaskSuspend, function
 | 
			
		||||
    MPU_vTaskSuspend:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSuspend, MPU_vTaskSuspendImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskResumeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskResume
 | 
			
		||||
    .type MPU_vTaskResume, function
 | 
			
		||||
    MPU_vTaskResume:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskResume, MPU_vTaskResumeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_ulTaskGetRunTimeCounterImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_ulTaskGetRunTimeCounter
 | 
			
		||||
    .type MPU_ulTaskGetRunTimeCounter, function
 | 
			
		||||
    MPU_ulTaskGetRunTimeCounter:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimeCounter, MPU_ulTaskGetRunTimeCounterImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_ulTaskGetRunTimePercentImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_ulTaskGetRunTimePercent
 | 
			
		||||
    .type MPU_ulTaskGetRunTimePercent, function
 | 
			
		||||
    MPU_ulTaskGetRunTimePercent:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimePercent, MPU_ulTaskGetRunTimePercentImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 | 
			
		||||
 | 
			
		||||
        .extern MPU_ulTaskGetIdleRunTimePercentImpl
 | 
			
		||||
        .align 4
 | 
			
		||||
        .global MPU_ulTaskGetIdleRunTimePercent
 | 
			
		||||
        .type MPU_ulTaskGetIdleRunTimePercent, function
 | 
			
		||||
        MPU_ulTaskGetIdleRunTimePercent:
 | 
			
		||||
            INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimePercent, MPU_ulTaskGetIdleRunTimePercentImpl
 | 
			
		||||
 | 
			
		||||
        /* --------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
        .extern MPU_ulTaskGetIdleRunTimeCounterImpl
 | 
			
		||||
        .align 4
 | 
			
		||||
        .global MPU_ulTaskGetIdleRunTimeCounter
 | 
			
		||||
        .type MPU_ulTaskGetIdleRunTimeCounter, function
 | 
			
		||||
        MPU_ulTaskGetIdleRunTimeCounter:
 | 
			
		||||
            INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter, MPU_ulTaskGetIdleRunTimeCounterImpl
 | 
			
		||||
 | 
			
		||||
        /* --------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 )*/
 | 
			
		||||
 | 
			
		||||
/* --------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskSetApplicationTaskTagImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskSetApplicationTaskTag
 | 
			
		||||
    .type MPU_vTaskSetApplicationTaskTag, function
 | 
			
		||||
    MPU_vTaskSetApplicationTaskTag:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetApplicationTaskTag, MPU_vTaskSetApplicationTaskTagImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGetApplicationTaskTagImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGetApplicationTaskTag
 | 
			
		||||
    .type MPU_xTaskGetApplicationTaskTag, function
 | 
			
		||||
    MPU_xTaskGetApplicationTaskTag:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetApplicationTaskTag, MPU_xTaskGetApplicationTaskTagImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTaskSetThreadLocalStoragePointerImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTaskSetThreadLocalStoragePointer
 | 
			
		||||
    .type MPU_vTaskSetThreadLocalStoragePointer, function
 | 
			
		||||
    MPU_vTaskSetThreadLocalStoragePointer:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer, MPU_vTaskSetThreadLocalStoragePointerImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_pvTaskGetThreadLocalStoragePointerImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_pvTaskGetThreadLocalStoragePointer
 | 
			
		||||
    .type MPU_pvTaskGetThreadLocalStoragePointer, function
 | 
			
		||||
    MPU_pvTaskGetThreadLocalStoragePointer:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer, MPU_pvTaskGetThreadLocalStoragePointerImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxTaskGetStackHighWaterMarkImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxTaskGetStackHighWaterMark
 | 
			
		||||
    .type MPU_uxTaskGetStackHighWaterMark, function
 | 
			
		||||
    MPU_uxTaskGetStackHighWaterMark:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark, MPU_uxTaskGetStackHighWaterMarkImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxTaskGetStackHighWaterMark2Impl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxTaskGetStackHighWaterMark2
 | 
			
		||||
    .type MPU_uxTaskGetStackHighWaterMark2, function
 | 
			
		||||
    MPU_uxTaskGetStackHighWaterMark2:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark2, MPU_uxTaskGetStackHighWaterMark2Impl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGetCurrentTaskHandleImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGetCurrentTaskHandle
 | 
			
		||||
    .type MPU_xTaskGetCurrentTaskHandle, function
 | 
			
		||||
    MPU_xTaskGetCurrentTaskHandle:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetCurrentTaskHandle, MPU_xTaskGetCurrentTaskHandleImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTaskGetSchedulerState == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGetSchedulerStateImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGetSchedulerState
 | 
			
		||||
    .type MPU_xTaskGetSchedulerState, function
 | 
			
		||||
    MPU_xTaskGetSchedulerState:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetSchedulerState, MPU_xTaskGetSchedulerStateImpl
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xQueueGetMutexHolderImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xQueueGetMutexHolder
 | 
			
		||||
    .type MPU_xQueueGetMutexHolder, function
 | 
			
		||||
    MPU_xQueueGetMutexHolder:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGetMutexHolder, MPU_xQueueGetMutexHolderImpl
 | 
			
		||||
 | 
			
		||||
#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xQueueTakeMutexRecursiveImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xQueueTakeMutexRecursive
 | 
			
		||||
    .type MPU_xQueueTakeMutexRecursive, function
 | 
			
		||||
    MPU_xQueueTakeMutexRecursive:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueTakeMutexRecursive, MPU_xQueueTakeMutexRecursiveImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xQueueGiveMutexRecursiveImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xQueueGiveMutexRecursive
 | 
			
		||||
    .type MPU_xQueueGiveMutexRecursive, function
 | 
			
		||||
    MPU_xQueueGiveMutexRecursive:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGiveMutexRecursive, MPU_xQueueGiveMutexRecursiveImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_QUEUE_SETS == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xQueueSelectFromSetImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xQueueSelectFromSet
 | 
			
		||||
    .type MPU_xQueueSelectFromSet, function
 | 
			
		||||
    MPU_xQueueSelectFromSet:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSelectFromSet, MPU_xQueueSelectFromSetImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xQueueAddToSetImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xQueueAddToSet
 | 
			
		||||
    .type MPU_xQueueAddToSet, function
 | 
			
		||||
    MPU_xQueueAddToSet:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueAddToSet, MPU_xQueueAddToSetImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configQUEUE_REGISTRY_SIZE > 0 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vQueueAddToRegistryImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vQueueAddToRegistry
 | 
			
		||||
    .type MPU_vQueueAddToRegistry, function
 | 
			
		||||
    MPU_vQueueAddToRegistry:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueAddToRegistry, MPU_vQueueAddToRegistryImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vQueueUnregisterQueueImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vQueueUnregisterQueue
 | 
			
		||||
    .type MPU_vQueueUnregisterQueue, function
 | 
			
		||||
    MPU_vQueueUnregisterQueue:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueUnregisterQueue, MPU_vQueueUnregisterQueueImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_pcQueueGetNameImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_pcQueueGetName
 | 
			
		||||
    .type MPU_pcQueueGetName, function
 | 
			
		||||
    MPU_pcQueueGetName:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcQueueGetName, MPU_pcQueueGetNameImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_TIMERS == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_pvTimerGetTimerIDImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_pvTimerGetTimerID
 | 
			
		||||
    .type MPU_pvTimerGetTimerID, function
 | 
			
		||||
    MPU_pvTimerGetTimerID:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTimerGetTimerID, MPU_pvTimerGetTimerIDImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTimerSetTimerIDImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTimerSetTimerID
 | 
			
		||||
    .type MPU_vTimerSetTimerID, function
 | 
			
		||||
    MPU_vTimerSetTimerID:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetTimerID, MPU_vTimerSetTimerIDImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerIsTimerActiveImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerIsTimerActive
 | 
			
		||||
    .type MPU_xTimerIsTimerActive, function
 | 
			
		||||
    MPU_xTimerIsTimerActive:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerIsTimerActive, MPU_xTimerIsTimerActiveImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerGetTimerDaemonTaskHandleImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerGetTimerDaemonTaskHandle
 | 
			
		||||
    .type MPU_xTimerGetTimerDaemonTaskHandle, function
 | 
			
		||||
    MPU_xTimerGetTimerDaemonTaskHandle:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle, MPU_xTimerGetTimerDaemonTaskHandleImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerGenericCommandFromTaskImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerGenericCommandFromTaskEntry
 | 
			
		||||
    .type MPU_xTimerGenericCommandFromTaskEntry, function
 | 
			
		||||
    MPU_xTimerGenericCommandFromTaskEntry:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGenericCommandFromTask, MPU_xTimerGenericCommandFromTaskImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_pcTimerGetNameImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_pcTimerGetName
 | 
			
		||||
    .type MPU_pcTimerGetName, function
 | 
			
		||||
    MPU_pcTimerGetName:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcTimerGetName, MPU_pcTimerGetNameImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_vTimerSetReloadModeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_vTimerSetReloadMode
 | 
			
		||||
    .type MPU_vTimerSetReloadMode, function
 | 
			
		||||
    MPU_vTimerSetReloadMode:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetReloadMode, MPU_vTimerSetReloadModeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerGetReloadModeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerGetReloadMode
 | 
			
		||||
    .type MPU_xTimerGetReloadMode, function
 | 
			
		||||
    MPU_xTimerGetReloadMode:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetReloadMode, MPU_xTimerGetReloadModeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_uxTimerGetReloadModeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_uxTimerGetReloadMode
 | 
			
		||||
    .type MPU_uxTimerGetReloadMode, function
 | 
			
		||||
    MPU_uxTimerGetReloadMode:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTimerGetReloadMode, MPU_uxTimerGetReloadModeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerGetPeriodImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerGetPeriod
 | 
			
		||||
    .type MPU_xTimerGetPeriod, function
 | 
			
		||||
    MPU_xTimerGetPeriod:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetPeriod, MPU_xTimerGetPeriodImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTimerGetExpiryTimeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTimerGetExpiryTime
 | 
			
		||||
    .type MPU_xTimerGetExpiryTime, function
 | 
			
		||||
    MPU_xTimerGetExpiryTime:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetExpiryTime, MPU_xTimerGetExpiryTimeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_TIMERS == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGenericNotifyImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGenericNotifyEntry
 | 
			
		||||
    .type MPU_xTaskGenericNotifyEntry, function
 | 
			
		||||
    MPU_xTaskGenericNotifyEntry:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotify, MPU_xTaskGenericNotifyImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGenericNotifyWaitImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGenericNotifyWaitEntry
 | 
			
		||||
    .type MPU_xTaskGenericNotifyWaitEntry, function
 | 
			
		||||
    MPU_xTaskGenericNotifyWaitEntry:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyWait, MPU_xTaskGenericNotifyWaitImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_ulTaskGenericNotifyTakeImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_ulTaskGenericNotifyTake
 | 
			
		||||
    .type MPU_ulTaskGenericNotifyTake, function
 | 
			
		||||
    MPU_ulTaskGenericNotifyTake:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyTake, MPU_ulTaskGenericNotifyTakeImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_xTaskGenericNotifyStateClearImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_xTaskGenericNotifyStateClear
 | 
			
		||||
    .type MPU_xTaskGenericNotifyStateClear, function
 | 
			
		||||
    MPU_xTaskGenericNotifyStateClear:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyStateClear, MPU_xTaskGenericNotifyStateClearImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
    .extern MPU_ulTaskGenericNotifyValueClearImpl
 | 
			
		||||
    .align 4
 | 
			
		||||
    .global MPU_ulTaskGenericNotifyValueClear
 | 
			
		||||
    .type MPU_ulTaskGenericNotifyValueClear, function
 | 
			
		||||
    MPU_ulTaskGenericNotifyValueClear:
 | 
			
		||||
        INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyValueClear, MPU_ulTaskGenericNotifyValueClearImpl
 | 
			
		||||
 | 
			
		||||
    /* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.end
 | 
			
		||||
							
								
								
									
										843
									
								
								portable/GCC/ARM_CRx_MPU/port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										843
									
								
								portable/GCC/ARM_CRx_MPU/port.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,843 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Standard includes. */
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers. That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
    #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 | 
			
		||||
 | 
			
		||||
/* Scheduler includes. */
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "portmacro.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "mpu_syscall_numbers.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/* Max value that fits in a uint32_t type. */
 | 
			
		||||
#define portUINT32_MAX    ( ~( ( uint32_t ) 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Check if adding a and b will result in overflow. */
 | 
			
		||||
#define portADD_UINT32_WILL_OVERFLOW( a, b )    ( ( a ) > ( portUINT32_MAX - ( b ) ) )
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Variable used to keep track of critical section nesting.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Sections
 | 
			
		||||
 *
 | 
			
		||||
 * This variable is stored as part of the task context and must be initialised
 | 
			
		||||
 * to a non zero value to ensure interrupts don't inadvertently become unmasked
 | 
			
		||||
 * before the scheduler starts. As it is stored as part of the task context, it
 | 
			
		||||
 * will be set to 0 when the first task is started.
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_DATA volatile UBaseType_t ulCriticalNesting = 0xFFFF;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set to 1 to pend a context switch from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Interrupt Management
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_DATA volatile UBaseType_t ulPortYieldRequired = pdFALSE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Interrupt nesting depth, used to count the number of interrupts to unwind.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Interrupt Management
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_DATA volatile UBaseType_t ulPortInterruptNesting = 0UL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Variable to track whether or not the scheduler has been started.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 *
 | 
			
		||||
 * This is the port specific version of the xSchedulerRunning in tasks.c.
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE;
 | 
			
		||||
 | 
			
		||||
/* -------------------------- Private Function Declarations -------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Determine if the given MPU region settings authorizes the requested
 | 
			
		||||
 * access to the given buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTaskMPURegion MPU region settings.
 | 
			
		||||
 * @param ulBufferStart Start address of the given buffer.
 | 
			
		||||
 * @param ulBufferLength Length of the given buffer.
 | 
			
		||||
 * @param ulAccessRequested Access requested.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if MPU region settins authorizes the requested access to the
 | 
			
		||||
 * given buffer, pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_FUNCTION static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion,
 | 
			
		||||
                                                                    const uint32_t ulBufferStart,
 | 
			
		||||
                                                                    const uint32_t ulBufferLength,
 | 
			
		||||
                                                                    const uint32_t ulAccessRequested );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Determine the smallest MPU Region Size Encoding for the given MPU
 | 
			
		||||
 * region size.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @param ulActualMPURegionSize MPU region size in bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The smallest MPU Region Size Encoding for the given MPU region size.
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set up MPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_FUNCTION static void prvSetupMPU( void );
 | 
			
		||||
 | 
			
		||||
/* -------------------------- Exported Function Declarations -------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enter critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Section
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_FUNCTION void vPortEnterCritical( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Exit critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Section
 | 
			
		||||
 */
 | 
			
		||||
PRIVILEGED_FUNCTION void vPortExitCritical( void );
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Setup a FreeRTOS task's initial context.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxTopOfStack Top of stack.
 | 
			
		||||
 * @param pxCode The task function.
 | 
			
		||||
 * @param pvParameters Argument passed to the task function.
 | 
			
		||||
 * @param xRunPrivileged Marks if the task is privileged.
 | 
			
		||||
 * @param xMPUSettings MPU settings of the task.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Location where to restore the task's context from.
 | 
			
		||||
 */
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                     TaskFunction_t pxCode,
 | 
			
		||||
                                     void * pvParameters,
 | 
			
		||||
                                     BaseType_t xRunPrivileged,
 | 
			
		||||
                                     xMPU_SETTINGS * xMPUSettings )
 | 
			
		||||
{
 | 
			
		||||
    /* Setup the initial context of the task. The context is set exactly as
 | 
			
		||||
     * expected by the portRESTORE_CONTEXT() macro. */
 | 
			
		||||
    UBaseType_t ulIndex = CONTEXT_SIZE - 1U;
 | 
			
		||||
 | 
			
		||||
    xSYSTEM_CALL_STACK_INFO * xSysCallInfo = NULL;
 | 
			
		||||
 | 
			
		||||
    if( xRunPrivileged == pdTRUE )
 | 
			
		||||
    {
 | 
			
		||||
        xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG;
 | 
			
		||||
        /* Current Program Status Register (CPSR). */
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = SYS_MODE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG );
 | 
			
		||||
        /* Current Program Status Register (CPSR). */
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = USER_MODE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x0UL )
 | 
			
		||||
    {
 | 
			
		||||
        /* The task will cause the processor to start in THUMB state, set the
 | 
			
		||||
         * Thumb state bit in the CPSR. */
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] |= portTHUMB_MODE_BIT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; /* PC. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
 | 
			
		||||
    /* General Purpose Registers. */
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0. */
 | 
			
		||||
    ulIndex--;
 | 
			
		||||
 | 
			
		||||
    #if( portENABLE_FPU == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
 | 
			
		||||
        xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x00000000; /* FPSR. */
 | 
			
		||||
        ulIndex--;
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* portENABLE_FPU */
 | 
			
		||||
 | 
			
		||||
    /* The task will start with a critical nesting count of 0. */
 | 
			
		||||
    xMPUSettings->ulContext[ ulIndex ] = portNO_CRITICAL_NESTING;
 | 
			
		||||
 | 
			
		||||
    /* Ensure that the system call stack is double word aligned. */
 | 
			
		||||
    xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo );
 | 
			
		||||
    xSysCallInfo->pulSystemCallStackPointer = &( xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] );
 | 
			
		||||
    xSysCallInfo->pulSystemCallStackPointer = ( uint32_t * ) ( ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) ) &
 | 
			
		||||
                                                               ( ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ) );
 | 
			
		||||
 | 
			
		||||
    /* This is not NULL only for the duration of a system call. */
 | 
			
		||||
    xSysCallInfo->pulTaskStackPointer = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Set the System Call to return to vPortSystemCallExit. */
 | 
			
		||||
    xSysCallInfo->pulSystemCallExitAddress = ( uint32_t * ) ( &vPortSystemCallExit );
 | 
			
		||||
 | 
			
		||||
    /* Return the address where this task's context should be restored from. */
 | 
			
		||||
    return &( xMPUSettings->ulContext[ ulIndex ] );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Store a FreeRTOS task's MPU settings in its TCB.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMPUSettings The MPU settings in TCB.
 | 
			
		||||
 * @param xRegions The updated MPU settings requested by the task.
 | 
			
		||||
 * @param pxBottomOfStack The base address of the task's Stack.
 | 
			
		||||
 * @param ulStackDepth The length of the task's stack.
 | 
			
		||||
 */
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
                                const struct xMEMORY_REGION * const xRegions,
 | 
			
		||||
                                StackType_t * pxBottomOfStack,
 | 
			
		||||
                                uint32_t ulStackDepth )
 | 
			
		||||
{
 | 
			
		||||
    #if defined( __ARMCC_VERSION )
 | 
			
		||||
        /* Declaration when these variable are defined in code instead of being
 | 
			
		||||
         * exported from linker scripts. */
 | 
			
		||||
        extern uint32_t * __SRAM_segment_start__;
 | 
			
		||||
        extern uint32_t * __SRAM_segment_end__;
 | 
			
		||||
    #else
 | 
			
		||||
        /* Declaration when these variable are exported from linker scripts. */
 | 
			
		||||
        extern uint32_t __SRAM_segment_start__[];
 | 
			
		||||
        extern uint32_t __SRAM_segment_end__[];
 | 
			
		||||
    #endif /* if defined( __ARMCC_VERSION ) */
 | 
			
		||||
 | 
			
		||||
    uint32_t ulIndex = 0x0;
 | 
			
		||||
    uint32_t ulRegionLength;
 | 
			
		||||
    uint32_t ulRegionLengthEncoded;
 | 
			
		||||
    uint32_t ulRegionLengthDecoded;
 | 
			
		||||
 | 
			
		||||
    if( xRegions == NULL )
 | 
			
		||||
    {
 | 
			
		||||
        /* No MPU regions are specified so allow access to all of the RAM. */
 | 
			
		||||
        ulRegionLength = ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__;
 | 
			
		||||
        ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
 | 
			
		||||
        ulRegionLength |= portMPU_REGION_ENABLE;
 | 
			
		||||
 | 
			
		||||
        /* MPU Settings is zero'd out in the TCB before this function is called.
 | 
			
		||||
         * We, therefore, do not need to explicitly zero out unused MPU regions
 | 
			
		||||
         * in xMPUSettings. */
 | 
			
		||||
        ulIndex = portSTACK_REGION;
 | 
			
		||||
 | 
			
		||||
        xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) __SRAM_segment_start__;
 | 
			
		||||
        xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
 | 
			
		||||
                                                          portMPU_REGION_ENABLE );
 | 
			
		||||
        xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
 | 
			
		||||
                                                               portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ )
 | 
			
		||||
        {
 | 
			
		||||
            /* If a length has been provided, the region is in use. */
 | 
			
		||||
            if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL )
 | 
			
		||||
            {
 | 
			
		||||
                ulRegionLength = xRegions[ ulIndex ].ulLengthInBytes;
 | 
			
		||||
                ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
 | 
			
		||||
 | 
			
		||||
                /* MPU region base address must be aligned to the region size
 | 
			
		||||
                 * boundary. */
 | 
			
		||||
                ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL );
 | 
			
		||||
                configASSERT( ( ( ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress ) % ( ulRegionLengthDecoded ) ) == 0UL );
 | 
			
		||||
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress;
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
 | 
			
		||||
                                                                  portMPU_REGION_ENABLE );
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = xRegions[ ulIndex ].ulParameters;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = 0x0UL;
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionSize = 0x0UL;
 | 
			
		||||
                xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = 0x0UL;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* This function is called automatically when the task is created - in
 | 
			
		||||
         * which case the stack region parameters will be valid. At all other
 | 
			
		||||
         * times the stack parameters will not be valid and it is assumed that the
 | 
			
		||||
         * stack region has already been configured. */
 | 
			
		||||
        if( ulStackDepth != 0x0UL )
 | 
			
		||||
        {
 | 
			
		||||
            ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) );
 | 
			
		||||
 | 
			
		||||
            /* MPU region base address must be aligned to the region size
 | 
			
		||||
             * boundary. */
 | 
			
		||||
            ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL );
 | 
			
		||||
            configASSERT( ( ( uint32_t ) pxBottomOfStack % ( ulRegionLengthDecoded ) ) == 0U );
 | 
			
		||||
 | 
			
		||||
            ulIndex = portSTACK_REGION;
 | 
			
		||||
            xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack;
 | 
			
		||||
            xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
 | 
			
		||||
                                                              portMPU_REGION_ENABLE );;
 | 
			
		||||
            xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
 | 
			
		||||
                                                                   portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
BaseType_t xPortIsTaskPrivileged( void )
 | 
			
		||||
{
 | 
			
		||||
    BaseType_t xTaskIsPrivileged = pdFALSE;
 | 
			
		||||
 | 
			
		||||
    /* Calling task's MPU settings. */
 | 
			
		||||
    const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
 | 
			
		||||
 | 
			
		||||
    if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
 | 
			
		||||
    {
 | 
			
		||||
        xTaskIsPrivileged = pdTRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return xTaskIsPrivileged;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
BaseType_t xPortStartScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
    /* Start the timer that generates the tick ISR. */
 | 
			
		||||
    configSETUP_TICK_INTERRUPT();
 | 
			
		||||
 | 
			
		||||
    /* Configure MPU regions that are common to all tasks. */
 | 
			
		||||
    prvSetupMPU();
 | 
			
		||||
 | 
			
		||||
    prvPortSchedulerRunning = pdTRUE;
 | 
			
		||||
 | 
			
		||||
    /* Load the context of the first task. */
 | 
			
		||||
    vPortStartFirstTask();
 | 
			
		||||
 | 
			
		||||
    /* Will only get here if vTaskStartScheduler() was called with the CPU in
 | 
			
		||||
     * a non-privileged mode or the binary point register was not set to its lowest
 | 
			
		||||
     * possible value. prvTaskExitError() is referenced to prevent a compiler
 | 
			
		||||
     * warning about it being defined but not referenced in the case that the user
 | 
			
		||||
     * defines their own exit address. */
 | 
			
		||||
    ( void ) prvTaskExitError();
 | 
			
		||||
    return pdFALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulRegionSize, ulReturnValue = 4U;
 | 
			
		||||
 | 
			
		||||
    /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs. */
 | 
			
		||||
    for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) )
 | 
			
		||||
    {
 | 
			
		||||
        if( ulActualMPURegionSize <= ulRegionSize )
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            ulReturnValue++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Shift the code by one before returning so it can be written directly
 | 
			
		||||
     * into the the correct bit position of the attribute register. */
 | 
			
		||||
    return ulReturnValue << 1UL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
static void prvSetupMPU( void )
 | 
			
		||||
{
 | 
			
		||||
#if defined( __ARMCC_VERSION )
 | 
			
		||||
    /* Declaration when these variable are defined in code. */
 | 
			
		||||
    /* Sections used for FLASH. */
 | 
			
		||||
    extern uint32_t * __FLASH_segment_start__;
 | 
			
		||||
    extern uint32_t * __FLASH_segment_end__;
 | 
			
		||||
    extern uint32_t * __privileged_functions_start__;
 | 
			
		||||
    extern uint32_t * __privileged_functions_end__;
 | 
			
		||||
 | 
			
		||||
    /* Sections used for RAM. */
 | 
			
		||||
    extern uint32_t * __SRAM_segment_start__;
 | 
			
		||||
    extern uint32_t * __SRAM_segment_end__;
 | 
			
		||||
    extern uint32_t * __privileged_data_start__;
 | 
			
		||||
    extern uint32_t * __privileged_data_end__;
 | 
			
		||||
#else
 | 
			
		||||
    /* Declaration when these variable are exported from linker scripts. */
 | 
			
		||||
    /* Sections used for FLASH. */
 | 
			
		||||
    extern uint32_t __FLASH_segment_start__[];
 | 
			
		||||
    extern uint32_t __FLASH_segment_end__[];
 | 
			
		||||
    extern uint32_t __privileged_functions_start__[];
 | 
			
		||||
    extern uint32_t __privileged_functions_end__[];
 | 
			
		||||
 | 
			
		||||
    /* Sections used for RAM. */
 | 
			
		||||
    extern uint32_t __SRAM_segment_start__[];
 | 
			
		||||
    extern uint32_t __SRAM_segment_end__[];
 | 
			
		||||
    extern uint32_t __privileged_data_start__[];
 | 
			
		||||
    extern uint32_t __privileged_data_end__[];
 | 
			
		||||
#endif /* if defined( __ARMCC_VERSION ) */
 | 
			
		||||
 | 
			
		||||
    uint32_t ulRegionLength;
 | 
			
		||||
    uint32_t ulRegionLengthEncoded;
 | 
			
		||||
 | 
			
		||||
    /* Disable the MPU before programming it. */
 | 
			
		||||
    vMPUDisable();
 | 
			
		||||
 | 
			
		||||
    /* Priv: RX, Unpriv: RX for entire Flash. */
 | 
			
		||||
    ulRegionLength = ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__;
 | 
			
		||||
    ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
 | 
			
		||||
    vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION,
 | 
			
		||||
                   ( uint32_t ) __FLASH_segment_start__,
 | 
			
		||||
                   ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
 | 
			
		||||
                   ( portMPU_REGION_PRIV_RO_USER_RO_EXEC |
 | 
			
		||||
                     portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) );
 | 
			
		||||
 | 
			
		||||
    /* Priv: RX, Unpriv: No access for privileged functions. */
 | 
			
		||||
    ulRegionLength = ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__;
 | 
			
		||||
    ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
 | 
			
		||||
    vMPUSetRegion( portPRIVILEGED_FLASH_REGION,
 | 
			
		||||
                   ( uint32_t ) __privileged_functions_start__,
 | 
			
		||||
                   ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
 | 
			
		||||
                   ( portMPU_REGION_PRIV_RO_USER_NA_EXEC |
 | 
			
		||||
                     portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) );
 | 
			
		||||
 | 
			
		||||
    /* Priv: RW, Unpriv: No Access for privileged data. */
 | 
			
		||||
    ulRegionLength = ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__;
 | 
			
		||||
    ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
 | 
			
		||||
    vMPUSetRegion( portPRIVILEGED_RAM_REGION,
 | 
			
		||||
                   ( uint32_t ) __privileged_data_start__,
 | 
			
		||||
                   ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
 | 
			
		||||
                   ( portMPU_REGION_PRIV_RW_USER_NA_NOEXEC |
 | 
			
		||||
                     portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ) );
 | 
			
		||||
 | 
			
		||||
    /* Enable the MPU background region - it allows privileged operating modes
 | 
			
		||||
     * access to unmapped regions of memory without generating a fault. */
 | 
			
		||||
    vMPUEnableBackgroundRegion();
 | 
			
		||||
 | 
			
		||||
    /* After setting default regions, enable the MPU. */
 | 
			
		||||
    vMPUEnable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion,
 | 
			
		||||
                                                const uint32_t ulBufferStart,
 | 
			
		||||
                                                const uint32_t ulBufferLength,
 | 
			
		||||
                                                const uint32_t ulAccessRequested )
 | 
			
		||||
{
 | 
			
		||||
    BaseType_t xAccessGranted = pdFALSE;
 | 
			
		||||
    uint32_t ulBufferEnd;
 | 
			
		||||
    uint32_t ulMPURegionLength;
 | 
			
		||||
    uint32_t ulMPURegionStart;
 | 
			
		||||
    uint32_t ulMPURegionEnd;
 | 
			
		||||
    uint32_t ulMPURegionAccessPermissions;
 | 
			
		||||
 | 
			
		||||
    if( portADD_UINT32_WILL_OVERFLOW( ulBufferStart, ( ulBufferLength - 1UL ) ) == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        ulBufferEnd = ulBufferStart + ulBufferLength - 1UL;
 | 
			
		||||
        ulMPURegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL );
 | 
			
		||||
        ulMPURegionStart = xTaskMPURegion->ulRegionBaseAddress;
 | 
			
		||||
        ulMPURegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulMPURegionLength - 1UL;
 | 
			
		||||
 | 
			
		||||
        if( ( ulBufferStart >= ulMPURegionStart ) &&
 | 
			
		||||
            ( ulBufferEnd <= ulMPURegionEnd ) &&
 | 
			
		||||
            ( ulBufferStart <= ulBufferEnd ) )
 | 
			
		||||
        {
 | 
			
		||||
            ulMPURegionAccessPermissions = xTaskMPURegion->ulRegionAttribute & portMPU_REGION_AP_BITMASK;
 | 
			
		||||
 | 
			
		||||
            if( ulAccessRequested == tskMPU_READ_PERMISSION ) /* RO. */
 | 
			
		||||
            {
 | 
			
		||||
                if( ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RO ) ||
 | 
			
		||||
                    ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RO_USER_RO ) )
 | 
			
		||||
                {
 | 
			
		||||
                    xAccessGranted = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if( ( ulAccessRequested & tskMPU_WRITE_PERMISSION ) != 0UL ) /* W or RW. */
 | 
			
		||||
            {
 | 
			
		||||
                if( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RW )
 | 
			
		||||
                {
 | 
			
		||||
                    xAccessGranted = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return xAccessGranted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
 | 
			
		||||
                                            uint32_t ulBufferLength,
 | 
			
		||||
                                            uint32_t ulAccessRequested )
 | 
			
		||||
{
 | 
			
		||||
    BaseType_t xAccessGranted = pdFALSE;
 | 
			
		||||
    uint32_t ulRegionIndex;
 | 
			
		||||
    xMPU_SETTINGS * xTaskMPUSettings = NULL;
 | 
			
		||||
 | 
			
		||||
    if( prvPortSchedulerRunning == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        /* Grant access to all the memory before the scheduler is started. It is
 | 
			
		||||
         * necessary because there is no task running yet and therefore, we
 | 
			
		||||
         * cannot use the permissions of any task. */
 | 
			
		||||
        xAccessGranted = pdTRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* Calling task's MPU settings. */
 | 
			
		||||
        xTaskMPUSettings = xTaskGetMPUSettings( NULL );
 | 
			
		||||
 | 
			
		||||
        if( ( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
 | 
			
		||||
        {
 | 
			
		||||
            /* Privileged tasks have access to all the memory. */
 | 
			
		||||
            xAccessGranted = pdTRUE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            for( ulRegionIndex = 0x0UL; ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB; ulRegionIndex++ )
 | 
			
		||||
            {
 | 
			
		||||
                xAccessGranted = prvMPURegionAuthorizesBuffer( &( xTaskMPUSettings->xRegion[ ulRegionIndex ] ),
 | 
			
		||||
                                                               ( uint32_t ) pvBuffer,
 | 
			
		||||
                                                               ulBufferLength,
 | 
			
		||||
                                                               ulAccessRequested );
 | 
			
		||||
 | 
			
		||||
                if( xAccessGranted == pdTRUE )
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return xAccessGranted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
 | 
			
		||||
    BaseType_t xAccessGranted = pdFALSE;
 | 
			
		||||
    const xMPU_SETTINGS * xTaskMpuSettings;
 | 
			
		||||
 | 
			
		||||
    if( prvPortSchedulerRunning == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        /* Grant access to all the kernel objects before the scheduler
 | 
			
		||||
         * is started. It is necessary because there is no task running
 | 
			
		||||
         * yet and therefore, we cannot use the permissions of any
 | 
			
		||||
         * task. */
 | 
			
		||||
        xAccessGranted = pdTRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* Calling task's MPU settings. */
 | 
			
		||||
        xTaskMpuSettings = xTaskGetMPUSettings( NULL );
 | 
			
		||||
 | 
			
		||||
        ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                          / portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
        ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                        % portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
 | 
			
		||||
        if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
 | 
			
		||||
        {
 | 
			
		||||
            xAccessGranted = pdTRUE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if( ( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) &
 | 
			
		||||
                  ( 1U << ulAccessControlListEntryBit ) ) != 0UL )
 | 
			
		||||
            {
 | 
			
		||||
                xAccessGranted = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return xAccessGranted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject )
 | 
			
		||||
{
 | 
			
		||||
    ( void ) lInternalIndexOfKernelObject;
 | 
			
		||||
 | 
			
		||||
    /* If Access Control List feature is not used, all the tasks have
 | 
			
		||||
     * access to all the kernel objects. */
 | 
			
		||||
    return pdTRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
 | 
			
		||||
                                     int32_t lInternalIndexOfKernelObject )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
 | 
			
		||||
    xMPU_SETTINGS * xTaskMpuSettings;
 | 
			
		||||
 | 
			
		||||
    ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                      / portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
    ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                    % portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
 | 
			
		||||
    xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
 | 
			
		||||
 | 
			
		||||
    xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
 | 
			
		||||
                                      int32_t lInternalIndexOfKernelObject )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
 | 
			
		||||
    xMPU_SETTINGS * xTaskMpuSettings;
 | 
			
		||||
 | 
			
		||||
    ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                      / portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
    ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
 | 
			
		||||
                                    % portACL_ENTRY_SIZE_BITS );
 | 
			
		||||
 | 
			
		||||
    xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
 | 
			
		||||
 | 
			
		||||
    xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
void prvTaskExitError( void )
 | 
			
		||||
{
 | 
			
		||||
    /* A function that implements a task must not exit or attempt to return to
 | 
			
		||||
     * its caller as there is nothing to return to. If a task wants to exit it
 | 
			
		||||
     * should instead call vTaskDelete( NULL ).
 | 
			
		||||
     *
 | 
			
		||||
     * Artificially force an assert() to be triggered if configASSERT() is
 | 
			
		||||
     * defined, then stop here so application writers can catch the error. */
 | 
			
		||||
    configASSERT( ulPortInterruptNesting == ~0UL );
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
void vPortEndScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
    prvPortSchedulerRunning = pdFALSE;
 | 
			
		||||
 | 
			
		||||
    /* Not implemented in this port. Artificially force an assert. */
 | 
			
		||||
    configASSERT( prvPortSchedulerRunning == pdTRUE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
    /* Now that interrupts are disabled, ulCriticalNesting can be accessed
 | 
			
		||||
     * directly.  Increment ulCriticalNesting to keep a count of how many times
 | 
			
		||||
     * portENTER_CRITICAL() has been called. */
 | 
			
		||||
    ulCriticalNesting++;
 | 
			
		||||
 | 
			
		||||
    /* This is not the interrupt safe version of the enter critical function so
 | 
			
		||||
     * assert() if it is being called from an interrupt context.  Only API
 | 
			
		||||
     * functions that end in "FromISR" can be used in an interrupt.  Only assert
 | 
			
		||||
     * if the critical nesting count is 1 to protect against recursive calls if
 | 
			
		||||
     * the assert function also uses a critical section. */
 | 
			
		||||
    if( ulCriticalNesting == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( ulPortInterruptNesting == 0 );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* PRIVILEGED_FUNCTION */
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
    if( ulCriticalNesting > portNO_CRITICAL_NESTING )
 | 
			
		||||
    {
 | 
			
		||||
        /* Decrement the nesting count as the critical section is being
 | 
			
		||||
         * exited. */
 | 
			
		||||
        ulCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        /* If the nesting level has reached zero then all interrupt
 | 
			
		||||
         * priorities must be re-enabled. */
 | 
			
		||||
        if( ulCriticalNesting == portNO_CRITICAL_NESTING )
 | 
			
		||||
        {
 | 
			
		||||
            /* Critical nesting has reached zero so all interrupt priorities
 | 
			
		||||
             * should be unmasked. */
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
							
								
								
									
										498
									
								
								portable/GCC/ARM_CRx_MPU/portASM.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								portable/GCC/ARM_CRx_MPU/portASM.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,498 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
    .arm
 | 
			
		||||
    .syntax unified
 | 
			
		||||
    .section privileged_functions
 | 
			
		||||
 | 
			
		||||
#define FREERTOS_ASSEMBLY
 | 
			
		||||
    #include "portmacro_asm.h"
 | 
			
		||||
    #include "mpu_syscall_numbers.h"
 | 
			
		||||
#undef FREERTOS_ASSEMBLY
 | 
			
		||||
 | 
			
		||||
    /* External FreeRTOS-Kernel variables. */
 | 
			
		||||
    .extern pxCurrentTCB
 | 
			
		||||
    .extern uxSystemCallImplementations
 | 
			
		||||
    .extern ulPortInterruptNesting
 | 
			
		||||
    .extern ulPortYieldRequired
 | 
			
		||||
 | 
			
		||||
    /* External Llnker script variables. */
 | 
			
		||||
    .extern __syscalls_flash_start__
 | 
			
		||||
    .extern __syscalls_flash_end__
 | 
			
		||||
 | 
			
		||||
    /* External FreeRTOS-Kernel functions. */
 | 
			
		||||
    .extern vTaskSwitchContext
 | 
			
		||||
    .extern vApplicationIRQHandler
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* Save the context of a FreeRTOS Task. */
 | 
			
		||||
.macro portSAVE_CONTEXT
 | 
			
		||||
    DSB
 | 
			
		||||
    ISB
 | 
			
		||||
    /* Push R0 and LR to the stack for current mode. */
 | 
			
		||||
    PUSH    { R0, LR }
 | 
			
		||||
 | 
			
		||||
    LDR     LR, =pxCurrentTCB   /* LR = &( pxCurrentTCB ). */
 | 
			
		||||
    LDR     LR, [LR]            /* LR = pxCurrentTCB. */
 | 
			
		||||
    LDR     LR, [LR]            /* LR = pxTopOfStack i.e. the address where to store the task context. */
 | 
			
		||||
 | 
			
		||||
    LDR     R0, =ulCriticalNesting  /* R0 = &( ulCriticalNesting ). */
 | 
			
		||||
    LDR     R0, [R0]                /* R0 = ulCriticalNesting. */
 | 
			
		||||
    STM     LR!, { R0 }             /* Store ulCriticalNesting. ! increments LR after storing. */
 | 
			
		||||
 | 
			
		||||
#if ( portENABLE_FPU == 1 )
 | 
			
		||||
    VMRS    R0, FPSCR       /* R0 = FPSCR. */
 | 
			
		||||
    STM     LR!, { R0 }     /* Store FPSCR. */
 | 
			
		||||
    VSTM    LR!, { D0-D15 } /* Store D0-D15. */
 | 
			
		||||
#endif /* ( portENABLE_FPU == 1 ) */
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }  /* Restore R0 to pre-exception value. */
 | 
			
		||||
    /* STM (user registers) - In a PL1 mode other than System mode, STM (user
 | 
			
		||||
     * registers) instruction stores multiple User mode registers to
 | 
			
		||||
     * consecutive memory locations using an address from a base register. The
 | 
			
		||||
     * processor reads the base register value normally, using the current mode
 | 
			
		||||
     * to determine the correct Banked version of the register. This instruction
 | 
			
		||||
     * cannot writeback to the base register.
 | 
			
		||||
     *
 | 
			
		||||
     * The following can be derived from the above description:
 | 
			
		||||
     * - The macro portSAVE_CONTEXT MUST be called from a PL1 mode other than
 | 
			
		||||
     *   the System mode.
 | 
			
		||||
     * - Base register LR of the current mode will be used which contains the
 | 
			
		||||
     *   location to store the context.
 | 
			
		||||
     * - It will store R0-R14 of User mode i.e. pre-exception SP(R13) and LR(R14)
 | 
			
		||||
     *   will be stored. */
 | 
			
		||||
    STM     LR, { R0-R14 }^
 | 
			
		||||
    ADD     LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }          /* Pre-exception PC is in R0. */
 | 
			
		||||
    MRS     R1, SPSR        /* R1 = Pre-exception CPSR. */
 | 
			
		||||
    STM     LR!, { R0-R1 }  /* Store pre-exception PC and CPSR. */
 | 
			
		||||
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* Restore the context of a FreeRTOS Task. */
 | 
			
		||||
.macro portRESTORE_CONTEXT
 | 
			
		||||
    /* Load the pointer to the current task's Task Control Block (TCB). */
 | 
			
		||||
    LDR     LR, =pxCurrentTCB   /* LR = &( pxCurrentTCB ). */
 | 
			
		||||
    LDR     LR, [LR]            /* LR = pxCurrentTCB. */
 | 
			
		||||
    ADD     R1, LR, #0x4        /* R1 now points to the xMPUSettings in TCB. */
 | 
			
		||||
    LDR     LR, [LR]            /* LR = pxTopOfStack i.e. the address where to restore the task context from. */
 | 
			
		||||
 | 
			
		||||
    /* When creating a loop label in a macro it has to be a numeric label.
 | 
			
		||||
     * for( R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */
 | 
			
		||||
    MOV     R5, #portFIRST_CONFIGURABLE_REGION
 | 
			
		||||
    123:
 | 
			
		||||
        LDMIA   R1!, { R2-R4 }  /* R2 = ulRegionSize, R3 = ulRegionAttribute, R4 = ulRegionBaseAddress. */
 | 
			
		||||
 | 
			
		||||
        MCR     p15, #0, R5, c6, c2, #0 /* MPU Region Number Register. */
 | 
			
		||||
        MCR     p15, #0, R4, c6, c1, #0 /* MPU Region Base Address Register. */
 | 
			
		||||
        MCR     p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */
 | 
			
		||||
        MCR     p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */
 | 
			
		||||
 | 
			
		||||
        ADD     R5, R5, #1
 | 
			
		||||
        CMP     R5, #portNUM_CONFIGURABLE_REGIONS
 | 
			
		||||
        BLE     123b
 | 
			
		||||
 | 
			
		||||
    LDR     R1, =ulCriticalNesting /* R1 = &( ulCriticalNesting ). */
 | 
			
		||||
    LDM     LR!, { R2 }            /* R2 = Stored ulCriticalNesting. */
 | 
			
		||||
    STR     R2, [R1]               /* Restore ulCriticalNesting. */
 | 
			
		||||
 | 
			
		||||
#if ( portENABLE_FPU == 1 )
 | 
			
		||||
    LDM     LR!, { R1 }     /* R1 = Stored FPSCR.  */
 | 
			
		||||
    VMSR    FPSCR, R1       /* Restore FPSCR. */
 | 
			
		||||
    VLDM   LR!, { D0-D15 }  /* Restore D0-D15. */
 | 
			
		||||
#endif /* portENABLE_FPU*/
 | 
			
		||||
 | 
			
		||||
    /* LDM (User registers) - In a PL1 mode other than System mode, LDM (User
 | 
			
		||||
     * registers) loads multiple User mode registers from consecutive memory
 | 
			
		||||
     * locations using an address from a base register. The registers loaded
 | 
			
		||||
     * cannot include the PC. The processor reads the base register value
 | 
			
		||||
     * normally, using the current mode to determine the correct Banked version
 | 
			
		||||
     * of the register. This instruction cannot writeback to the base register.
 | 
			
		||||
     *
 | 
			
		||||
     *  The following can be derived from the above description:
 | 
			
		||||
     * - The macro portRESTORE_CONTEXT MUST be called from a PL1 mode other than
 | 
			
		||||
     *   the System mode.
 | 
			
		||||
     * - Base register LR of the current mode will be used which contains the
 | 
			
		||||
     *   location to restore the context from.
 | 
			
		||||
     * - It will restore R0-R14 of User mode i.e. SP(R13) and LR(R14) of User
 | 
			
		||||
     *   mode will be restored.
 | 
			
		||||
     */
 | 
			
		||||
    LDM     LR, { R0-R14 }^
 | 
			
		||||
    ADD     LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */
 | 
			
		||||
 | 
			
		||||
    RFE     LR  /* Restore PC and CPSR from the context. */
 | 
			
		||||
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vPortStartFirstTask( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vPortStartFirstTask
 | 
			
		||||
.type vPortStartFirstTask, %function
 | 
			
		||||
vPortStartFirstTask:
 | 
			
		||||
    /* This function is called from System Mode to start the FreeRTOS-Kernel.
 | 
			
		||||
     * As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot
 | 
			
		||||
     * be called from the System mode. We, therefore, switch to the Supervisor
 | 
			
		||||
     * mode before calling portRESTORE_CONTEXT. */
 | 
			
		||||
    CPS #SVC_MODE
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.align 4
 | 
			
		||||
.global FreeRTOS_SVC_Handler
 | 
			
		||||
.type FreeRTOS_SVC_Handler, %function
 | 
			
		||||
FreeRTOS_SVC_Handler:
 | 
			
		||||
    PUSH    { R11-R12 }
 | 
			
		||||
 | 
			
		||||
    /* ------------------------- Caller Flash Location Check ------------------------- */
 | 
			
		||||
 | 
			
		||||
    LDR     R11, =__syscalls_flash_start__
 | 
			
		||||
    LDR     R12, =__syscalls_flash_end__
 | 
			
		||||
    CMP     LR, R11 /* If SVC instruction address is less than __syscalls_flash_start__, exit. */
 | 
			
		||||
    BLT     svcHandlerExit
 | 
			
		||||
    CMP     LR, R12 /* If SVC instruction address is greater than __syscalls_flash_end__, exit. */
 | 
			
		||||
    BGT     svcHandlerExit
 | 
			
		||||
 | 
			
		||||
    /* ---------------------------- Get Caller SVC Number ---------------------------- */
 | 
			
		||||
 | 
			
		||||
    MRS     R11, SPSR               /* LR = CPSR at the time of SVC. */
 | 
			
		||||
    TST     R11, #0x20              /* Check Thumb bit (5) in CPSR. */
 | 
			
		||||
    LDRHNE  R11, [LR, #-0x2]        /* If Thumb, load halfword. */
 | 
			
		||||
    BICNE   R11, R11, #0xFF00       /* And extract immidiate field (i.e. SVC number). */
 | 
			
		||||
    LDREQ   R11, [LR, #-0x4]        /* If ARM, load word. */
 | 
			
		||||
    BICEQ   R11, R11, #0xFF000000   /* And extract immidiate field (i.e. SVC number). */
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------- SVC Routing --------------------------------- */
 | 
			
		||||
 | 
			
		||||
    /* If SVC Number < #NUM_SYSTEM_CALLS, go to svcSystemCallEnter. */
 | 
			
		||||
    CMP     R11, #NUM_SYSTEM_CALLS
 | 
			
		||||
    BLT     svcSystemCallEnter
 | 
			
		||||
 | 
			
		||||
    /* If SVC Number == #portSVC_SYSTEM_CALL_EXIT, go to svcSystemCallExit. */
 | 
			
		||||
    CMP     R11, #portSVC_SYSTEM_CALL_EXIT
 | 
			
		||||
    BEQ     svcSystemCallExit
 | 
			
		||||
 | 
			
		||||
    /* If SVC Number == #portSVC_YIELD, go to svcPortYield. */
 | 
			
		||||
    CMP     R11, #portSVC_YIELD
 | 
			
		||||
    BEQ     svcPortYield
 | 
			
		||||
 | 
			
		||||
svcHandlerExit:
 | 
			
		||||
    POP     { R11-R12 }
 | 
			
		||||
    MOVS    PC, LR /* Copies the SPSR into the CPSR, performing the mode swap. */
 | 
			
		||||
 | 
			
		||||
svcPortYield:
 | 
			
		||||
    POP     { R11-R12 }
 | 
			
		||||
    portSAVE_CONTEXT
 | 
			
		||||
    BL      vTaskSwitchContext
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
 | 
			
		||||
svcSystemCallExit:
 | 
			
		||||
    LDR     R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */
 | 
			
		||||
    LDR     R11, [R11]         /* R11 = pxCurrentTCB. */
 | 
			
		||||
    ADD     R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */
 | 
			
		||||
 | 
			
		||||
    /* Restore the user mode SP and LR. */
 | 
			
		||||
    LDM   R11, { R13-R14 }^
 | 
			
		||||
 | 
			
		||||
    AND     R12, R12, #0x0      /* R12 = 0. */
 | 
			
		||||
    STR     R12, [R11]          /* xSystemCallStackInfo.pulTaskStackPointer = NULL. */
 | 
			
		||||
    STR     R12, [R11, #0x4]    /* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry = NULL. */
 | 
			
		||||
 | 
			
		||||
    LDMDB   R11, { R12 }        /* R12 = ulTaskFlags. */
 | 
			
		||||
 | 
			
		||||
    TST     R12, #portTASK_IS_PRIVILEGED_FLAG
 | 
			
		||||
    /* If the task is privileged, we can exit now. */
 | 
			
		||||
    BNE     svcHandlerExit
 | 
			
		||||
    /* Otherwise, we need to switch back to User mode. */
 | 
			
		||||
    MRS     R12, SPSR
 | 
			
		||||
    BIC     R12, R12, #0x0F
 | 
			
		||||
    MSR     SPSR_cxsf, R12
 | 
			
		||||
 | 
			
		||||
    B   svcHandlerExit
 | 
			
		||||
 | 
			
		||||
svcSystemCallEnter:
 | 
			
		||||
    LDR     R12, =uxSystemCallImplementations /* R12 = uxSystemCallImplementations. */
 | 
			
		||||
    /* R12 = uxSystemCallImplementations[ R12 + ( R11 << 2 ) ].
 | 
			
		||||
     * R12 now contains the address of the system call impl function. */
 | 
			
		||||
    LDR     R12, [R12, R11, lsl #2]
 | 
			
		||||
 | 
			
		||||
    /* If R12 == NULL, exit. */
 | 
			
		||||
    CMP     R12, #0x0
 | 
			
		||||
    BEQ     svcHandlerExit
 | 
			
		||||
 | 
			
		||||
    /* It is okay to clobber LR here because we do not need to return to the
 | 
			
		||||
     * SVC enter location anymore. LR now contains the address of the system
 | 
			
		||||
     * call impl function. */
 | 
			
		||||
    MOV     LR, R12
 | 
			
		||||
 | 
			
		||||
    LDR     R11, =pxCurrentTCB  /* R11 = &( pxCurrentTCB ). */
 | 
			
		||||
    LDR     R11, [R11]          /* R11 = pxCurrentTCB. */
 | 
			
		||||
    ADD     R11, R11, #portSYSTEM_CALL_INFO_OFFSET  /* R11 now points to xSystemCallStackInfo in TCB. */
 | 
			
		||||
 | 
			
		||||
    /* Store User mode SP and LR in xSystemCallStackInfo.pulTaskStackPointer and
 | 
			
		||||
     * xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry. */
 | 
			
		||||
    STM     R11, { R13-R14 }^
 | 
			
		||||
    ADD     R11, R11, 0x8
 | 
			
		||||
 | 
			
		||||
    /* Load User mode SP an LR with xSystemCallStackInfo.pulSystemCallStackPointer
 | 
			
		||||
     * and xSystemCallStackInfo.pulSystemCallExitAddress. */
 | 
			
		||||
    LDM     R11, { R13-R14 }^
 | 
			
		||||
 | 
			
		||||
    /* Change to SYS_MODE for the System Call. */
 | 
			
		||||
    MRS     R12, SPSR
 | 
			
		||||
    ORR     R12, R12, #SYS_MODE
 | 
			
		||||
    MSR     SPSR_cxsf, R12
 | 
			
		||||
 | 
			
		||||
    B       svcHandlerExit
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vPortDisableInterrupts( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vPortDisableInterrupts
 | 
			
		||||
.type vPortDisableInterrupts, %function
 | 
			
		||||
vPortDisableInterrupts:
 | 
			
		||||
    CPSID    I
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vPortEnableInterrupts( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vPortEnableInterrupts
 | 
			
		||||
.type vPortEnableInterrupts, %function
 | 
			
		||||
vPortEnableInterrupts:
 | 
			
		||||
    CPSIE   I
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vMPUSetRegion( uint32_t ulRegionNumber,
 | 
			
		||||
 *                     uint32_t ulBaseAddress,
 | 
			
		||||
 *                     uint32_t ulRegionSize,
 | 
			
		||||
 *                     uint32_t ulRegionPermissions );
 | 
			
		||||
 *
 | 
			
		||||
 * According to the Procedure Call Standard for the ARM Architecture (AAPCS),
 | 
			
		||||
 * paramters are passed in the following registers:
 | 
			
		||||
 * R0 = ulRegionNumber.
 | 
			
		||||
 * R1 = ulBaseAddress.
 | 
			
		||||
 * R2 = ulRegionSize.
 | 
			
		||||
 * R3 = ulRegionPermissions.
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vMPUSetRegion
 | 
			
		||||
.type vMPUSetRegion, %function
 | 
			
		||||
vMPUSetRegion:
 | 
			
		||||
    AND     R0,  R0, #0x0F    /* R0 = R0 & 0x0F. Max possible region number is 15. */
 | 
			
		||||
 | 
			
		||||
    MCR     p15, #0, R0, c6, c2, #0 /* MPU Region Number Register. */
 | 
			
		||||
    MCR     p15, #0, R1, c6, c1, #0 /* MPU Region Base Address Register. */
 | 
			
		||||
    MCR     p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */
 | 
			
		||||
    MCR     p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */
 | 
			
		||||
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vMPUEnable( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vMPUEnable
 | 
			
		||||
.type vMPUEnable, %function
 | 
			
		||||
vMPUEnable:
 | 
			
		||||
    PUSH    { R0 }
 | 
			
		||||
 | 
			
		||||
    MRC     p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
 | 
			
		||||
    ORR     R0,  R0, #0x1 /* R0 = R0 | 0x1. Set the M bit in SCTLR. */
 | 
			
		||||
    DSB
 | 
			
		||||
    MCR     p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
 | 
			
		||||
    ISB
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vMPUDisable( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vMPUDisable
 | 
			
		||||
.type vMPUDisable, %function
 | 
			
		||||
vMPUDisable:
 | 
			
		||||
    PUSH    { R0 }
 | 
			
		||||
 | 
			
		||||
    MRC     p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
 | 
			
		||||
    BIC     R0,  R0, #1 /* R0 = R0 & ~0x1. Clear the M bit in SCTLR. */
 | 
			
		||||
    /* Wait for all pending data accesses to complete. */
 | 
			
		||||
    DSB
 | 
			
		||||
    MCR     p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
 | 
			
		||||
    /* Flush the pipeline and prefetch buffer(s) in the processor to ensure that
 | 
			
		||||
    *  all following instructions are fetched from cache or memory. */
 | 
			
		||||
    ISB
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vMPUEnableBackgroundRegion( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vMPUEnableBackgroundRegion
 | 
			
		||||
.type vMPUEnableBackgroundRegion, %function
 | 
			
		||||
vMPUEnableBackgroundRegion:
 | 
			
		||||
    PUSH    { R0 }
 | 
			
		||||
 | 
			
		||||
    MRC     p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
 | 
			
		||||
    ORR     R0, R0, #0x20000 /* R0 = R0 | 0x20000. Set the BR bit in SCTLR. */
 | 
			
		||||
    MCR     p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * void vMPUDisableBackgroundRegion( void );
 | 
			
		||||
 */
 | 
			
		||||
.align 4
 | 
			
		||||
.global vMPUDisableBackgroundRegion
 | 
			
		||||
.type vMPUDisableBackgroundRegion, %function
 | 
			
		||||
vMPUDisableBackgroundRegion:
 | 
			
		||||
    PUSH    { R0 }
 | 
			
		||||
 | 
			
		||||
    MRC     p15, 0, R0, c1, c0, 0 /* R0 = System Control Register (SCTLR). */
 | 
			
		||||
    BIC     R0, R0, #0x20000 /* R0 = R0 & ~0x20000. Clear the BR bit in SCTLR. */
 | 
			
		||||
    MCR     p15, 0, R0, c1, c0, 0 /* SCTLR = R0. */
 | 
			
		||||
 | 
			
		||||
    POP     { R0 }
 | 
			
		||||
    BX      LR
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.align 4
 | 
			
		||||
.global FreeRTOS_IRQ_Handler
 | 
			
		||||
.type FreeRTOS_IRQ_Handler, %function
 | 
			
		||||
FreeRTOS_IRQ_Handler:
 | 
			
		||||
    SUB     LR, LR, #4 /* Return to the interrupted instruction. */
 | 
			
		||||
    SRSDB   SP!, #IRQ_MODE /* Save return state (i.e. SPSR_irq and LR_irq) to the IRQ stack. */
 | 
			
		||||
 | 
			
		||||
    /* Change to supervisor mode to allow reentry. It is necessary to ensure
 | 
			
		||||
     * that a BL instruction within the interrupt handler code does not
 | 
			
		||||
     * overwrite LR_irq. */
 | 
			
		||||
    CPS     #SVC_MODE
 | 
			
		||||
 | 
			
		||||
    PUSH    { R0-R3, R12 } /* Push AAPCS callee saved registers. */
 | 
			
		||||
 | 
			
		||||
    /* Update interrupt nesting count. */
 | 
			
		||||
    LDR     R0, =ulPortInterruptNesting /* R0 = &( ulPortInterruptNesting ). */
 | 
			
		||||
    LDR     R1, [R0] /* R1 = ulPortInterruptNesting. */
 | 
			
		||||
    ADD     R2, R1, #1 /* R2 = R1 + 1. */
 | 
			
		||||
    STR     R2, [R0] /* Store the updated nesting count. */
 | 
			
		||||
 | 
			
		||||
    /* Call the application provided IRQ handler. */
 | 
			
		||||
    PUSH    { R0-R3, LR }
 | 
			
		||||
    BL      vApplicationIRQHandler
 | 
			
		||||
    POP     { R0-R3, LR }
 | 
			
		||||
 | 
			
		||||
    /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */
 | 
			
		||||
    CPSID   I
 | 
			
		||||
    DSB
 | 
			
		||||
    ISB
 | 
			
		||||
 | 
			
		||||
    /* Restore the old interrupt nesting count. R0 holds the address of
 | 
			
		||||
     * ulPortInterruptNesting and R1 holds original value of
 | 
			
		||||
     * ulPortInterruptNesting. */
 | 
			
		||||
    STR     R1, [R0]
 | 
			
		||||
 | 
			
		||||
    /* Context swtich is only performed when interrupt nesting count is 0. */
 | 
			
		||||
    CMP     R1, #0
 | 
			
		||||
    BNE     exit_without_switch
 | 
			
		||||
 | 
			
		||||
    /* Check ulPortInterruptNesting to see if the interrupt requested a context
 | 
			
		||||
     * switch. */
 | 
			
		||||
    LDR     R1, =ulPortYieldRequired /* R1 = &( ulPortYieldRequired ). */
 | 
			
		||||
    LDR     R0, [R1] /* R0 = ulPortYieldRequired. */
 | 
			
		||||
    /* If ulPortYieldRequired != 0, goto switch_before_exit. */
 | 
			
		||||
    CMP     R0, #0
 | 
			
		||||
    BNE     switch_before_exit
 | 
			
		||||
 | 
			
		||||
exit_without_switch:
 | 
			
		||||
    POP     { R0-R3, R12 } /* Restore AAPCS callee saved registers. */
 | 
			
		||||
    CPS     #IRQ_MODE
 | 
			
		||||
    RFE     SP!
 | 
			
		||||
 | 
			
		||||
switch_before_exit:
 | 
			
		||||
    /* A context swtich is to be performed. Clear ulPortYieldRequired. R1 holds
 | 
			
		||||
     * the address of ulPortYieldRequired. */
 | 
			
		||||
    MOV     R0, #0
 | 
			
		||||
    STR     R0, [R1]
 | 
			
		||||
 | 
			
		||||
    /* Restore AAPCS callee saved registers, SPSR_irq and LR_irq before saving
 | 
			
		||||
     * the task context. */
 | 
			
		||||
    POP     { R0-R3, R12 }
 | 
			
		||||
    CPS     #IRQ_MODE
 | 
			
		||||
    /* The contents of the IRQ stack at this point is the following:
 | 
			
		||||
     *       +----------+
 | 
			
		||||
     *  SP+4 | SPSR_irq |
 | 
			
		||||
     *       +----------+
 | 
			
		||||
     *    SP |  LR_irq  |
 | 
			
		||||
     *       +----------+
 | 
			
		||||
     */
 | 
			
		||||
    LDMIB   SP!, { LR }
 | 
			
		||||
    MSR     SPSR_cxsf, LR
 | 
			
		||||
    LDMDB   SP, { LR }
 | 
			
		||||
    ADD     SP, SP, 0x4
 | 
			
		||||
    portSAVE_CONTEXT
 | 
			
		||||
 | 
			
		||||
    /* Call the function that selects the new task to execute. */
 | 
			
		||||
    BLX     vTaskSwitchContext
 | 
			
		||||
 | 
			
		||||
    /* Restore the context of, and branch to, the task selected to execute
 | 
			
		||||
     * next. */
 | 
			
		||||
    portRESTORE_CONTEXT
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
.end
 | 
			
		||||
							
								
								
									
										522
									
								
								portable/GCC/ARM_CRx_MPU/portmacro.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										522
									
								
								portable/GCC/ARM_CRx_MPU/portmacro.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,522 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PORTMACRO_H
 | 
			
		||||
#define PORTMACRO_H
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port
 | 
			
		||||
 * @file portmacro.h
 | 
			
		||||
 * @note The settings in this file configure FreeRTOS correctly for the given
 | 
			
		||||
 *  hardware and compiler. These settings should not be altered.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Include stdint for integer types of specific bit widths. */
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* ------------------------------ FreeRTOS Config Check ------------------------------ */
 | 
			
		||||
 | 
			
		||||
#ifndef configSYSTEM_CALL_STACK_SIZE
 | 
			
		||||
    #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \
 | 
			
		||||
            "to use when an unprivileged task makes a FreeRTOS Kernel call. "
 | 
			
		||||
#endif /* configSYSTEM_CALL_STACK_SIZE */
 | 
			
		||||
 | 
			
		||||
#if( configUSE_MPU_WRAPPERS_V1 == 1 )
 | 
			
		||||
    #error This port is usable with MPU wrappers V2 only.
 | 
			
		||||
#endif /* configUSE_MPU_WRAPPERS_V1 */
 | 
			
		||||
 | 
			
		||||
#ifndef configSETUP_TICK_INTERRUPT
 | 
			
		||||
    #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \
 | 
			
		||||
           "to call the function that sets up the tick interrupt."
 | 
			
		||||
#endif /* configSETUP_TICK_INTERRUPT */
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
 | 
			
		||||
 | 
			
		||||
    /* Check the configuration. */
 | 
			
		||||
    #if( configMAX_PRIORITIES > 32 )
 | 
			
		||||
        #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \
 | 
			
		||||
                "configMAX_PRIORITIES is less than or equal to 32. " \
 | 
			
		||||
                "It is very rare that a system requires more than 10 to 15 difference " \
 | 
			
		||||
                "priorities as tasks that share a priority will time slice."
 | 
			
		||||
    #endif /* ( configMAX_PRIORITIES > 32 ) */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Mark that a task of the given priority is ready.
 | 
			
		||||
     *
 | 
			
		||||
     * @ingroup Scheduler
 | 
			
		||||
     *
 | 
			
		||||
     * @param[in] uxPriority Priority of the task that is ready.
 | 
			
		||||
     * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
 | 
			
		||||
     */
 | 
			
		||||
    #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \
 | 
			
		||||
        ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Mark that a task of the given priority is no longer ready.
 | 
			
		||||
     *
 | 
			
		||||
     * @ingroup Scheduler
 | 
			
		||||
     *
 | 
			
		||||
     * @param[in] uxPriority Priority of the task that is no longer ready.
 | 
			
		||||
     * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
 | 
			
		||||
     */
 | 
			
		||||
    #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \
 | 
			
		||||
        ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Determine the highest priority ready task's priority.
 | 
			
		||||
     *
 | 
			
		||||
     * @ingroup Scheduler
 | 
			
		||||
     *
 | 
			
		||||
     * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
 | 
			
		||||
     * @param[in] uxTopPriority The highest priority ready task's priority.
 | 
			
		||||
     */
 | 
			
		||||
    #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \
 | 
			
		||||
        ( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) )
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 | 
			
		||||
 | 
			
		||||
/* ------------------------------ Port Type Definitions ------------------------------ */
 | 
			
		||||
 | 
			
		||||
#include "portmacro_asm.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Critical section nesting value.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Sections
 | 
			
		||||
 *
 | 
			
		||||
 * @note A task exits critical section and enables IRQs when its nesting count
 | 
			
		||||
 * reaches this value.
 | 
			
		||||
 */
 | 
			
		||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is
 | 
			
		||||
 * in Thumb State.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 */
 | 
			
		||||
#define portTHUMB_MODE_BIT      ( ( StackType_t ) 0x20 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Bitmask to check if an address is of Thumb Code.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 */
 | 
			
		||||
#define portTHUMB_MODE_ADDRESS  ( 0x01UL )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Data type used to represent a stack word.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
typedef uint32_t StackType_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Signed data type equal to the data word operating size of the CPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
typedef int32_t BaseType_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Unsigned data type equal to the data word operating size of the CPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
typedef uint32_t UBaseType_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Data type used for the FreeRTOS Tick Counter.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Using 32-bit tick type on a 32-bit architecture ensures that reads of
 | 
			
		||||
 * the tick count do not need to be guarded with a critical section.
 | 
			
		||||
 */
 | 
			
		||||
typedef uint32_t TickType_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Marks the direction the stack grows on the targeted CPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
#define portSTACK_GROWTH   ( -1 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Specifies stack pointer alignment requirements of the target CPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
#define portBYTE_ALIGNMENT 8U
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Task function prototype macro as described on FreeRTOS.org.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 *
 | 
			
		||||
 * @note This is not required for this port but included in case common demo
 | 
			
		||||
 * code uses it.
 | 
			
		||||
 */
 | 
			
		||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
 | 
			
		||||
    void vFunction( void * pvParameters )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Task function prototype macro as described on FreeRTOS.org.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 *
 | 
			
		||||
 * @note This is not required for this port but included in case common demo
 | 
			
		||||
 * code uses it.
 | 
			
		||||
 */
 | 
			
		||||
#define portTASK_FUNCTION( vFunction, pvParameters ) \
 | 
			
		||||
    void vFunction( void * pvParameters )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The no-op ARM assembly instruction.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
#define portNOP()                                    __asm volatile( "NOP" )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The inline GCC label.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
#define portINLINE                                   __inline
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The memory access synchronization barrier.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Interface Specifications
 | 
			
		||||
 */
 | 
			
		||||
#define portMEMORY_BARRIER()                         __asm volatile( "" ::: "memory" )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Defines if the tick count can be accessed atomically.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup System Clock
 | 
			
		||||
 */
 | 
			
		||||
#define portTICK_TYPE_IS_ATOMIC                      1
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The number of miliseconds between system ticks.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup System Clock
 | 
			
		||||
 */
 | 
			
		||||
#define portTICK_PERIOD_MS                           ( ( TickType_t ) 1000UL / configTICK_RATE_HZ )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The largest possible delay value for any FreeRTOS API.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup System Clock
 | 
			
		||||
 */
 | 
			
		||||
#define portMAX_DELAY                                ( TickType_t ) 0xFFFFFFFFUL
 | 
			
		||||
 | 
			
		||||
/* ----------------------------- Port Assembly Functions ----------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief FreeRTOS Supervisor Call (SVC) Handler.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 */
 | 
			
		||||
void FreeRTOS_SVC_Handler( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief FreeRTOS Interrupt Handler.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 */
 | 
			
		||||
void FreeRTOS_IRQ_Handler( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Yield the CPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 */
 | 
			
		||||
void vPortYield( void );
 | 
			
		||||
 | 
			
		||||
#define portYIELD() vPortYield()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enable interrupts.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Interrupt Management
 | 
			
		||||
 */
 | 
			
		||||
void vPortEnableInterrupts( void );
 | 
			
		||||
 | 
			
		||||
#define portENABLE_INTERRUPTS() vPortEnableInterrupts()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Disable interrupts.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Interrupt Management
 | 
			
		||||
 */
 | 
			
		||||
void vPortDisableInterrupts( void );
 | 
			
		||||
 | 
			
		||||
#define portDISABLE_INTERRUPTS() vPortDisableInterrupts()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Exit from a FreeRTO System Call.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 */
 | 
			
		||||
void vPortSystemCallExit( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Start executing first task.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 */
 | 
			
		||||
void vPortStartFirstTask( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enable the onboard MPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
void vMPUEnable( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Disable the onboard MPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
void vMPUDisable( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enable the MPU Background Region.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
void vMPUEnableBackgroundRegion( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Disable the MPU Background Region.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
void vMPUDisableBackgroundRegion( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Set permissions for an MPU Region.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] ulRegionNumber The MPU Region Number to set permissions for.
 | 
			
		||||
 * @param[in] ulBaseAddress The base address of the MPU Region.
 | 
			
		||||
 * @param[in] ulRegionSize The size of the MPU Region in bytes.
 | 
			
		||||
 * @param[in] ulRegionPermissions The permissions associated with the MPU Region.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This is an internal function and assumes that the inputs to this
 | 
			
		||||
 * function are checked before calling this function.
 | 
			
		||||
 */
 | 
			
		||||
void vMPUSetRegion( uint32_t ulRegionNumber,
 | 
			
		||||
                    uint32_t ulBaseAddress,
 | 
			
		||||
                    uint32_t ulRegionSize,
 | 
			
		||||
                    uint32_t ulRegionPermissions );
 | 
			
		||||
 | 
			
		||||
/* ------------------------------- Port.c Declarations ------------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Enter critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Section
 | 
			
		||||
 */
 | 
			
		||||
void vPortEnterCritical( void );
 | 
			
		||||
 | 
			
		||||
#define portENTER_CRITICAL() vPortEnterCritical()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Exit critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Critical Section
 | 
			
		||||
 */
 | 
			
		||||
void vPortExitCritical( void );
 | 
			
		||||
 | 
			
		||||
#define portEXIT_CRITICAL() vPortExitCritical()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Checks whether or not the processor is privileged.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 *
 | 
			
		||||
 * @note The processor privilege level is determined by checking the
 | 
			
		||||
 * mode bits [4:0] of the Current Program Status Register (CPSR).
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE, if the processer is privileged, pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortIsPrivileged( void );
 | 
			
		||||
 | 
			
		||||
#define portIS_PRIVILEGED() xPortIsPrivileged()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Checks whether or not a task is privileged.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 *
 | 
			
		||||
 * @note A task's privilege level is associated with the task and is different from
 | 
			
		||||
 * the processor's privilege level returned by xPortIsPrivileged. For example,
 | 
			
		||||
 * the processor is privileged when an unprivileged task executes a system call.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the task is privileged, pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortIsTaskPrivileged( void );
 | 
			
		||||
 | 
			
		||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Default return address for tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function is used as the default return address for tasks if
 | 
			
		||||
 * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h.
 | 
			
		||||
 */
 | 
			
		||||
void prvTaskExitError( void );
 | 
			
		||||
 | 
			
		||||
#ifdef configTASK_RETURN_ADDRESS
 | 
			
		||||
    #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
 | 
			
		||||
#else
 | 
			
		||||
    #define portTASK_RETURN_ADDRESS prvTaskExitError
 | 
			
		||||
#endif /* configTASK_RETURN_ADDRESS */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Returns the number of leading zeros in a 32 bit variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] ulBitmap 32-Bit number to count leading zeros in.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of leading zeros in ulBitmap.
 | 
			
		||||
 */
 | 
			
		||||
UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief End the FreeRTOS scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * Not implemented on this port.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 */
 | 
			
		||||
void vPortEndScheduler( void );
 | 
			
		||||
 | 
			
		||||
/* --------------------------------- MPU Definitions --------------------------------- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Mark that this port utilizes the onboard ARM MPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 */
 | 
			
		||||
#define portUSING_MPU_WRAPPERS     1
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Used to mark if a task should be created as a privileged task.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @note A privileged task is created by performing a bitwise OR of this value and
 | 
			
		||||
 * the task priority. For example, to create a privileged task at priority 2, the
 | 
			
		||||
 * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ).
 | 
			
		||||
 */
 | 
			
		||||
#define portPRIVILEGE_BIT          ( 0x80000000UL )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Size of an Access Control List (ACL) entry in bits.
 | 
			
		||||
 */
 | 
			
		||||
#define portACL_ENTRY_SIZE_BITS    ( 32UL )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Structure to hold the MPU Register Values.
 | 
			
		||||
 *
 | 
			
		||||
 * @struct xMPU_REGION_REGISTERS
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 *
 | 
			
		||||
 * @note The ordering of this struct MUST be in sync with the ordering in
 | 
			
		||||
 * portRESTORE_CONTEXT.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct MPU_REGION_REGISTERS
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulRegionSize;        /* Information for MPU Region Size and Enable Register. */
 | 
			
		||||
    uint32_t ulRegionAttribute;   /* Information for MPU Region Access Control Register. */
 | 
			
		||||
    uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */
 | 
			
		||||
} xMPU_REGION_REGISTERS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Structure to hold per-task System Call Stack information.
 | 
			
		||||
 *
 | 
			
		||||
 * @struct xSYSTEM_CALL_STACK_INFO
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 *
 | 
			
		||||
 * @note The ordering of this structure MUST be in sync with the assembly code
 | 
			
		||||
 * of the port.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct SYSTEM_CALL_STACK_INFO
 | 
			
		||||
{
 | 
			
		||||
    uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */
 | 
			
		||||
    uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */
 | 
			
		||||
    uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */
 | 
			
		||||
    uint32_t * pulSystemCallExitAddress; /**< System call exit address. */
 | 
			
		||||
    uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */
 | 
			
		||||
} xSYSTEM_CALL_STACK_INFO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Per-Task MPU settings structure stored in the TCB.
 | 
			
		||||
 * @struct xMPU_SETTINGS
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup MPU Control
 | 
			
		||||
 * @ingroup Task Context
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 *
 | 
			
		||||
 * @note The ordering of this structure MUST be in sync with the assembly code
 | 
			
		||||
 * of the port.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct MPU_SETTINGS
 | 
			
		||||
{
 | 
			
		||||
    xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
 | 
			
		||||
    uint32_t ulTaskFlags;
 | 
			
		||||
    xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
 | 
			
		||||
    uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */
 | 
			
		||||
 | 
			
		||||
    #if( configENABLE_ACCESS_CONTROL_LIST == 1 )
 | 
			
		||||
        uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE
 | 
			
		||||
                                        / portACL_ENTRY_SIZE_BITS )
 | 
			
		||||
                                      + 1UL ];
 | 
			
		||||
    #endif
 | 
			
		||||
} xMPU_SETTINGS;
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
} /* extern C */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* PORTMACRO_H */
 | 
			
		||||
							
								
								
									
										279
									
								
								portable/GCC/ARM_CRx_MPU/portmacro_asm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								portable/GCC/ARM_CRx_MPU/portmacro_asm.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,279 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 | 
			
		||||
 * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PORTMACRO_ASM_H
 | 
			
		||||
#define PORTMACRO_ASM_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOSConfig.h"
 | 
			
		||||
 | 
			
		||||
#ifndef configTOTAL_MPU_REGIONS
 | 
			
		||||
    #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h"
 | 
			
		||||
#elif( configTOTAL_MPU_REGIONS == 12 )
 | 
			
		||||
    #define portMPU_TOTAL_REGIONS ( 12UL )
 | 
			
		||||
#elif( configTOTAL_MPU_REGIONS == 16 )
 | 
			
		||||
    #define portMPU_TOTAL_REGIONS ( 16UL )
 | 
			
		||||
#else
 | 
			
		||||
    #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h"
 | 
			
		||||
#endif /* configTOTAL_MPU_REGIONS */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The application write can disable Floating Point Unit (FPU) support by
 | 
			
		||||
 * setting configENABLE_FPU to 0. Floating point context stored in TCB
 | 
			
		||||
 * comprises of 32 floating point registers (D0-D31) and FPSCR register.
 | 
			
		||||
 * Disabling FPU, therefore, reduces the per-task RAM usage by
 | 
			
		||||
 * ( 32 + 1 ) * 4 = 132 bytes per task.
 | 
			
		||||
 *
 | 
			
		||||
 * BE CAREFUL DISABLING THIS: Certain standard library APIs try to optimize
 | 
			
		||||
 * themselves by using the floating point registers. If the FPU support is
 | 
			
		||||
 * disabled, the use of such APIs may result in memory corruption.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef configENABLE_FPU
 | 
			
		||||
    #define configENABLE_FPU    1
 | 
			
		||||
#endif /* configENABLE_FPU */
 | 
			
		||||
 | 
			
		||||
#define portENABLE_FPU configENABLE_FPU
 | 
			
		||||
 | 
			
		||||
/* On the ArmV7-R Architecture the Operating mode of the Processor is set
 | 
			
		||||
 * using the Current Program Status Register (CPSR) Mode bits, [4:0]. The only
 | 
			
		||||
 * unprivileged mode is User Mode.
 | 
			
		||||
 *
 | 
			
		||||
 * Additional information about the Processor Modes can be found here:
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief CPSR bits for various processor modes.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 */
 | 
			
		||||
#define USER_MODE   0x10U
 | 
			
		||||
#define FIQ_MODE    0x11U
 | 
			
		||||
#define IRQ_MODE    0x12U
 | 
			
		||||
#define SVC_MODE    0x13U
 | 
			
		||||
#define MON_MODE    0x16U
 | 
			
		||||
#define ABT_MODE    0x17U
 | 
			
		||||
#define HYP_MODE    0x1AU
 | 
			
		||||
#define UND_MODE    0x1BU
 | 
			
		||||
#define SYS_MODE    0x1FU
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Flag used to mark that a FreeRTOS Task is privileged.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Port Privilege
 | 
			
		||||
 */
 | 
			
		||||
#define portTASK_IS_PRIVILEGED_FLAG   ( 1UL << 1UL )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief SVC numbers for various scheduler operations.
 | 
			
		||||
 *
 | 
			
		||||
 * @ingroup Scheduler
 | 
			
		||||
 *
 | 
			
		||||
 * @note These value must not be used in mpu_syscall_numbers.h.
 | 
			
		||||
 */
 | 
			
		||||
#define portSVC_YIELD                 0x0100U
 | 
			
		||||
#define portSVC_SYSTEM_CALL_EXIT      0x0104U
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Macros required to manipulate MPU.
 | 
			
		||||
 *
 | 
			
		||||
 * Further information about MPU can be found in Arm's documentation
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* MPU sub-region disable settings. This information is encoded in the MPU
 | 
			
		||||
 * Region Size and Enable Register. */
 | 
			
		||||
#define portMPU_SUBREGION_0_DISABLE   ( 0x1UL << 8UL )
 | 
			
		||||
#define portMPU_SUBREGION_1_DISABLE   ( 0x1UL << 9UL )
 | 
			
		||||
#define portMPU_SUBREGION_2_DISABLE   ( 0x1UL << 10UL )
 | 
			
		||||
#define portMPU_SUBREGION_3_DISABLE   ( 0x1UL << 11UL )
 | 
			
		||||
#define portMPU_SUBREGION_4_DISABLE   ( 0x1UL << 12UL )
 | 
			
		||||
#define portMPU_SUBREGION_5_DISABLE   ( 0x1UL << 13UL )
 | 
			
		||||
#define portMPU_SUBREGION_6_DISABLE   ( 0x1UL << 14UL )
 | 
			
		||||
#define portMPU_SUBREGION_7_DISABLE   ( 0x1UL << 15UL )
 | 
			
		||||
 | 
			
		||||
/* Default MPU regions. */
 | 
			
		||||
#define portFIRST_CONFIGURABLE_REGION ( 0 )
 | 
			
		||||
#define portLAST_CONFIGURABLE_REGION  ( portMPU_TOTAL_REGIONS - 5UL )
 | 
			
		||||
#define portSTACK_REGION              ( portMPU_TOTAL_REGIONS - 4UL )
 | 
			
		||||
#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL )
 | 
			
		||||
#define portPRIVILEGED_FLASH_REGION   ( portMPU_TOTAL_REGIONS - 2UL )
 | 
			
		||||
#define portPRIVILEGED_RAM_REGION     ( portMPU_TOTAL_REGIONS - 1UL )
 | 
			
		||||
#define portNUM_CONFIGURABLE_REGIONS \
 | 
			
		||||
    ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL )
 | 
			
		||||
/* Plus one to make space for the stack region. */
 | 
			
		||||
#define portTOTAL_NUM_REGIONS_IN_TCB        ( portNUM_CONFIGURABLE_REGIONS + 1UL )
 | 
			
		||||
 | 
			
		||||
/* MPU region sizes. This information is encoded in the MPU Region Size and
 | 
			
		||||
 * Enable Register. */
 | 
			
		||||
#define portMPU_REGION_SIZE_32B             ( 0x04UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_64B             ( 0x05UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_128B            ( 0x06UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_256B            ( 0x07UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_512B            ( 0x08UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_1KB             ( 0x09UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_2KB             ( 0x0AUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_4KB             ( 0x0BUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_8KB             ( 0x0CUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_16KB            ( 0x0DUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_32KB            ( 0x0EUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_64KB            ( 0x0FUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_128KB           ( 0x10UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_256KB           ( 0x11UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_512KB           ( 0x12UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_1MB             ( 0x13UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_2MB             ( 0x14UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_4MB             ( 0x15UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_8MB             ( 0x16UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_16MB            ( 0x17UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_32MB            ( 0x18UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_64MB            ( 0x19UL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_128MB           ( 0x1AUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_256MB           ( 0x1BUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_512MB           ( 0x1CUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_1GB             ( 0x1DUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_2GB             ( 0x1EUL << 1UL )
 | 
			
		||||
#define portMPU_REGION_SIZE_4GB             ( 0x1FUL << 1UL )
 | 
			
		||||
 | 
			
		||||
/* MPU memory types. This information is encoded in the TEX, S, C and B bits
 | 
			
		||||
 * of the MPU Region Access Control Register. */
 | 
			
		||||
#define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE  ( 0x00UL ) /* TEX=000, S=NA, C=0, B=0. */
 | 
			
		||||
#define portMPU_REGION_DEVICE_SHAREABLE            ( 0x01UL ) /* TEX=000, S=NA, C=0, B=1. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED   ( 0x02UL ) /* TEX=000, S=0, C=1, B=0. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWTNOWA_SHARED      ( 0x06UL ) /* TEX=000, S=1, C=1, B=0. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED   ( 0x03UL ) /* TEX=000, S=0, C=1, B=1. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWBNOWA_SHARED      ( 0x07UL ) /* TEX=000, S=1, C=1, B=1. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OINC_NONSHARED       ( 0x08UL ) /* TEX=001, S=0, C=0, B=0. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OINC_SHARED          ( 0x0CUL ) /* TEX=001, S=1, C=0, B=0. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWBWA_NONSHARED     ( 0x0BUL ) /* TEX=001, S=0, C=1, B=1. */
 | 
			
		||||
#define portMPU_REGION_NORMAL_OIWBWA_SHARED        ( 0x0FUL ) /* TEX=001, S=1, C=1, B=1. */
 | 
			
		||||
#define portMPU_REGION_DEVICE_NONSHAREABLE         ( 0x10UL ) /* TEX=010, S=NA, C=0, B=0. */
 | 
			
		||||
 | 
			
		||||
/* MPU access permissions. This information is encoded in the XN and AP bits of
 | 
			
		||||
 * the MPU Region Access Control Register. */
 | 
			
		||||
#define portMPU_REGION_AP_BITMASK                  ( 0x07UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_XN_BITMASK                  ( 0x01UL << 12UL )
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_NA_USER_NA             ( 0x00UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_NA_USER_NA_EXEC        ( portMPU_REGION_PRIV_NA_USER_NA ) /* Priv: X, Unpriv: X. */
 | 
			
		||||
#define portMPU_REGION_PRIV_NA_USER_NA_NOEXEC      ( portMPU_REGION_PRIV_NA_USER_NA | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: No Access, Unpriv: No Access. */
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_NA             ( 0x01UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_NA_EXEC        ( portMPU_REGION_PRIV_RW_USER_NA ) /* Priv: RWX, Unpriv: X. */
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_NA_NOEXEC      ( portMPU_REGION_PRIV_RW_USER_NA | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: No access. */
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RO             ( 0x02UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RO_EXEC        ( portMPU_REGION_PRIV_RW_USER_RO ) /* Priv: RWX, Unpriv: RX. */
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RO_NOEXEC      ( portMPU_REGION_PRIV_RW_USER_RO | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: R. */
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RW             ( 0x03UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RW_EXEC        ( portMPU_REGION_PRIV_RW_USER_RW ) /* Priv: RWX, Unpriv: RWX. */
 | 
			
		||||
#define portMPU_REGION_PRIV_RW_USER_RW_NOEXEC      ( portMPU_REGION_PRIV_RW_USER_RW | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: RW. */
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_NA             ( 0x05UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_NA_EXEC        ( portMPU_REGION_PRIV_RO_USER_NA ) /* Priv: RX, Unpriv: X. */
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_NA_NOEXEC      ( portMPU_REGION_PRIV_RO_USER_NA | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: No access. */
 | 
			
		||||
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_RO             ( 0x06UL << 8UL )
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_RO_EXEC        ( portMPU_REGION_PRIV_RO_USER_RO ) /* Priv: RX, Unpriv: RX. */
 | 
			
		||||
#define portMPU_REGION_PRIV_RO_USER_RO_NOEXEC      ( portMPU_REGION_PRIV_RO_USER_RO | \
 | 
			
		||||
                                                     portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: R. */
 | 
			
		||||
 | 
			
		||||
/* MPU region management. */
 | 
			
		||||
#define portMPU_REGION_EXECUTE_NEVER               ( 0x01UL << 12UL )
 | 
			
		||||
#define portMPU_REGION_ENABLE                      ( 0x01UL )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The size (in words) of a task context.
 | 
			
		||||
 *
 | 
			
		||||
 * An array of this size is allocated in TCB where a task's context is saved
 | 
			
		||||
 * when it is switched out.
 | 
			
		||||
 *
 | 
			
		||||
 * Information about Floating Point Unit (FPU):
 | 
			
		||||
 * https://developer.arm.com/documentation/den0042/a/Floating-Point
 | 
			
		||||
 *
 | 
			
		||||
 * Additional information related to the Cortex R4-F's FPU Implementation:
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0363/e/fpu-programmer-s-model
 | 
			
		||||
 *
 | 
			
		||||
 * Additional information related to the Cortex R5-F's FPU Implementation:
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model
 | 
			
		||||
 *
 | 
			
		||||
 * Additional information related to the ArmV7-R CPSR:
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en
 | 
			
		||||
 *
 | 
			
		||||
 * Additional information related to the GPRs:
 | 
			
		||||
 * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-core-registers?lang=en
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if( portENABLE_FPU == 1 )
 | 
			
		||||
    /*
 | 
			
		||||
     * +-------------------+-------+----------+--------+----------+----------+----------+------+
 | 
			
		||||
     * | ulCriticalNesting | FPSCR |  S0-S31  | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
 | 
			
		||||
     * +-------------------+-------+----------+--------+----------+----------+----------+------+
 | 
			
		||||
     *
 | 
			
		||||
     * <------------------><------><---------><--------><---------><--------><----------><----->
 | 
			
		||||
     *           1            1        32         13         1         1          1        1
 | 
			
		||||
     */
 | 
			
		||||
    #define CONTEXT_SIZE 51U
 | 
			
		||||
#else
 | 
			
		||||
    /*
 | 
			
		||||
     * +-------------------+--------+----------+----------+----------+------+
 | 
			
		||||
     * | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
 | 
			
		||||
     * +-------------------+--------+----------+----------+----------+------+
 | 
			
		||||
     *
 | 
			
		||||
     * <------------------><--------><---------><--------><----------><----->
 | 
			
		||||
     *           1             13         1         1          1        1
 | 
			
		||||
     */
 | 
			
		||||
    #define CONTEXT_SIZE 18U
 | 
			
		||||
#endif /* CONTEXT_SIZE */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Offset of xSystemCallStackInfo from the start of a TCB.
 | 
			
		||||
 */
 | 
			
		||||
#define portSYSTEM_CALL_INFO_OFFSET             \
 | 
			
		||||
    ( ( 1U /* pxTopOfStack. */ +                \
 | 
			
		||||
        ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \
 | 
			
		||||
        1U /* ulTaskFlags. */                   \
 | 
			
		||||
      ) * 4U )
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
} /* extern C */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* PORTMACRO_ASM_H */
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user